Matthias Nott
9 days ago 6cbbea9b96db551e5c0ac26f0ace3d4c3d82a276
lib/screens/chat_screen.dart
....@@ -216,12 +216,15 @@
216216 _ws!.onOpen = () {
217217 _sessionReady = false; // Gate messages until sessions arrive
218218 _pendingMessages.clear();
219
- final activeId = ref.read(activeSessionIdProvider);
220
- _sendCommand('sync', activeId != null ? {'activeSessionId': activeId} : null);
221
- // catch_up is sent after sessions arrive (in _handleSessions)
222
-
223
- // Re-register APNs token after reconnect so daemon always has a fresh token
224
- _push?.onMqttConnected();
219
+ // Delay sync slightly to let broker acknowledge our subscriptions first.
220
+ // Without this, the catch_up response arrives before pailot/control/out
221
+ // subscription is active, and the message is lost.
222
+ Future.delayed(const Duration(milliseconds: 500), () {
223
+ if (!mounted) return;
224
+ final activeId = ref.read(activeSessionIdProvider);
225
+ _sendCommand('sync', activeId != null ? {'activeSessionId': activeId} : null);
226
+ _push?.onMqttConnected();
227
+ });
225228 };
226229 _ws!.onResume = () {
227230 // App came back from background. The in-memory state already has
....@@ -534,8 +537,10 @@
534537 status: MessageStatus.sent,
535538 );
536539
537
- final activeId = ref.read(activeSessionIdProvider);
538
- if (sessionId != null && sessionId != activeId) {
540
+ // Use currentSessionId from notifier (what's actually loaded in the provider)
541
+ // not activeSessionIdProvider (can be stale after background resume)
542
+ final currentId = ref.read(messagesProvider.notifier).currentSessionId;
543
+ if (sessionId != null && sessionId != currentId) {
539544 // Store message for the other session so it's there when user switches
540545 TraceService.instance.addTrace(
541546 'message stored for session',
....@@ -608,9 +613,9 @@
608613 duration: duration,
609614 );
610615
611
- final activeId = ref.read(activeSessionIdProvider);
612
- _chatLog('voice: sessionId=$sessionId activeId=$activeId audioPath=$savedAudioPath content="${content.substring(0, content.length.clamp(0, 30))}"');
613
- if (sessionId != null && sessionId != activeId) {
616
+ final currentId = ref.read(messagesProvider.notifier).currentSessionId;
617
+ _chatLog('voice: sessionId=$sessionId currentId=$currentId audioPath=$savedAudioPath content="${content.substring(0, content.length.clamp(0, 30))}"');
618
+ if (sessionId != null && sessionId != currentId) {
614619 _chatLog('voice: cross-session, storing for $sessionId');
615620 await _storeForSession(sessionId, storedMessage);
616621 _chatLog('voice: stored, incrementing unread');
....@@ -679,9 +684,9 @@
679684 status: MessageStatus.sent,
680685 );
681686
682
- // Cross-session routing: store for target session if not active
683
- final activeId = ref.read(activeSessionIdProvider);
684
- if (sessionId != null && sessionId != activeId) {
687
+ // Cross-session routing: store for target session if not currently loaded
688
+ final currentId = ref.read(messagesProvider.notifier).currentSessionId;
689
+ if (sessionId != null && sessionId != currentId) {
685690 _storeForSession(sessionId, message);
686691 _incrementUnread(sessionId);
687692 return;