mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-15 00:42:54 +01:00
playback: preserve detached fallback queue state
This commit is contained in:
@@ -161,6 +161,7 @@ class PlaybackController(
|
|||||||
private var windowFiltered = false
|
private var windowFiltered = false
|
||||||
private var detachedWindow = false
|
private var detachedWindow = false
|
||||||
private var detachedPosition: Long? = null
|
private var detachedPosition: Long? = null
|
||||||
|
private var detachedFallbackPosition: Long? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
queueRepository.setResetListener { reset ->
|
queueRepository.setResetListener { reset ->
|
||||||
@@ -1505,9 +1506,11 @@ class PlaybackController(
|
|||||||
private fun markDetached(
|
private fun markDetached(
|
||||||
window: List<QueueWindowItem>,
|
window: List<QueueWindowItem>,
|
||||||
position: Long?,
|
position: Long?,
|
||||||
|
fallbackPosition: Long?,
|
||||||
) {
|
) {
|
||||||
detachedWindow = true
|
detachedWindow = true
|
||||||
detachedPosition = position
|
detachedPosition = position
|
||||||
|
detachedFallbackPosition = fallbackPosition
|
||||||
windowFiltered = offline
|
windowFiltered = offline
|
||||||
windowPositions = LongArray(window.size + 1) { if (it == 0) DETACHED_POSITION else window[it - 1].position }
|
windowPositions = LongArray(window.size + 1) { if (it == 0) DETACHED_POSITION else window[it - 1].position }
|
||||||
windowStart = window.firstOrNull()?.position ?: 0L
|
windowStart = window.firstOrNull()?.position ?: 0L
|
||||||
@@ -1517,6 +1520,7 @@ class PlaybackController(
|
|||||||
private fun clearDetached() {
|
private fun clearDetached() {
|
||||||
detachedWindow = false
|
detachedWindow = false
|
||||||
detachedPosition = null
|
detachedPosition = null
|
||||||
|
detachedFallbackPosition = null
|
||||||
windowFiltered = offline
|
windowFiltered = offline
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1536,7 +1540,7 @@ class PlaybackController(
|
|||||||
windowEnd = windowPositions.lastOrNull() ?: -1L
|
windowEnd = windowPositions.lastOrNull() ?: -1L
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun currentQueuePosition(): Long? = currentPosition() ?: detachedPosition
|
private fun currentQueuePosition(): Long? = currentPosition() ?: detachedPosition ?: detachedFallbackPosition
|
||||||
|
|
||||||
private suspend fun rebuildWindow(
|
private suspend fun rebuildWindow(
|
||||||
window: List<QueueWindowItem>,
|
window: List<QueueWindowItem>,
|
||||||
@@ -1586,7 +1590,7 @@ class PlaybackController(
|
|||||||
if (!detachedWindow || currentPosition() != null) return false
|
if (!detachedWindow || currentPosition() != null) return false
|
||||||
queueRepository.setCursor(position)
|
queueRepository.setCursor(position)
|
||||||
rebuildDetachedSurvivors(snapshot, position)
|
rebuildDetachedSurvivors(snapshot, position)
|
||||||
refresh(position)
|
refresh(lastPosition)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1608,7 +1612,7 @@ class PlaybackController(
|
|||||||
updating = false
|
updating = false
|
||||||
}
|
}
|
||||||
val next = window.firstOrNull()?.position
|
val next = window.firstOrNull()?.position
|
||||||
markDetached(window, next)
|
markDetached(window, next, nearest.takeIf { snapshot.size > 0L })
|
||||||
lastPosition = next
|
lastPosition = next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4021,6 +4021,59 @@ class PlaybackControllerTest {
|
|||||||
assertEquals(0L, controller.state.value.position)
|
assertEquals(0L, controller.state.value.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun offlineDetachedPlaybackWithoutAForwardSurvivorCanPlayPrevious() {
|
||||||
|
detachOfflineTrackWithoutAForwardSurvivor()
|
||||||
|
|
||||||
|
controller.previousTrack()
|
||||||
|
|
||||||
|
await { handle.currentItem?.id == "s1" && controller.state.value.position == 0L }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun offlineDetachedPlaybackWithoutAForwardSurvivorCanRemoveAnEarlierTrack() {
|
||||||
|
detachOfflineTrackWithoutAForwardSurvivor()
|
||||||
|
|
||||||
|
runBlocking { controller.removeAt(0) }
|
||||||
|
|
||||||
|
val snapshot = runBlocking { queues.snapshot() }
|
||||||
|
assertEquals(1L, snapshot.size)
|
||||||
|
assertEquals("s3", runBlocking { queues.itemAt(snapshot, 0) }?.song?.id)
|
||||||
|
assertEquals(listOf("s2"), handle.items.map { it.id })
|
||||||
|
assertNull(controller.state.value.position)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun offlineDetachedPlaybackWithoutAForwardSurvivorReloadsWhenOnline() {
|
||||||
|
detachOfflineTrackWithoutAForwardSurvivor()
|
||||||
|
|
||||||
|
setOnline()
|
||||||
|
|
||||||
|
await { handle.items.map { it.id } == listOf("s2", "s3") }
|
||||||
|
controller.next()
|
||||||
|
await { handle.currentItem?.id == "s3" && controller.state.value.position == 1L }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun clearingTheFinalDetachedSurvivorPublishesNoQueuePosition() {
|
||||||
|
seedAlbum(1, sourceId = 1)
|
||||||
|
seedSong("x1", "al2")
|
||||||
|
controller.playAlbum(1, "al1", 0)
|
||||||
|
await { handle.currentItem?.id == "s1" && controller.state.value.isPlaying }
|
||||||
|
controller.addToQueue(1, QueueKind.Song, "x1")
|
||||||
|
await { runBlocking { queues.snapshot().upNextSize } == 1L }
|
||||||
|
val point = runBlocking { queues.captureResetPoint() }
|
||||||
|
runBlocking { db.libraryDao().deleteSongs(1, listOf("s1")) }
|
||||||
|
runBlocking { queues.resetChangedOrigins(setOf(QueueOrigin(QueueKind.Album, 1, "al1")), point) }
|
||||||
|
await { handle.items.map { it.id } == listOf("s1", "x1") && controller.state.value.position == 0L }
|
||||||
|
|
||||||
|
controller.clearUpNext()
|
||||||
|
|
||||||
|
await { handle.items.map { it.id } == listOf("s1") }
|
||||||
|
assertEquals(0L, runBlocking { queues.snapshot().size })
|
||||||
|
assertNull(controller.state.value.position)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun aResetRemapsAContextTrackThatMovedToUpNext() {
|
fun aResetRemapsAContextTrackThatMovedToUpNext() {
|
||||||
seedPlaylist(5)
|
seedPlaylist(5)
|
||||||
|
|||||||
Reference in New Issue
Block a user