feat(queue): move shuffle/loop controls into queue drawer, scoped to queue
This commit is contained in:
+12
-12
@@ -8,14 +8,8 @@
|
||||
* Server data (library/albums/…) is Tier 2 (see `rtkqPersist.ts`).
|
||||
*/
|
||||
import { instanceStorage } from '../config/instances';
|
||||
import {
|
||||
queueInitialState,
|
||||
type QueueState,
|
||||
} from './slices/queue';
|
||||
import {
|
||||
playerInitialState,
|
||||
type PlayerState,
|
||||
} from './slices/player';
|
||||
import { queueInitialState, type QueueState } from './slices/queue';
|
||||
import { playerInitialState, type PlayerState } from './slices/player';
|
||||
import type { RootState } from './index';
|
||||
|
||||
const QUEUE_KEY = 'queue';
|
||||
@@ -26,11 +20,17 @@ const PLAYER_KEY = 'player';
|
||||
// transient UI, so they are intentionally left out.
|
||||
type PersistedQueue = Pick<
|
||||
QueueState,
|
||||
'entries' | 'currentIndex' | 'source' | 'sourceId' | 'sourceName'
|
||||
| 'entries'
|
||||
| 'currentIndex'
|
||||
| 'source'
|
||||
| 'sourceId'
|
||||
| 'sourceName'
|
||||
| 'shuffle'
|
||||
| 'loop'
|
||||
>;
|
||||
type PersistedPlayer = Pick<
|
||||
PlayerState,
|
||||
'currentTrackId' | 'position' | 'volume' | 'muted' | 'repeat' | 'shuffle'
|
||||
'currentTrackId' | 'position' | 'volume' | 'muted'
|
||||
>;
|
||||
|
||||
function pickQueue(state: QueueState): PersistedQueue {
|
||||
@@ -40,6 +40,8 @@ function pickQueue(state: QueueState): PersistedQueue {
|
||||
source: state.source,
|
||||
sourceId: state.sourceId,
|
||||
sourceName: state.sourceName,
|
||||
shuffle: state.shuffle,
|
||||
loop: state.loop,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -49,8 +51,6 @@ function pickPlayer(state: PlayerState): PersistedPlayer {
|
||||
position: state.position,
|
||||
volume: state.volume,
|
||||
muted: state.muted,
|
||||
repeat: state.repeat,
|
||||
shuffle: state.shuffle,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
|
||||
|
||||
export type RepeatMode = 'none' | 'one' | 'all';
|
||||
|
||||
export interface PlayerState {
|
||||
currentTrackId: string | null;
|
||||
isPlaying: boolean;
|
||||
@@ -9,8 +7,6 @@ export interface PlayerState {
|
||||
duration: number;
|
||||
volume: number;
|
||||
muted: boolean;
|
||||
repeat: RepeatMode;
|
||||
shuffle: boolean;
|
||||
isQueueOpen: boolean;
|
||||
}
|
||||
|
||||
@@ -21,8 +17,6 @@ export const playerInitialState: PlayerState = {
|
||||
duration: 0,
|
||||
volume: 0.78,
|
||||
muted: false,
|
||||
repeat: 'none',
|
||||
shuffle: false,
|
||||
isQueueOpen: false,
|
||||
};
|
||||
|
||||
@@ -58,12 +52,6 @@ export const playerSlice = createSlice({
|
||||
toggleMute(state) {
|
||||
state.muted = !state.muted;
|
||||
},
|
||||
setRepeat(state, action: PayloadAction<RepeatMode>) {
|
||||
state.repeat = action.payload;
|
||||
},
|
||||
toggleShuffle(state) {
|
||||
state.shuffle = !state.shuffle;
|
||||
},
|
||||
toggleQueue(state) {
|
||||
state.isQueueOpen = !state.isQueueOpen;
|
||||
},
|
||||
@@ -79,8 +67,6 @@ export const {
|
||||
setDuration,
|
||||
setVolume,
|
||||
toggleMute,
|
||||
setRepeat,
|
||||
toggleShuffle,
|
||||
toggleQueue,
|
||||
} = playerSlice.actions;
|
||||
export default playerSlice.reducer;
|
||||
|
||||
@@ -23,6 +23,8 @@ export interface QueueState {
|
||||
source: QueueSource;
|
||||
sourceId: string | null;
|
||||
sourceName: string | null;
|
||||
shuffle: boolean;
|
||||
loop: boolean;
|
||||
}
|
||||
|
||||
export const queueInitialState: QueueState = {
|
||||
@@ -31,6 +33,8 @@ export const queueInitialState: QueueState = {
|
||||
source: 'manual',
|
||||
sourceId: null,
|
||||
sourceName: null,
|
||||
shuffle: false,
|
||||
loop: false,
|
||||
};
|
||||
|
||||
export const queueSlice = createSlice({
|
||||
@@ -82,7 +86,15 @@ export const queueSlice = createSlice({
|
||||
state.currentIndex = action.payload;
|
||||
},
|
||||
nextTrack(state) {
|
||||
if (state.currentIndex < state.entries.length - 1) state.currentIndex++;
|
||||
if (state.shuffle && state.entries.length > 1) {
|
||||
let next = state.currentIndex;
|
||||
while (next === state.currentIndex) {
|
||||
next = Math.floor(Math.random() * state.entries.length);
|
||||
}
|
||||
state.currentIndex = next;
|
||||
} else if (state.currentIndex < state.entries.length - 1) {
|
||||
state.currentIndex++;
|
||||
}
|
||||
},
|
||||
prevTrack(state) {
|
||||
if (state.currentIndex > 0) state.currentIndex--;
|
||||
@@ -91,6 +103,12 @@ export const queueSlice = createSlice({
|
||||
state.entries = [];
|
||||
state.currentIndex = -1;
|
||||
},
|
||||
toggleShuffle(state) {
|
||||
state.shuffle = !state.shuffle;
|
||||
},
|
||||
toggleLoop(state) {
|
||||
state.loop = !state.loop;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -105,5 +123,7 @@ export const {
|
||||
nextTrack,
|
||||
prevTrack,
|
||||
clearQueue,
|
||||
toggleShuffle,
|
||||
toggleLoop,
|
||||
} = queueSlice.actions;
|
||||
export default queueSlice.reducer;
|
||||
|
||||
Reference in New Issue
Block a user