From 1481d1244b9e53a5c254a6b00db374fc881c3073 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 29 Jul 2026 02:10:51 +0300 Subject: [PATCH] fix: seekVersion forces LaunchedEffect restart on seek/resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When playing=true and seek happens, LaunchedEffect(playing) key didn't change, so the elapsed timer kept using the old start time. Added seekVersion counter as second key — increments on waveform tap and play/resume click, forcing the timer coroutine to restart with the new elapsedMs position. --- .../main/java/com/utun/chat/ui/components/MessageBubble.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/MessageBubble.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/MessageBubble.kt index 2534ef29..abcab169 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/MessageBubble.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/MessageBubble.kt @@ -88,6 +88,7 @@ private fun VoiceBubble(message: Message, textColor: Color, val durMs = message.voiceDurationMs var playing by remember { mutableStateOf(false) } var paused by remember { mutableStateOf(false) } + var seekVersion by remember { mutableStateOf(0) } var elapsedMs by remember { mutableStateOf(0) } var progress by remember { mutableStateOf(0f) } @@ -95,7 +96,7 @@ private fun VoiceBubble(message: Message, textColor: Color, val onPaused = remember { { paused = true; playing = false } } /* elapsed timer while playing */ - LaunchedEffect(playing) { + LaunchedEffect(playing, seekVersion) { if (playing && !paused) { val start = System.currentTimeMillis() - elapsedMs while (playing && !paused) { @@ -116,6 +117,7 @@ private fun VoiceBubble(message: Message, textColor: Color, if (playing && !paused) { onPlay(message.filePath, onDone, onPaused) } else { + seekVersion++ playing = true; paused = false onPlay(message.filePath, onDone, onPaused) } @@ -136,6 +138,7 @@ private fun VoiceBubble(message: Message, textColor: Color, if (message.filePath.isEmpty()) return@detectTapGestures val seekFrac = (offset.x / size.width).coerceIn(0f, 1f) val seekMs = (seekFrac * durMs).toInt() + seekVersion++ playing = true; paused = false; elapsedMs = seekMs; progress = seekFrac onSeek(message.filePath, seekMs, onDone) }