From 90fc31a938afac0f6910c7947c6ecba0adebfea4 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Mon, 06 Apr 2026 14:12:23 +0200
Subject: [PATCH] fix: immediate disk writes, notification tap skip same session, catch_up trace logging, resume simplification

---
 lib/services/message_store.dart |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/lib/services/message_store.dart b/lib/services/message_store.dart
index 2d682ec..f45e0d0 100644
--- a/lib/services/message_store.dart
+++ b/lib/services/message_store.dart
@@ -6,6 +6,7 @@
 import 'package:path_provider/path_provider.dart';
 
 import '../models/message.dart';
+import 'trace_service.dart';
 
 /// Per-session JSON file persistence with debounced saves.
 class MessageStore {
@@ -59,6 +60,8 @@
 
   /// Write directly to disk, bypassing debounce. For critical saves.
   static Future<void> writeDirect(String sessionId, List<Message> messages) async {
+    // Cancel ALL pending debounce to prevent race with frozen iOS timers
+    _debounceTimer?.cancel();
     _pendingSaves.remove(sessionId);
     await _writeSession(sessionId, messages);
   }
@@ -85,9 +88,11 @@
       final file = File('${dir.path}/${_fileForSession(sessionId)}');
       // Strip heavy fields for persistence
       final lightMessages = messages.map((m) => m.toJsonLight()).toList();
-      await file.writeAsString(jsonEncode(lightMessages));
+      final json = jsonEncode(lightMessages);
+      await file.writeAsString(json);
+      TraceService.instance.addTrace('MsgStore WRITE', '${sessionId.substring(0, 8)}: ${messages.length} msgs');
     } catch (e) {
-      // Silently fail - message persistence is best-effort
+      TraceService.instance.addTrace('MsgStore WRITE ERROR', '${sessionId.substring(0, 8)}: $e');
     }
   }
 
@@ -130,11 +135,14 @@
 
       final jsonStr = await file.readAsString();
       final List<dynamic> jsonList = jsonDecode(jsonStr) as List<dynamic>;
-      return jsonList
+      final msgs = jsonList
           .map((j) => _messageFromJson(j as Map<String, dynamic>))
           .where((m) => !m.isEmptyVoice && !m.isEmptyText)
           .toList();
+      TraceService.instance.addTrace('MsgStore LOAD', '${sessionId.substring(0, 8)}: ${msgs.length} msgs');
+      return msgs;
     } catch (e) {
+      TraceService.instance.addTrace('MsgStore LOAD ERROR', '${sessionId.substring(0, 8)}: $e');
       return [];
     }
   }

--
Gitblit v1.3.1