feat(web): #415 stage 3 (web) — rotation-aware system playlist play
Web half of Stage 3. System-playlist tile play now:
- calls the new GET /api/playlists/system/{variant}/shuffle endpoint
(rotation-aware order from the server) instead of getPlaylist;
plays the returned order AS-IS — no client Fisher-Yates, since
the server already ordered it. Supersedes #413's client shuffle
for system playlists specifically; user playlists keep getPlaylist
+ stored order.
- tags the queue with the system variant. The player store carries
_queueSource; the events dispatcher includes `source` on
play_started so the server advances that playlist's rotation.
User playlists are unchanged (getPlaylist, plain playQueue, no
source). Tests updated: For-You play hits systemShuffle (not
getPlaylist/refresh) and passes source:for_you; user play uses
getPlaylist + plain playQueue with no source.
Flutter half is blocked — the Flutter client has no play-event
reporting at all (no /api/events POST, no scrobble), so there's no
play_started to attach `source` to. Surfacing that as a separate
decision rather than silently scope-exploding #415.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import { useQueryClient } from '@tanstack/svelte-query';
|
||||
import type { Playlist, PlaylistTrack, TrackRef } from '$lib/api/types';
|
||||
import { user } from '$lib/auth/store.svelte';
|
||||
import { getPlaylist, refreshDiscover, refreshForYou } from '$lib/api/playlists';
|
||||
import { getPlaylist, systemShuffle, refreshDiscover, refreshForYou } from '$lib/api/playlists';
|
||||
import { playlistTrackToRef } from '$lib/playlists/playlistTrackToRef';
|
||||
import { errCode } from '$lib/api/errors';
|
||||
import { qk } from '$lib/api/queries';
|
||||
@@ -45,14 +45,23 @@
|
||||
if (starting) return;
|
||||
starting = true;
|
||||
try {
|
||||
const detail = await getPlaylist(playlist.id);
|
||||
const refs = toTrackRefs(detail.tracks);
|
||||
if (refs.length > 0) {
|
||||
// System playlists default to shuffle so replaying within a
|
||||
// day feels different. User playlists keep stored order.
|
||||
// Explicit refresh moved to the kebab menu — playing no
|
||||
// longer rebuilds the snapshot.
|
||||
playQueue(refs, 0, { shuffle: playlist.system_variant != null });
|
||||
const variant = playlist.system_variant;
|
||||
if (variant != null) {
|
||||
// #415: server returns the rotation-aware order (unplayed
|
||||
// this rotation first). Play it as-is — no client shuffle —
|
||||
// and tag the queue so play_started carries `source` and
|
||||
// the server advances the rotation.
|
||||
const detail = await systemShuffle(variant);
|
||||
const refs = toTrackRefs(detail.tracks);
|
||||
if (refs.length > 0) {
|
||||
playQueue(refs, 0, { source: variant });
|
||||
}
|
||||
} else {
|
||||
const detail = await getPlaylist(playlist.id);
|
||||
const refs = toTrackRefs(detail.tracks);
|
||||
if (refs.length > 0) {
|
||||
playQueue(refs, 0);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
starting = false;
|
||||
|
||||
Reference in New Issue
Block a user