mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2026-10-22 23:42:14 +03:00
Fix Play Next ignoring shuffle order (#1222)
This commit is contained in:
1 parent
bd39b61f02
commit
37b6ad2271
2 files changed
+48
-2
No files matched your search
@@ -29,6 +29,9 @@ This is a list of requirements that the internal playback is built around.
|
||||
play order and starts at its first item while shuffle is enabled.
|
||||
- Adding "next" during shuffle puts all inserted items immediately after the current item in their
|
||||
supplied order; Media3's randomly assigned insertion positions must not leak into the UI order.
|
||||
Implementation: `QueueAwarePlayer.addMediaItems` detects `shuffleModeEnabled && index ==
|
||||
currentMediaItemIndex + 1` and rewrites the shuffle order via `ShuffleOrderCoordinator.insertNext`
|
||||
to splice the new items at `currentShufflePos + 1`.
|
||||
- Reordering a shuffled queue changes play order without accidentally treating a play-order row as
|
||||
a canonical Media3 index.
|
||||
- Queue, current item/index/position, repeat mode, shuffle flag, and exact shuffle order survive
|
||||
|
||||
+45
-2
@@ -1,6 +1,7 @@
|
||||
package org.moire.ultrasonic.service
|
||||
|
||||
import androidx.media3.common.C
|
||||
import androidx.media3.common.MediaItem
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Test
|
||||
@@ -103,10 +104,52 @@ class PlaybackQueueActionsTest {
|
||||
verify(playback, never()).play()
|
||||
}
|
||||
|
||||
private fun playback(shuffleEnabled: Boolean): PlaybackRepository {
|
||||
@Test
|
||||
fun `play next without shuffle inserts immediately after current item`() = runTest {
|
||||
val playback = playback(shuffleEnabled = false, currentIndex = 2, queueSize = 5)
|
||||
|
||||
PlaybackQueueActions(playback).add(
|
||||
tracks = emptyList(),
|
||||
insertionMode = QueueInsertionMode.AFTER_CURRENT,
|
||||
autoPlay = false
|
||||
)
|
||||
|
||||
// insertAt = currentMediaItemIndex + 1 = 3
|
||||
verify(playback).addMediaItems(3, emptyList())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `play next with shuffle inserts at correct index for QueueAwarePlayer to reorder`() =
|
||||
runTest {
|
||||
val playback = playback(shuffleEnabled = true, currentIndex = 1, queueSize = 4)
|
||||
|
||||
PlaybackQueueActions(playback).add(
|
||||
tracks = emptyList(),
|
||||
insertionMode = QueueInsertionMode.AFTER_CURRENT,
|
||||
autoPlay = false
|
||||
)
|
||||
|
||||
// insertAt = currentMediaItemIndex + 1 = 2; QueueAwarePlayer handles shuffle order
|
||||
verify(playback).addMediaItems(2, emptyList())
|
||||
}
|
||||
|
||||
private fun playback(
|
||||
shuffleEnabled: Boolean,
|
||||
currentIndex: Int = C.INDEX_UNSET,
|
||||
queueSize: Int = 0
|
||||
): PlaybackRepository {
|
||||
val playback = mock<PlaybackRepository>()
|
||||
val entries = (0 until queueSize).map { i ->
|
||||
PlaybackQueueEntry(mediaItemIndex = i, mediaItem = MediaItem.EMPTY)
|
||||
}
|
||||
whenever(playback.snapshot).thenReturn(
|
||||
MutableStateFlow(PlaybackSnapshot(shuffleModeEnabled = shuffleEnabled))
|
||||
MutableStateFlow(
|
||||
PlaybackSnapshot(
|
||||
shuffleModeEnabled = shuffleEnabled,
|
||||
currentMediaItemIndex = currentIndex,
|
||||
queueInPlayOrder = entries
|
||||
)
|
||||
)
|
||||
)
|
||||
return playback
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user