From 1a2c703fbbb14c75bc41ad9341618ac7c72b3cc5 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Mon, 23 Mar 2026 12:10:21 +0100
Subject: [PATCH] fix: file picker shows caption dialog before sending

---
 lib/screens/chat_screen.dart |   73 ++++++++++++++++++++++++++++--------
 1 files changed, 57 insertions(+), 16 deletions(-)

diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index 90fabf2..1a9bf5e 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -678,38 +678,79 @@
       final bytes = await File(file.path!).readAsBytes();
       final b64 = base64Encode(bytes);
       final mimeType = _guessMimeType(file.name);
-
       attachments.add({
         'data': b64,
         'mimeType': mimeType,
         'fileName': file.name,
       });
+    }
+    if (attachments.isEmpty) return;
 
-      // Show in chat
-      if (mimeType.startsWith('image/')) {
-        ref.read(messagesProvider.notifier).addMessage(Message.image(
-          role: MessageRole.user,
-          imageBase64: b64,
-          content: file.name,
-          status: MessageStatus.sent,
-        ));
-      } else {
-        ref.read(messagesProvider.notifier).addMessage(Message.text(
-          role: MessageRole.user,
-          content: 'šŸ“Ž ${file.name} (${_formatSize(bytes.length)})',
-          status: MessageStatus.sent,
-        ));
+    // Show caption dialog
+    final fileNames = result.files.map((f) => f.name).join(', ');
+    final caption = await _showCaptionDialog(result.files.length);
+    if (caption == null) return;
+
+    // Handle voice caption
+    String textCaption = caption;
+    String? voiceB64;
+    if (caption.startsWith('__voice__:')) {
+      final voicePath = caption.substring('__voice__:'.length);
+      final voiceFile = File(voicePath);
+      if (await voiceFile.exists()) {
+        voiceB64 = base64Encode(await voiceFile.readAsBytes());
       }
+      textCaption = '';
+    }
+
+    // Send voice first if present
+    if (voiceB64 != null) {
+      final voiceMsg = Message.voice(
+        role: MessageRole.user,
+        audioUri: caption.substring('__voice__:'.length),
+        status: MessageStatus.sent,
+      );
+      ref.read(messagesProvider.notifier).addMessage(voiceMsg);
+      _ws?.send({
+        'type': 'voice',
+        'audioBase64': voiceB64,
+        'content': '',
+        'messageId': voiceMsg.id,
+        'sessionId': targetSessionId,
+      });
     }
 
     // Send all files as one atomic bundle
     _ws?.send({
       'type': 'bundle',
-      'caption': '',
+      'caption': textCaption,
       'attachments': attachments,
       'sessionId': targetSessionId,
     });
 
+    // Show in chat
+    for (final att in attachments) {
+      final mime = att['mimeType'] as String;
+      final name = att['fileName'] as String? ?? 'file';
+      if (mime.startsWith('image/')) {
+        ref.read(messagesProvider.notifier).addMessage(Message.image(
+          role: MessageRole.user,
+          imageBase64: att['data'] as String,
+          content: name,
+          status: MessageStatus.sent,
+        ));
+      } else {
+        final size = base64Decode(att['data'] as String).length;
+        ref.read(messagesProvider.notifier).addMessage(Message.text(
+          role: MessageRole.user,
+          content: textCaption.isNotEmpty
+              ? '$textCaption\nšŸ“Ž $name (${_formatSize(size)})'
+              : 'šŸ“Ž $name (${_formatSize(size)})',
+          status: MessageStatus.sent,
+        ));
+      }
+    }
+
     _scrollToBottom();
   }
 

--
Gitblit v1.3.1