From 2a61f41741f81042e0272d06ba15ce5590e1227d Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Mon, 23 Mar 2026 07:22:58 +0100
Subject: [PATCH] fix: screenshot chat leak, transcript disk update, cross-session image routing
---
lib/screens/chat_screen.dart | 64 ++++++++++++++++++++++++++++++--
1 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index 68842d8..23ce43d 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -214,7 +214,16 @@
final messageId = msg['messageId'] as String?;
final content = msg['content'] as String?;
if (messageId != null && content != null) {
- ref.read(messagesProvider.notifier).updateContent(messageId, content);
+ // Try updating in current session first
+ final currentMessages = ref.read(messagesProvider);
+ final inCurrent = currentMessages.any((m) => m.id == messageId);
+ if (inCurrent) {
+ ref.read(messagesProvider.notifier).updateContent(messageId, content);
+ } else {
+ // Message is in a different session (user switched after recording).
+ // Load that session's messages from disk, update, and save back.
+ _updateTranscriptOnDisk(messageId, content);
+ }
}
case 'unread':
final sessionId = msg['sessionId'] as String?;
@@ -391,13 +400,16 @@
void _handleIncomingImage(Map<String, dynamic> msg) {
final imageData = msg['imageBase64'] as String? ?? msg['data'] as String? ?? msg['image'] as String?;
final content = msg['content'] as String? ?? msg['caption'] as String? ?? '';
+ final sessionId = msg['sessionId'] as String?;
if (imageData == null) return;
- // Always update the Navigate screen screenshot
+ // Always update the Navigate screen screenshot provider
ref.read(latestScreenshotProvider.notifier).state = imageData;
- final isScreenshot = content == 'Screenshot' || content == 'Capturing screenshot...';
+ final isScreenshot = content == 'Screenshot' ||
+ content == 'Capturing screenshot...' ||
+ (msg['type'] == 'screenshot');
if (isScreenshot) {
// Remove any "Capturing screenshot..." placeholder text messages
@@ -405,7 +417,7 @@
(m) => m.role == MessageRole.assistant && m.content == 'Capturing screenshot...',
);
- // Only add to chat if the Screen button requested it
+ // Only add to chat if the Screen button explicitly requested it
if (!_screenshotForChat) {
ref.read(isTypingProvider.notifier).state = false;
return;
@@ -419,6 +431,14 @@
content: content,
status: MessageStatus.sent,
);
+
+ // Cross-session routing: store for target session if not active
+ final activeId = ref.read(activeSessionIdProvider);
+ if (sessionId != null && sessionId != activeId) {
+ _storeForSession(sessionId, message);
+ _incrementUnread(sessionId);
+ return;
+ }
ref.read(messagesProvider.notifier).addMessage(message);
ref.read(isTypingProvider.notifier).state = false;
@@ -436,6 +456,42 @@
_chatLog('storeForSession: verified ${verify.length} messages after save');
}
+ /// Update a transcript for a message stored on disk (not in the active session).
+ /// Scans all session files to find the message by ID, updates content, and saves.
+ Future<void> _updateTranscriptOnDisk(String messageId, String content) async {
+ try {
+ final dir = await getApplicationDocumentsDirectory();
+ final msgDir = Directory('${dir.path}/messages');
+ if (!await msgDir.exists()) return;
+
+ await for (final entity in msgDir.list()) {
+ if (entity is! File || !entity.path.endsWith('.json')) continue;
+
+ final jsonStr = await entity.readAsString();
+ final List<dynamic> jsonList = jsonDecode(jsonStr) as List<dynamic>;
+ bool found = false;
+
+ final updated = jsonList.map((j) {
+ final map = j as Map<String, dynamic>;
+ if (map['id'] == messageId) {
+ found = true;
+ return {...map, 'content': content};
+ }
+ return map;
+ }).toList();
+
+ if (found) {
+ await entity.writeAsString(jsonEncode(updated));
+ _chatLog('transcript: updated messageId=$messageId on disk in ${entity.path.split('/').last}');
+ return;
+ }
+ }
+ _chatLog('transcript: messageId=$messageId not found on disk');
+ } catch (e) {
+ _chatLog('transcript: disk update error=$e');
+ }
+ }
+
void _incrementUnread(String sessionId) {
final counts = Map<String, int>.from(ref.read(unreadCountsProvider));
counts[sessionId] = (counts[sessionId] ?? 0) + 1;
--
Gitblit v1.3.1