From c9ced26fb059d32d5bd10c37b18ebe97a2f3018a Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Sun, 22 Mar 2026 19:54:44 +0100
Subject: [PATCH] fix: save voice audio to file for cross-session persistence

---
 lib/screens/chat_screen.dart |   33 +++++++++++++++++++++++++++++----
 1 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index 16069ba..7741463 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -1,6 +1,8 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:path_provider/path_provider.dart';
+
 import 'package:flutter/material.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:go_router/go_router.dart';
@@ -302,7 +304,7 @@
     }
   }
 
-  void _handleIncomingVoice(Map<String, dynamic> msg) {
+  Future<void> _handleIncomingVoice(Map<String, dynamic> msg) async {
     final sessionId = msg['sessionId'] as String?;
     final audioData = msg['audioBase64'] as String? ?? msg['audio'] as String? ?? msg['data'] as String?;
     final content = msg['content'] as String? ?? msg['text'] as String? ?? '';
@@ -319,9 +321,33 @@
       duration: duration,
     );
 
+    // Save audio to file so it survives persistence (base64 gets stripped)
+    String? savedAudioPath;
+    if (audioData != null) {
+      try {
+        final dir = await getTemporaryDirectory();
+        savedAudioPath = '${dir.path}/voice_${message.id}.m4a';
+        final bytes = base64Decode(audioData.contains(',') ? audioData.split(',').last : audioData);
+        await File(savedAudioPath).writeAsBytes(bytes);
+      } catch (_) {
+        savedAudioPath = null;
+      }
+    }
+
+    final storedMessage = Message(
+      id: message.id,
+      role: message.role,
+      type: message.type,
+      content: content,
+      audioUri: savedAudioPath ?? audioData,
+      timestamp: message.timestamp,
+      status: message.status,
+      duration: duration,
+    );
+
     final activeId = ref.read(activeSessionIdProvider);
     if (sessionId != null && sessionId != activeId) {
-      _storeForSession(sessionId, message);
+      _storeForSession(sessionId, storedMessage);
       _incrementUnread(sessionId);
       final sessions = ref.read(sessionsProvider);
       final session = sessions.firstWhere(
@@ -339,12 +365,11 @@
       return;
     }
 
-    ref.read(messagesProvider.notifier).addMessage(message);
+    ref.read(messagesProvider.notifier).addMessage(storedMessage);
     ref.read(isTypingProvider.notifier).state = false;
     _scrollToBottom();
 
     if (audioData != null && !AudioService.isBackgrounded && !_isCatchingUp && !_isRecording) {
-      // Queue incoming voice chunks — don't play while recording
       AudioService.queueBase64(audioData);
     }
   }

--
Gitblit v1.3.1