float the up-next block behind the current track

Re-anchor the block whenever playback lands on a different context track
(skip, previous, jump, shuffle toggle, restore), so "Up next" always
plays next instead of stranding the block behind a track the listener
has moved past. reanchorFor reports whether the anchor actually moved,
since the current track's combined position can be unchanged even when
the block shifts.
This commit is contained in:
austinried
2026-10-04 00:30:00 +00:00
parent d5a9a11cef
commit 9832f7c217
4 changed files with 131 additions and 15 deletions
@@ -353,6 +353,82 @@ class PlaybackControllerTest {
assertTrue(runBlocking { queues.snapshot().upNext }.isEmpty())
}
@Test
fun skippingPastTheQueueBringsItBackBehindTheCurrentTrack() {
seedAlbum(4, sourceId = 1)
seedSong("x1", "al2")
controller.playAlbum(1, "al1", 1)
await {
controller.state.value.item
?.id == "s2"
}
controller.addToQueue(1, QueueKind.Song, "x1")
await { runBlocking { controller.upcomingItem()?.id } == "x1" }
controller.playAt(4)
await {
controller.state.value.item
?.id == "s4"
}
await { runBlocking { controller.upcomingItem()?.id } == "x1" }
controller.next()
await {
controller.state.value.item
?.id == "x1"
}
}
@Test
fun goingBackInTheContextBringsTheQueueBackWithIt() {
seedAlbum(4, sourceId = 1)
seedSong("x1", "al2")
controller.playAlbum(1, "al1", 2)
await {
controller.state.value.item
?.id == "s3"
}
controller.addToQueue(1, QueueKind.Song, "x1")
controller.previous()
await {
controller.state.value.item
?.id == "s2"
}
await { runBlocking { controller.upcomingItem()?.id } == "x1" }
controller.next()
await {
controller.state.value.item
?.id == "x1"
}
}
@Test
fun togglingShuffleKeepsTheQueueBehindTheCurrentTrack() {
seedAlbum(4, sourceId = 1)
seedSong("x1", "al2")
controller.playAlbum(1, "al1", 1)
await {
controller.state.value.item
?.id == "s2"
}
controller.addToQueue(1, QueueKind.Song, "x1")
controller.toggleShuffle()
await { controller.state.value.shuffle }
await { runBlocking { controller.upcomingItem()?.id } == "x1" }
controller.next()
await {
controller.state.value.item
?.id == "x1"
}
}
@Test
fun theDurationUsesTheNextTracksMetadataWhileItLoads() {
seedAlbum(3, sourceId = 1)