Skip to content

Implement shuffle - #3381

Open
FrayxRulez wants to merge 1 commit into
playback-reconcilefrom
playback-shuffle
Open

Implement shuffle#3381
FrayxRulez wants to merge 1 commit into
playback-reconcilefrom
playback-shuffle

Conversation

@FrayxRulez

Copy link
Copy Markdown
Collaborator

Third of three. Stacked on #3380 — base retargets as the stack merges.

Shuffle has been a GlyphToggleButton in PlaybackHeader and PlaybackPopup with its handler
commented out, setting IsReversed instead, because shuffle itself was never written.

The order

_shuffled holds the same items as the playlist in a fixed order, and Next / Previous walk it
instead of the playlist. Fixed rather than a fresh random pick each time, so Previous goes back
to the track that was actually heard. MoveNextImpl and MovePreviousImpl needed one line each —
they now index Order instead of _items, and the existing bounds, repeat and stop handling
works unchanged on it.

The track playing when shuffle is switched on goes to the front of the order, rather than sitting
somewhere Next would reach again later. Switching shuffle off drops the order instead of
remembering it: coming back to a shuffle from an hour ago is not what the button means.

Pages loaded later are inserted at random positions after the current one. What is behind it
has been heard, and dropping a new track back there would have Previous replay something that
never played.

Paging

SetSource no longer derives the paging trigger from the index it was given, since with shuffle
that index is a position in the shuffled order and says nothing about how much of the playlist is
left to load. LoadMoreAround looks the track up in the playlist instead. Play(PlaybackItem)
jumping straight to a track from the popup — now triggers it too, which it never did.

Notifications

SettingsChanged is new on IPlaybackService. Repeat and shuffle can both be changed from the
system transport controls, so the buttons cannot only be refreshed by whoever pressed them; both
surfaces subscribe alongside StateChanged. UpdateRepeat is renamed UpdateModes now that it
drives both buttons.

The shuffle button's tooltip is the plain Strings.Shuffle rather than a state-specific pair like
repeat's. Repeat is tri-state and a two-state toggle cannot express it, so its name has to carry
it; shuffle is binary and ToggleButton announces on/off on its own, so a state-specific name
would say it twice. No new strings needed.

Notes

  • The playlist popup still lists items in playlist order, not shuffle order. That is deliberate:
    drag-reorder there maps onto setProfileAudioPosition, which only means anything in the real
    order.
  • Wrapping with repeat-list on replays the same order rather than reshuffling. Defensible either
    way; say the word if you want a reshuffle on wrap.
  • IsReversed now has no writer. The shuffle button was its only one. It is still on
    IPlaybackService and still threaded through the navigation logic, where it does nothing. Left
    alone rather than deleted in the same PR that adds shuffle — removing it would simplify
    MoveNextImpl / MovePreviousImpl noticeably, if you want that as a follow-up.

Testing

Builds clean. Not exercised at runtime.

🤖 Generated with Claude Code

The button existed in two places and set IsReversed, since shuffle itself
was never written. It now walks a fixed shuffled order, so Previous goes
back to what was actually heard, and pages loaded later are folded into
the part not yet played.

Paging is measured against the playlist rather than the order being
walked, which shuffle reaches the ends of in no particular order.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant