From 09baaeb77d3b0bb44075f3e09c3b57bdea0e9ee6 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Wed, 4 Nov 2026 10:46:49 +0000 Subject: [PATCH] playback: keep speculative prepare failures quiet A restore now prepares the saved window before any play gesture, so a network failure at launch reached the error listener and showed a toast even though the user had not asked to play. Only report playback errors when playback was requested. The new tests now wait for the prepare operation rather than the window contents, which can be observed a poll before the prepare lands. --- .../subtracks/playback/PlaybackController.kt | 2 +- .../playback/PlaybackControllerTest.kt | 25 ++++++++++++++++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/src/main/kotlin/com/subtracks/playback/PlaybackController.kt b/app/src/main/kotlin/com/subtracks/playback/PlaybackController.kt index 667fe2dc..339280da 100644 --- a/app/src/main/kotlin/com/subtracks/playback/PlaybackController.kt +++ b/app/src/main/kotlin/com/subtracks/playback/PlaybackController.kt @@ -1452,7 +1452,7 @@ class PlaybackController( } override fun onError(message: UiMessage) { - showMessage(message) + if (player?.playWhenReady == true) showMessage(message) refresh() } } diff --git a/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt b/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt index acfbf07d..abd34bd9 100644 --- a/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt +++ b/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt @@ -348,15 +348,33 @@ class PlaybackControllerTest { runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) } controller.connect() - await { handle.items.isNotEmpty() } + await { handle.operations.contains("prepare") } - assertTrue(handle.operations.contains("prepare")) assertFalse(handle.operations.contains("play")) assertFalse(handle.isIdle) assertFalse(handle.playWhenReady) assertFalse(controller.state.value.isPlaying) } + @Test + fun aPrepareFailureBeforePlaybackIsNotReported() { + seedAlbum(3, sourceId = 1) + runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) } + + controller.connect() + await { handle.operations.contains("prepare") } + + handle.fail(UiMessage(R.string.playback_error_network)) + assertTrue(messages.isEmpty()) + + controller.togglePlayPause() + await { handle.operations.contains("play") } + handle.fail(UiMessage(R.string.playback_error_network)) + await { messages.isNotEmpty() } + + assertEquals(1, messages.size) + } + @Test fun restoringAnEmptyQueueDoesNotPrepare() { seedAlbum(3, sourceId = 1) @@ -387,14 +405,13 @@ class PlaybackControllerTest { runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) } controller.connect() - await { handle.items.isNotEmpty() } + await { handle.operations.contains("prepare") } handle.operations.clear() controller.togglePlayPause() await { handle.operations.contains("play") } assertEquals(listOf("play"), handle.operations) - assertTrue(handle.playWhenReady) } @Test