mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-10 15:11:58 +01:00
replace only the queue items a delete actually changed
Deleting any download re-set the whole queue window, which makes the player re-prepare the current item and audibly pauses. It now rebuilds only the items whose local file appeared or went away, comparing what the window reports with what the repository can resolve, and falls back to the full reload when the window no longer lines up.
This commit is contained in:
@@ -61,6 +61,20 @@ class FakePlayerHandle : PlayerHandle {
|
||||
|
||||
override val currentItem: QueueItem? get() = items.getOrNull(index)
|
||||
|
||||
/** Overrides the URIs the window reports; defaults to a stream URI per item. */
|
||||
@Volatile
|
||||
var uris: List<String> = emptyList()
|
||||
|
||||
override fun itemUris(): List<String?> = uris.ifEmpty { items.map { "http://stream/${it.id}" } }
|
||||
|
||||
override fun replaceItem(
|
||||
index: Int,
|
||||
item: QueueItem,
|
||||
) {
|
||||
operations += "replaceItem($index, ${item.id})"
|
||||
if (index in items.indices) items[index] = item
|
||||
}
|
||||
|
||||
override fun setWindow(
|
||||
items: List<QueueItem>,
|
||||
startIndex: Int,
|
||||
|
||||
@@ -2300,7 +2300,7 @@ class PlaybackControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun refreshingMediaItemsRebuildsTheWindowAtTheSamePosition() {
|
||||
fun refreshingMediaItemsLeavesAnUnaffectedQueueAlone() {
|
||||
seedAlbum(3, sourceId = 1)
|
||||
controller.playAlbum(1, "al1", 0)
|
||||
await { handle.operations.contains("play") }
|
||||
@@ -2308,12 +2308,28 @@ class PlaybackControllerTest {
|
||||
val windows = handle.operations.count { it.startsWith("setWindow") }
|
||||
|
||||
controller.refreshMediaItems()
|
||||
Thread.sleep(200)
|
||||
|
||||
await { handle.operations.count { it.startsWith("setWindow") } > windows }
|
||||
assertEquals(windows, handle.operations.count { it.startsWith("setWindow") })
|
||||
assertEquals("s1", handle.currentItem?.id)
|
||||
assertEquals(42_000L, handle.positionMs)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun refreshingMediaItemsReplacesOnlyAnItemWhoseLocalFileIsGone() {
|
||||
seedAlbum(3, sourceId = 1)
|
||||
controller.playAlbum(1, "al1", 0)
|
||||
await { handle.operations.contains("play") }
|
||||
val windows = handle.operations.count { it.startsWith("setWindow") }
|
||||
handle.uris = handle.items.mapIndexed { index, item -> if (index == 0) "file:///gone" else "http://stream/${item.id}" }
|
||||
|
||||
controller.refreshMediaItems()
|
||||
|
||||
await { handle.operations.any { it.startsWith("replaceItem(0,") } }
|
||||
assertEquals(windows, handle.operations.count { it.startsWith("setWindow") })
|
||||
assertEquals(0, handle.operations.count { it.startsWith("replaceItem(1,") })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun positionTickerAdvancesPositionWithoutEmittingPlaybackState() =
|
||||
runBlocking {
|
||||
|
||||
Reference in New Issue
Block a user