Worklog, anti geo spoofing and UI Polish

This commit is contained in:
2026-05-05 05:51:19 +08:00
parent d068887354
commit ccedf6e5f0
15 changed files with 2589 additions and 45 deletions
+19 -4
View File
@@ -163,6 +163,21 @@ class ChatController {
} catch (e) {
if (!isOfflineSaveError(e)) rethrow;
final ref = _ref;
if (ref != null) {
final existing =
ref.read(offlinePendingChatMessagesProvider)[threadId] ?? [];
// Idempotency guard: suppress if the same body was queued within the
// last 10 s — prevents duplicate messages from rapid taps while offline.
final cutoff = AppTime.now().subtract(const Duration(seconds: 10));
if (existing.any((m) => m.body == body && m.createdAt.isAfter(cutoff))) {
debugPrint(
'[ChatController] duplicate offline message suppressed for thread=$threadId',
);
return;
}
}
final message = ChatMessage(
id: id,
threadId: threadId,
@@ -171,13 +186,13 @@ class ChatController {
createdAt: AppTime.now(),
);
final ref = _ref;
if (ref != null) {
final ref2 = _ref;
if (ref2 != null) {
final current = Map<String, List<ChatMessage>>.from(
ref.read(offlinePendingChatMessagesProvider),
ref2.read(offlinePendingChatMessagesProvider),
);
current[threadId] = [...(current[threadId] ?? []), message];
ref.read(offlinePendingChatMessagesProvider.notifier).state =
ref2.read(offlinePendingChatMessagesProvider.notifier).state =
Map.unmodifiable(current);
}
mirrorBatchToBrick<ChatMessage>([message], tag: 'offline_chat');