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/screens/chat_screen.dart |   29 +++++++++++++++--------------
 1 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index e470ce7..e889469 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -223,19 +223,18 @@
       // Re-register APNs token after reconnect so daemon always has a fresh token
       _push?.onMqttConnected();
     };
-    _ws!.onResume = () async {
-      // App came back from background — reload messages and catch up.
-      _chatLog('onResume: reloading messages and sending catch_up');
+    _ws!.onResume = () {
+      // App came back from background. The in-memory state already has
+      // any messages received while suspended (addMessage was called).
+      // Just rebuild the UI and scroll to bottom to show them.
+      _chatLog('onResume: rebuilding UI and sending catch_up');
       _sendCommand('catch_up', {'lastSeq': _lastSeq});
-      // Force reload current session messages from provider (triggers rebuild)
-      final activeId = ref.read(activeSessionIdProvider);
-      if (activeId != null) {
-        // Re-save then re-load to ensure UI matches persisted state
-        await ref.read(messagesProvider.notifier).switchSession(activeId);
-      }
       if (mounted) {
         setState(() {});
-        _scrollToBottom();
+        // Scroll after the frame rebuilds
+        WidgetsBinding.instance.addPostFrameCallback((_) {
+          if (mounted) _scrollToBottom();
+        });
       }
     };
     _ws!.onError = (error) {
@@ -260,11 +259,12 @@
     // sent immediately if already connected.
     _push = PushService(mqttService: _ws!);
     _push!.onNotificationTap = (data) {
-      // Switch to the session immediately, then request catch_up.
-      // The MQTT connection auto-reconnects on resume, and onResume
-      // already sends catch_up. We just need to be on the right session.
+      // Only switch if tapping a notification for a DIFFERENT session.
+      // If already on this session, the message is already displayed —
+      // calling switchSession would reload from disk and lose it.
       final sessionId = data['sessionId'] as String?;
-      if (sessionId != null && mounted) {
+      final activeId = ref.read(activeSessionIdProvider);
+      if (sessionId != null && sessionId != activeId && mounted) {
         _switchSession(sessionId);
       }
     };
@@ -414,6 +414,7 @@
               );
             }
 
+            _chatLog('catch_up msg: session=${msgSessionId?.substring(0, 8) ?? "NULL"} active=${activeId?.substring(0, 8)} match=${msgSessionId == activeId || msgSessionId == null} content="${content.substring(0, content.length.clamp(0, 40))}"');
             if (msgSessionId == null || msgSessionId == activeId) {
               // Active session or no session: add directly to chat
               ref.read(messagesProvider.notifier).addMessage(message);

--
Gitblit v1.3.1