From fa34201bc07e5312ff0c6825933cd02ce7900254 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Sat, 21 Mar 2026 20:55:10 +0100
Subject: [PATCH] fix: voice caption ordering, background audio, image persistence
---
lib/services/message_store.dart | 27 +++++++++++++++++++++++++--
1 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/lib/services/message_store.dart b/lib/services/message_store.dart
index 448390e..424d73a 100644
--- a/lib/services/message_store.dart
+++ b/lib/services/message_store.dart
@@ -82,7 +82,7 @@
final jsonStr = await file.readAsString();
final List<dynamic> jsonList = jsonDecode(jsonStr) as List<dynamic>;
final allMessages = jsonList
- .map((j) => Message.fromJson(j as Map<String, dynamic>))
+ .map((j) => _messageFromJson(j as Map<String, dynamic>))
.where((m) => !m.isEmptyVoice) // Filter out voice msgs with no content
.toList();
@@ -106,7 +106,7 @@
final jsonStr = await file.readAsString();
final List<dynamic> jsonList = jsonDecode(jsonStr) as List<dynamic>;
return jsonList
- .map((j) => Message.fromJson(j as Map<String, dynamic>))
+ .map((j) => _messageFromJson(j as Map<String, dynamic>))
.where((m) => !m.isEmptyVoice)
.toList();
} catch (e) {
@@ -114,6 +114,29 @@
}
}
+ /// Deserialize a message from JSON, applying migration rules:
+ /// - Voice messages without audioUri are downgraded to text (transcript only).
+ /// This handles messages saved before a restart, where the temp audio file
+ /// is no longer available. The transcript (content) is preserved.
+ static Message _messageFromJson(Map<String, dynamic> json) {
+ final raw = Message.fromJson(json);
+ if (raw.type == MessageType.voice &&
+ (raw.audioUri == null || raw.audioUri!.isEmpty)) {
+ // Downgrade to text so the bubble shows the transcript instead of a
+ // broken play button.
+ return Message(
+ id: raw.id,
+ role: raw.role,
+ type: MessageType.text,
+ content: raw.content,
+ timestamp: raw.timestamp,
+ status: raw.status,
+ duration: raw.duration,
+ );
+ }
+ return raw;
+ }
+
/// Delete stored messages for a session.
static Future<void> delete(String sessionId) async {
try {
--
Gitblit v1.3.1