From e1c8bac29517bc4390e6e7ca22e37f74bbf7f20a Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Mon, 23 Mar 2026 12:22:00 +0100
Subject: [PATCH] fix: atomic bundle with voiceMessageId for transcript, no double voice send
---
lib/screens/chat_screen.dart | 31 +++++++++++++------------------
1 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index 1a9bf5e..4f43034 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -874,37 +874,32 @@
textCaption = '';
}
- // Send everything as a single atomic bundle — the server will compose
- // all attachments + caption into one terminal input (like dropping files + text)
final attachments = encodedImages.map((b64) =>
<String, dynamic>{'data': b64, 'mimeType': 'image/jpeg'}
).toList();
- _ws?.send({
- 'type': 'bundle',
- 'caption': textCaption,
- if (voiceB64 != null) 'audioBase64': voiceB64,
- 'attachments': attachments,
- 'sessionId': targetSessionId,
- });
-
- // If voice caption, also send separately for Whisper transcription
+ // Create voice bubble first to get messageId for transcript reflection
+ String? voiceMessageId;
if (voiceB64 != null) {
final voiceMsg = Message.voice(
role: MessageRole.user,
audioUri: caption.substring('__voice__:'.length),
status: MessageStatus.sent,
);
+ voiceMessageId = voiceMsg.id;
ref.read(messagesProvider.notifier).addMessage(voiceMsg);
- _ws?.send({
- 'type': 'voice',
- 'audioBase64': voiceB64,
- 'content': '',
- 'messageId': voiceMsg.id,
- 'sessionId': targetSessionId,
- });
}
+ // Send everything as a single atomic bundle
+ _ws?.send({
+ 'type': 'bundle',
+ 'caption': textCaption,
+ if (voiceB64 != null) 'audioBase64': voiceB64,
+ if (voiceMessageId != null) 'voiceMessageId': voiceMessageId,
+ 'attachments': attachments,
+ 'sessionId': targetSessionId,
+ });
+
// Show images in chat locally
for (var i = 0; i < encodedImages.length; i++) {
final message = Message.image(
--
Gitblit v1.3.1