From 15e79ece4127d8eb69e192927d7a65e3ab485354 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Sun, 22 Mar 2026 20:18:18 +0100
Subject: [PATCH] fix: play/pause toggle - await stop before setting playing ID

---
 lib/screens/chat_screen.dart |   27 +++++++++++++++++----------
 1 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index a1f82f8..68842d8 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -71,11 +71,12 @@
     if (!mounted) return;
 
     // Listen for playback state changes to reset play button UI
+    // Use a brief delay to avoid race between queue transitions
     AudioService.onPlaybackStateChanged = () {
-      if (mounted) {
-        setState(() {
-          if (!AudioService.isPlaying) {
-            _playingMessageId = null;
+      if (mounted && !AudioService.isPlaying) {
+        Future.delayed(const Duration(milliseconds: 100), () {
+          if (mounted && !AudioService.isPlaying) {
+            setState(() => _playingMessageId = null);
           }
         });
       }
@@ -382,6 +383,7 @@
     _scrollToBottom();
 
     if (audioData != null && !AudioService.isBackgrounded && !_isCatchingUp && !_isRecording) {
+      setState(() => _playingMessageId = storedMessage.id);
       AudioService.queueBase64(audioData);
     }
   }
@@ -483,6 +485,11 @@
   String? _recordingSessionId; // Capture session at recording start
 
   Future<void> _startRecording() async {
+    // Stop any playing audio before recording
+    if (AudioService.isPlaying) {
+      await AudioService.stopPlayback();
+      setState(() => _playingMessageId = null);
+    }
     _recordingSessionId = ref.read(activeSessionIdProvider);
     final path = await AudioService.startRecording();
     if (path != null) {
@@ -554,21 +561,21 @@
     }
   }
 
-  void _playMessage(Message message) {
+  void _playMessage(Message message) async {
     if (message.audioUri == null) return;
 
     // Toggle: if this message is already playing, stop it
     if (_playingMessageId == message.id) {
-      AudioService.stopPlayback();
+      await AudioService.stopPlayback();
       setState(() => _playingMessageId = null);
       return;
     }
 
-    // Stop any current playback first
-    if (_playingMessageId != null) {
-      AudioService.stopPlayback();
-    }
+    // Stop any current playback first, then set playing ID AFTER stop completes
+    // (stopPlayback triggers onPlaybackStateChanged which clears _playingMessageId)
+    await AudioService.stopPlayback();
 
+    if (!mounted) return;
     setState(() => _playingMessageId = message.id);
 
     if (message.audioUri!.startsWith('/')) {

--
Gitblit v1.3.1