mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
feat(queue): preserve Play Next order toggle (#464)
* feat(queue): add preservePlayNextOrder setting + playNext store action - New Track.playNextAdded flag (analogous to autoAdded / radioAdded). Stale flags behind queueIndex are harmless — only forward streak scan. - New playerStore action playNext(tracks): tags incoming tracks and delegates to enqueueAt for unified undo + server sync. - New authStore boolean preservePlayNextOrder (default false). When on, playNext appends behind the existing Play-Next streak (Spotify-style) instead of inserting directly after the current track. * refactor(context-menu): centralise Play Next; add Settings toggle + i18n - Replace 3 inline splice/enqueueAt call sites in ContextMenu with the new playNext action. Side-benefit: the single-song path now goes through enqueueAt and gets undo + queue sync (previously missing). - Settings → Audio → Playback: new toggle below Gapless. - 8 locales: preservePlayNextOrder + preservePlayNextOrderDesc. * docs(contributors): credit + changelog entry for #464
This commit is contained in:
committed by
GitHub
parent
e1f2cb4c37
commit
0fab2849e5
@@ -73,6 +73,10 @@ export interface Track {
|
||||
size?: number;
|
||||
autoAdded?: boolean;
|
||||
radioAdded?: boolean;
|
||||
/** Inserted via "Play Next". Used by the preserve-order toggle to find the
|
||||
* end of the current Play-Next streak. Stale flags behind queueIndex are
|
||||
* harmless — the streak scan only looks forward from queueIndex+1. */
|
||||
playNextAdded?: boolean;
|
||||
}
|
||||
|
||||
export function songToTrack(song: SubsonicSong): Track {
|
||||
@@ -260,6 +264,12 @@ interface PlayerState {
|
||||
setProgress: (t: number, duration: number) => void;
|
||||
enqueue: (tracks: Track[], _orbitConfirmed?: boolean) => void;
|
||||
enqueueAt: (tracks: Track[], insertIndex: number, _orbitConfirmed?: boolean) => void;
|
||||
/** "Play Next" — inserts after the current track. When
|
||||
* `preservePlayNextOrder` is on, appends to the existing Play-Next streak
|
||||
* (Spotify-style); otherwise inserts directly after the current track and
|
||||
* pushes any earlier Play-Next items down (default). Falls back to
|
||||
* `playTrack` when nothing is currently playing. */
|
||||
playNext: (tracks: Track[]) => void;
|
||||
enqueueRadio: (tracks: Track[], artistId?: string) => void;
|
||||
setRadioArtistId: (artistId: string) => void;
|
||||
/** For Lucky Mix: drop upcoming tail; keep the currently playing item only. */
|
||||
@@ -3247,6 +3257,23 @@ export const usePlayerStore = create<PlayerState>()(
|
||||
});
|
||||
},
|
||||
|
||||
playNext: (tracks) => {
|
||||
if (tracks.length === 0) return;
|
||||
const state = get();
|
||||
const tagged = tracks.map(t => ({ ...t, playNextAdded: true as const }));
|
||||
if (!state.currentTrack) {
|
||||
state.playTrack(tagged[0], tagged);
|
||||
return;
|
||||
}
|
||||
const baseIdx = state.queueIndex + 1;
|
||||
let insertIdx = baseIdx;
|
||||
if (useAuthStore.getState().preservePlayNextOrder) {
|
||||
const q = state.queue;
|
||||
while (insertIdx < q.length && q[insertIdx].playNextAdded) insertIdx++;
|
||||
}
|
||||
get().enqueueAt(tagged, insertIdx);
|
||||
},
|
||||
|
||||
clearQueue: () => {
|
||||
invoke('audio_stop').catch(console.error);
|
||||
isAudioPaused = false;
|
||||
|
||||
Reference in New Issue
Block a user