fix(android): AlbumDetail shuffle button actually shuffles

The Shuffle button on AlbumDetail was wired to the same code path
as Play — both called `play(startTrackId = null)` which started the
queue in track order. PlaylistDetail already does inline `.shuffled()`
for shuffle; mirror that on AlbumDetail via a new `shuffle()` VM
method that pre-shuffles the track list before handing it to the
player.

A future refinement could use Media3's `setShuffleModeEnabled` for
play-then-shuffle without disturbing the original queue ordering,
but pre-shuffling matches the existing PlaylistDetail behavior and
keeps both screens consistent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-26 01:01:31 -04:00
parent 802281c7c5
commit a85a95507c
2 changed files with 18 additions and 1 deletions
@@ -87,7 +87,7 @@ fun AlbumDetailScreen(
albumLiked = albumLiked,
likedTrackIds = likedTrackIds,
onPlayAll = { viewModel.play(startTrackId = null) },
onShuffleAll = { viewModel.play(startTrackId = null) },
onShuffleAll = viewModel::shuffle,
onTrackClick = { id -> viewModel.play(startTrackId = id) },
onToggleAlbumLike = viewModel::toggleLikeAlbum,
onToggleTrackLike = viewModel::toggleLikeTrack,
@@ -90,6 +90,23 @@ class AlbumDetailViewModel @Inject constructor(
)
}
/**
* Play the album in shuffled order. Pre-shuffles the list and hands
* the result to the player — matches the PlaylistDetail shuffle
* pattern. A future refinement could use Media3's
* `setShuffleModeEnabled` for play-then-shuffle without disturbing
* the original queue ordering.
*/
fun shuffle() {
val detail = (internal.value as? AlbumDetailUiState.Success)?.detail ?: return
if (detail.tracks.isEmpty()) return
player.setQueue(
tracks = detail.tracks.shuffled(),
initialIndex = 0,
source = "album:${detail.album.id}",
)
}
fun toggleLikeAlbum() {
val desired = !albumLiked.value
viewModelScope.launch {