playback: turn off shuffle when a song is tapped

This commit is contained in:
austinried
2026-11-12 04:31:58 +00:00
parent 11276c2e1f
commit 29335f7ddf
4 changed files with 14 additions and 51 deletions
@@ -106,7 +106,6 @@ private data class ReloadUndo(
private data class PendingPlay( private data class PendingPlay(
val entries: List<QueueEntry>, val entries: List<QueueEntry>,
val position: Long, val position: Long,
val disableShuffle: Boolean,
) )
class PlaybackController( class PlaybackController(
@@ -191,7 +190,7 @@ class PlaybackController(
val shuffle = pendingShuffle val shuffle = pendingShuffle
pendingShuffle = null pendingShuffle = null
when { when {
pending != null -> start(pending.entries, pending.position, pending.disableShuffle) pending != null -> start(pending.entries, pending.position)
shuffle != null -> startShuffled(shuffle) shuffle != null -> startShuffled(shuffle)
else -> restore() else -> restore()
} }
@@ -240,16 +239,6 @@ class PlaybackController(
startOrdinal: Long, startOrdinal: Long,
) = playContext(queueRepository.starredEntry(sourceId), startOrdinal) ) = playContext(queueRepository.starredEntry(sourceId), startOrdinal)
fun playAlbumInOrder(
sourceId: Long,
albumId: String,
) = playContext(queueRepository.albumEntry(sourceId, albumId), 0, disableShuffle = true)
fun playPlaylistInOrder(
sourceId: Long,
playlistId: String,
) = playContext(queueRepository.playlistEntry(sourceId, playlistId), 0, disableShuffle = true)
fun shuffleAlbum( fun shuffleAlbum(
sourceId: Long, sourceId: Long,
albumId: String, albumId: String,
@@ -277,8 +266,7 @@ class PlaybackController(
private fun playContext( private fun playContext(
entry: QueueEntry, entry: QueueEntry,
start: Long, start: Long,
disableShuffle: Boolean = false, ) = play(listOf(entry), start)
) = play(listOf(entry), start, disableShuffle)
private fun shuffleContext(entry: QueueEntry) = shufflePlay(listOf(entry)) private fun shuffleContext(entry: QueueEntry) = shufflePlay(listOf(entry))
@@ -982,20 +970,18 @@ class PlaybackController(
private fun play( private fun play(
entries: List<QueueEntry>, entries: List<QueueEntry>,
startPosition: Long, startPosition: Long,
disableShuffle: Boolean = false,
) { ) {
if (player == null) { if (player == null) {
pendingPlay = PendingPlay(entries, startPosition, disableShuffle) pendingPlay = PendingPlay(entries, startPosition)
connect() connect()
return return
} }
scope.launch { start(entries, startPosition, disableShuffle) } scope.launch { start(entries, startPosition) }
} }
private suspend fun start( private suspend fun start(
entries: List<QueueEntry>, entries: List<QueueEntry>,
startPosition: Long, startPosition: Long,
disableShuffle: Boolean = false,
) = startLock.withLock { ) = startLock.withLock {
windowJob?.cancel() windowJob?.cancel()
windowStart = 0 windowStart = 0
@@ -1003,7 +989,7 @@ class PlaybackController(
lastEdit = null lastEdit = null
endedHandled = false endedHandled = false
val modes = queueRepository.modes() val modes = queueRepository.modes()
shuffleEnabled = !disableShuffle && modes.shuffle shuffleEnabled = false
repeatMode = modes.repeat.toRepeatMode() repeatMode = modes.repeat.toRepeatMode()
player?.setRepeatOne(repeatMode == RepeatMode.One) player?.setRepeatOne(repeatMode == RepeatMode.One)
queueRepository.replace(entries) queueRepository.replace(entries)
@@ -1014,14 +1000,7 @@ class PlaybackController(
stopLocked() stopLocked()
return@withLock return@withLock
} }
val start = startPosition.coerceIn(0, snapshot.contextSize - 1) val position = startPosition.coerceIn(0, snapshot.contextSize - 1)
val position =
if (shuffleEnabled) {
queueRepository.setShuffle(pinnedSeed(snapshot.contextSize, start))
0L
} else {
start
}
queueRepository.setCursor(position) queueRepository.setCursor(position)
this.snapshot = readSnapshot() this.snapshot = readSnapshot()
loadWindow(position, autoplay = true) loadWindow(position, autoplay = true)
@@ -96,7 +96,7 @@ class AlbumDetailViewModel(
fun playAll() { fun playAll() {
viewModelScope.launch { viewModelScope.launch {
playbackController.playAlbumInOrder(sourceId.first(), albumId) playbackController.playAlbum(sourceId.first(), albumId, 0)
} }
} }
@@ -94,7 +94,7 @@ class PlaylistDetailViewModel(
fun playAll() { fun playAll() {
viewModelScope.launch { viewModelScope.launch {
playbackController.playPlaylistInOrder(sourceId.first(), playlistId) playbackController.playPlaylist(sourceId.first(), playlistId, 0)
} }
} }
@@ -2494,7 +2494,7 @@ class PlaybackControllerTest {
} }
@Test @Test
fun tappingASongWhileShuffledPlaysThatSong() { fun tappingASongTurnsOffShuffleAndPlaysThatSong() {
seedAlbum(5, sourceId = 1) seedAlbum(5, sourceId = 1)
controller.playAlbum(1, "al1", 0) controller.playAlbum(1, "al1", 0)
@@ -2509,12 +2509,14 @@ class PlaybackControllerTest {
controller.playAlbum(1, "al1", 3) controller.playAlbum(1, "al1", 3)
await { await {
controller.state.value.item controller.state.value.item
?.id == "s4" ?.id == "s4" && !controller.state.value.shuffle
} }
assertEquals("s4", handle.currentItem?.id) assertEquals("s4", handle.currentItem?.id)
val shuffled = runBlocking { queues.snapshot() } assertEquals(3L, controller.state.value.position)
assertEquals("s4", runBlocking { queues.itemAt(shuffled, controller.state.value.position!!)?.song?.id }) val snapshot = runBlocking { queues.snapshot() }
assertFalse(snapshot.shuffled)
assertEquals("s4", runBlocking { queues.itemAt(snapshot, controller.state.value.position!!)?.song?.id })
} }
@Test @Test
@@ -2730,24 +2732,6 @@ class PlaybackControllerTest {
) )
} }
@Test
fun playInOrderTurnsOffShuffle() {
seedAlbum(3, sourceId = 1)
controller.shuffleAlbum(1, "al1")
await { controller.state.value.shuffle }
controller.playAlbumInOrder(1, "al1")
await { !controller.state.value.shuffle }
assertEquals(
"s1",
controller.state.value.item
?.id,
)
assertEquals(0L, controller.state.value.position)
}
@Test @Test
fun shufflePlayOnASingleTrackAlbumPlaysIt() { fun shufflePlayOnASingleTrackAlbumPlaysIt() {
seedAlbum(1, sourceId = 1) seedAlbum(1, sourceId = 1)