From d17b6376e8137447c244693853fd05b57aaf368f Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Tue, 24 Mar 2026 13:55:54 +0100
Subject: [PATCH] fix: audio queue debug logging, 200ms playback state delay

---
 lib/services/audio_service.dart |   15 +++++++++++----
 lib/screens/chat_screen.dart    |   25 +++++++++++++------------
 2 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index fb675e6..2e1155a 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -86,12 +86,18 @@
     // Listen for playback state changes to reset play button UI
     // Use a brief delay to avoid race between queue transitions
     AudioService.onPlaybackStateChanged = () {
-      if (mounted && !AudioService.isPlaying) {
-        Future.delayed(const Duration(milliseconds: 100), () {
-          if (mounted && !AudioService.isPlaying) {
-            setState(() => _playingMessageId = null);
-          }
-        });
+      if (mounted) {
+        if (AudioService.isPlaying) {
+          // Something started playing — keep the indicator as-is
+        } else {
+          // Playback stopped — clear indicator only if queue is truly empty.
+          // Use a short delay since the queue transition has a brief gap.
+          Future.delayed(const Duration(milliseconds: 200), () {
+            if (mounted && !AudioService.isPlaying) {
+              setState(() => _playingMessageId = null);
+            }
+          });
+        }
       }
     };
 
@@ -519,12 +525,7 @@
     _scrollToBottom();
 
     if (audioData != null && !AudioService.isBackgrounded && !_isCatchingUp && !_isRecording) {
-      // Only set playing ID if nothing is currently playing (first chunk).
-      // Subsequent chunks just queue audio without touching the play indicator,
-      // preventing the completion callback race from clearing it prematurely.
-      if (_playingMessageId == null) {
-        setState(() => _playingMessageId = storedMessage.id);
-      }
+      setState(() => _playingMessageId = storedMessage.id);
       AudioService.queueBase64(audioData);
     }
   }
diff --git a/lib/services/audio_service.dart b/lib/services/audio_service.dart
index 680a0fd..0da9b0f 100644
--- a/lib/services/audio_service.dart
+++ b/lib/services/audio_service.dart
@@ -167,13 +167,20 @@
     if (path == null) return;
 
     if (_isPlaying) {
-      // Already playing — just add to queue, it will play when current finishes
+      // Already playing — add to queue, plays when current finishes
       _queue.add(path);
+      debugPrint('AudioService: queued (queue size: ${_queue.length})');
     } else {
       // Nothing playing — start immediately
-      await _player.play(DeviceFileSource(path));
-      _isPlaying = true;
-      onPlaybackStateChanged?.call();
+      try {
+        await _player.play(DeviceFileSource(path));
+        _isPlaying = true;
+        onPlaybackStateChanged?.call();
+        debugPrint('AudioService: playing immediately');
+      } catch (e) {
+        debugPrint('AudioService: play failed: $e');
+        _onTrackComplete();
+      }
     }
   }
 

--
Gitblit v1.3.1