feat(chats): очистка истории и удаление чата из меню

This commit is contained in:
klockky
2026-06-28 14:29:13 +03:00
parent 574206dc21
commit 39c4f89992
2 changed files with 108 additions and 2 deletions
+30
View File
@@ -7,6 +7,7 @@ import '../../core/config/komet_settings.dart';
import '../../core/protocol/opcode_map.dart';
import '../../core/protocol/packet.dart';
import '../../core/cache/info_cache.dart';
import '../../core/cache/message_session_cache.dart';
import '../../core/storage/app_database.dart';
import '../../core/storage/token_storage.dart';
import '../../core/utils/logger.dart';
@@ -1520,6 +1521,35 @@ class ChatsModule {
}
}
static Future<String?> clearHistory(
Api api, {
required int chatId,
required int lastEventTime,
bool forAll = false,
}) async {
try {
await api.sendRequest(Opcode.chatClear, {
'chatId': chatId,
'lastEventTime': lastEventTime,
'forAll': forAll,
});
final accountId = await TokenStorage.getActiveAccountId();
if (accountId != null) {
await AppDatabase.clearMessages(accountId, chatId);
MessageSessionCache.remove(accountId, chatId);
_historyFetched.remove(chatId);
await reconcileLastMessage(accountId, chatId);
}
return null;
} on PacketError catch (e) {
logger.w('clearHistory $chatId: ${e.message}');
return e.message;
} catch (e) {
logger.w('clearHistory $chatId: $e');
return 'Не удалось очистить историю';
}
}
static Future<bool> leaveChat(Api api, {required int chatId}) async {
try {
await api.sendRequest(Opcode.chatLeave, {'chatId': chatId});
+78 -2
View File
@@ -2349,17 +2349,93 @@ class _ChatScreenState extends State<ChatScreen>
ChatMenuItem(
icon: Symbols.mop,
label: 'Очистить историю',
onTap: () {},
onTap: _clearHistory,
),
ChatMenuItem(
icon: Symbols.delete,
label: 'Удалить чат',
onTap: () {},
onTap: _deleteChat,
),
],
);
}
Future<bool?> _showConfirmDialog({
required String title,
required String body,
required String confirmLabel,
}) {
final cs = Theme.of(context).colorScheme;
return showDialog<bool>(
context: context,
builder: (ctx) => AlertDialog(
backgroundColor: cs.surfaceContainerHigh,
title: Text(title),
content: Text(
body,
style: TextStyle(color: cs.onSurfaceVariant, fontSize: 15),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx, false),
child: const Text('Отмена'),
),
TextButton(
onPressed: () => Navigator.pop(ctx, true),
child: Text(confirmLabel, style: TextStyle(color: cs.error)),
),
],
),
);
}
Future<void> _clearHistory() async {
final confirmed = await _showConfirmDialog(
title: 'Очистить историю',
body: 'Все сообщения в этом чате будут удалены без возможности '
'восстановления.',
confirmLabel: 'Очистить',
);
if (!mounted || confirmed != true) return;
final err = await ChatsModule.clearHistory(
api,
chatId: widget.chatId,
lastEventTime: chat?.lastEventTime ?? 0,
);
if (!mounted) return;
if (err != null) {
showCustomNotification(context, err);
return;
}
setState(() {
_messages = [];
_hasMoreHistory = false;
_combinedItemsCache = null;
});
_messagesRev.value++;
}
Future<void> _deleteChat() async {
final confirmed = await _showConfirmDialog(
title: 'Удалить чат',
body: 'Чат будет удалён вместе со всей перепиской.',
confirmLabel: 'Удалить',
);
if (!mounted || confirmed != true) return;
final err = await ChatsModule.deleteChat(
api,
chatId: widget.chatId,
lastEventTime: chat?.lastEventTime ?? 0,
forAll: false,
);
if (!mounted) return;
if (err != null) {
showCustomNotification(context, err);
return;
}
Navigator.of(context).pop();
}
Future<void> _startCall() async {
if (widget.chatType != 'DIALOG') {
showCustomNotification(context, 'Звонки доступны только в диалогах');