From 4779bfc88bd3e0b874c38c367a9f52535cbf8e82 Mon Sep 17 00:00:00 2001 From: austinried <4966622+austinried@users.noreply.github.com> Date: Sat, 3 Oct 2026 05:04:46 +0000 Subject: [PATCH] keep playback running when offline mode is toggled, and swap the recently-added header icon --- .../com/subtracks/playback/PlaybackController.kt | 13 +++++++++---- .../main/kotlin/com/subtracks/ui/home/HomeScreen.kt | 4 ++-- .../subtracks/playback/PlaybackControllerTest.kt | 6 ++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/app/src/main/kotlin/com/subtracks/playback/PlaybackController.kt b/app/src/main/kotlin/com/subtracks/playback/PlaybackController.kt index 3028d59b..6e463de1 100644 --- a/app/src/main/kotlin/com/subtracks/playback/PlaybackController.kt +++ b/app/src/main/kotlin/com/subtracks/playback/PlaybackController.kt @@ -1321,8 +1321,7 @@ class PlaybackController( if (snapshot.size == 0L) return@withLock downloads.awaitLoaded() val current = currentPosition() ?: return@withLock - val positionMs = player.currentPositionMs - val autoplay = player.playWhenReady + windowJob?.cancel() val target = if (offline) { downloadedAtOrAfter(snapshot, current) ?: run { @@ -1332,9 +1331,15 @@ class PlaybackController( } else { current } - windowJob?.cancel() queueRepository.setCursor(target) - loadWindow(target, autoplay = autoplay, startPositionMs = if (target == current) positionMs else 0) + if (target == current) { + // Keep the playing item in place and only add/remove its neighbours, so a downloaded + // track does not re-prepare (and audibly gap) when offline mode is toggled. + rebuildWindow(queueRepository.window(snapshot, target, QUEUE_WINDOW_RADIUS), target) + refresh(target) + } else { + loadWindow(target, autoplay = player.playWhenReady, startPositionMs = 0) + } } private fun movedCursor( diff --git a/app/src/main/kotlin/com/subtracks/ui/home/HomeScreen.kt b/app/src/main/kotlin/com/subtracks/ui/home/HomeScreen.kt index fcac39ea..f65d71f4 100644 --- a/app/src/main/kotlin/com/subtracks/ui/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/subtracks/ui/home/HomeScreen.kt @@ -27,9 +27,9 @@ import androidx.compose.material.icons.rounded.CalendarMonth import androidx.compose.material.icons.rounded.Category import androidx.compose.material.icons.rounded.Groups import androidx.compose.material.icons.rounded.History +import androidx.compose.material.icons.rounded.LibraryAdd import androidx.compose.material.icons.rounded.LocalFireDepartment import androidx.compose.material.icons.rounded.MusicNote -import androidx.compose.material.icons.rounded.NewReleases import androidx.compose.material.icons.rounded.Person import androidx.compose.material.icons.rounded.Replay import androidx.compose.material.icons.rounded.Star @@ -496,7 +496,7 @@ private val HomeSection.icon: ImageVector HomeSection.Genres -> Icons.Rounded.Category HomeSection.Decades -> Icons.Rounded.CalendarMonth HomeSection.RecentlyStarredSongs -> Icons.Rounded.Star - HomeSection.RecentlyAddedAlbums -> Icons.Rounded.NewReleases + HomeSection.RecentlyAddedAlbums -> Icons.Rounded.LibraryAdd HomeSection.Rediscover -> Icons.Rounded.Replay } diff --git a/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt b/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt index d9c321e6..394a7d0c 100644 --- a/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt +++ b/app/src/test/kotlin/com/subtracks/playback/PlaybackControllerTest.kt @@ -2535,7 +2535,8 @@ class PlaybackControllerTest { handle.operations.clear() setOnline() - await { handle.operations.any { it.startsWith("setWindow") } } + await { handle.operations.any { it.startsWith("add") } } + assertFalse(handle.operations.any { it.startsWith("setWindow") }) assertEquals( "s5", controller.state.value.item @@ -2801,7 +2802,8 @@ class PlaybackControllerTest { setOffline() - await { handle.operations.any { it.startsWith("setWindow") } } + await { handle.operations.any { it.startsWith("remove") || it.startsWith("add") } } + assertFalse(handle.operations.any { it.startsWith("setWindow") }) assertEquals( "s2", controller.state.value.item