27766ae063
test-web / test (push) Successful in 39s
When the whole queue proves unplayable (e.g. a tab left open across the daily system-playlist rebuild — the exact stale-snapshot case), the player now re-pulls the fresh snapshot and resumes instead of dead-ending on "Try again". The seeder hands the store an opaque refetch closure so the store stays decoupled from the playlist API and the per-artist (songs_like_artist) identity problem: single-instance variants re-pull via systemShuffle, per-artist mixes via getPlaylist(id), radio re-seeds from its track. Bounded to one self-heal per exhaustion (reset on the next successful play) so a still-broken refresh can't loop; "Try again" stays the genuine last resort. Wired from PlaylistCard, the playlist detail page, and playRadio. Issue #968. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
34 lines
1.2 KiB
TypeScript
34 lines
1.2 KiB
TypeScript
import type { TrackRef, PlaylistDetail } from '$lib/api/types';
|
|
import { systemShuffle, getPlaylist } from '$lib/api/playlists';
|
|
import { playlistTrackToRef } from './playlistTrackToRef';
|
|
|
|
// #968: builds the self-heal closure for a system-playlist queue. On total
|
|
// playback failure (every queued track unplayable — typically a stale tab
|
|
// left open across the daily rebuild) the player calls this to re-pull the
|
|
// current snapshot and resume.
|
|
//
|
|
// Single-instance variants (for_you, discover, deep_cuts, …) re-pull by
|
|
// variant via the rotation-aware shuffle endpoint. Per-artist mixes
|
|
// (songs_like_artist — one playlist per seed artist) can't be addressed by
|
|
// variant alone, so they re-pull by playlist id. Mirrors the play routing
|
|
// in PlaylistCard.
|
|
|
|
function toRefs(detail: PlaylistDetail): TrackRef[] {
|
|
return detail.tracks
|
|
.map((r) => playlistTrackToRef(r))
|
|
.filter((t): t is TrackRef => t !== null);
|
|
}
|
|
|
|
export function systemPlaylistRefetch(opts: {
|
|
variant: string;
|
|
playlistId: string;
|
|
perArtist: boolean;
|
|
}): () => Promise<TrackRef[]> {
|
|
return async () => {
|
|
const detail = opts.perArtist
|
|
? await getPlaylist(opts.playlistId)
|
|
: await systemShuffle(opts.variant);
|
|
return toRefs(detail);
|
|
};
|
|
}
|