diff --git a/packages/common/src/store/playback/selectors.ts b/packages/common/src/store/playback/selectors.ts index e4fe3ba0cfc..972a13d5543 100644 --- a/packages/common/src/store/playback/selectors.ts +++ b/packages/common/src/store/playback/selectors.ts @@ -60,10 +60,6 @@ export const getRetries = getPlaybackRetryCount // Shuffle / repeat / overshoot export const getRepeat = (state: CommonState) => state.playback.repeat export const getShuffle = (state: CommonState) => state.playback.shuffle -export const getShuffleIndex = (state: CommonState) => - state.playback.shuffleIndex -export const getShuffleOrder = (state: CommonState) => - state.playback.shuffleOrder export const getOvershot = (state: CommonState) => state.playback.overshot export const getUndershot = (state: CommonState) => state.playback.undershot diff --git a/packages/common/src/store/playback/slice.test.ts b/packages/common/src/store/playback/slice.test.ts index 97eae0420bb..74c387ae4e2 100644 --- a/packages/common/src/store/playback/slice.test.ts +++ b/packages/common/src/store/playback/slice.test.ts @@ -101,4 +101,204 @@ describe('playback slice', () => { expect(cleared.queue).toHaveLength(0) expect(cleared.index).toBe(-1) }) + + describe('shuffle', () => { + it('enabling shuffle reorders queue with current track at position 0', () => { + const tracks = [track(1), track(2), track(3), track(4), track(5)] + const seeded = playbackReducer( + initialState, + actions.playFrom({ tracks, startIndex: 2 }) + ) + const shuffled = playbackReducer( + seeded, + actions.setShuffle({ enable: true }) + ) + expect(shuffled.shuffle).toBe(true) + expect(shuffled.index).toBe(0) + expect(shuffled.queue[0]).toEqual(track(3)) + expect(shuffled.queue).toHaveLength(tracks.length) + expect(new Set(shuffled.queue.map((t) => t.trackId))).toEqual( + new Set(tracks.map((t) => t.trackId)) + ) + expect(shuffled.shuffleOriginalQueue).toEqual(tracks) + expect(shuffled.shuffleOriginalIndices[0]).toBe(2) + }) + + it('next/previous walk the shuffled queue in visible order', () => { + const tracks = [track(1), track(2), track(3), track(4)] + const seeded = playbackReducer( + initialState, + actions.playFrom({ tracks, startIndex: 0 }) + ) + const shuffled = playbackReducer( + seeded, + actions.setShuffle({ enable: true }) + ) + const after1 = playbackReducer(shuffled, actions.next({})) + expect(after1.index).toBe(1) + expect(after1.queue[after1.index]).toEqual(shuffled.queue[1]) + const after2 = playbackReducer(after1, actions.previous()) + expect(after2.index).toBe(0) + }) + + it('disabling shuffle restores original order with current track preserved', () => { + const tracks = [track(1), track(2), track(3), track(4), track(5)] + const seeded = playbackReducer( + initialState, + actions.playFrom({ tracks, startIndex: 0 }) + ) + const shuffled = playbackReducer( + seeded, + actions.setShuffle({ enable: true }) + ) + // Advance once in the shuffled queue. + const advanced = playbackReducer(shuffled, actions.next({})) + const playingTrack = advanced.queue[advanced.index] + const restored = playbackReducer( + advanced, + actions.setShuffle({ enable: false }) + ) + expect(restored.shuffle).toBe(false) + expect(restored.queue).toEqual(tracks) + expect(restored.queue[restored.index]).toEqual(playingTrack) + expect(restored.shuffleOriginalQueue).toEqual([]) + expect(restored.shuffleOriginalIndices).toEqual([]) + }) + + it('removeFromQueue while shuffled removes from both visible and original', () => { + const tracks = [track(1), track(2), track(3), track(4)] + const seeded = playbackReducer( + initialState, + actions.playFrom({ tracks, startIndex: 0 }) + ) + const shuffled = playbackReducer( + seeded, + actions.setShuffle({ enable: true }) + ) + // Remove the visible track at position 1 (some random track). + const removedTrack = shuffled.queue[1] + const afterRemove = playbackReducer( + shuffled, + actions.removeFromQueue({ index: 1 }) + ) + expect(afterRemove.queue).toHaveLength(3) + expect(afterRemove.queue.find((t) => t.trackId === removedTrack.trackId)) + .toBeUndefined() + expect(afterRemove.shuffleOriginalQueue).toHaveLength(3) + expect( + afterRemove.shuffleOriginalQueue.find( + (t) => t.trackId === removedTrack.trackId + ) + ).toBeUndefined() + // Disabling shuffle should restore the remaining 3 in original order. + const restored = playbackReducer( + afterRemove, + actions.setShuffle({ enable: false }) + ) + const expectedRemaining = tracks.filter( + (t) => t.trackId !== removedTrack.trackId + ) + expect(restored.queue).toEqual(expectedRemaining) + }) + + it('addToQueue while shuffled appends to both visible and original', () => { + const tracks = [track(1), track(2), track(3)] + const seeded = playbackReducer( + initialState, + actions.playFrom({ tracks, startIndex: 0 }) + ) + const shuffled = playbackReducer( + seeded, + actions.setShuffle({ enable: true }) + ) + const added = playbackReducer( + shuffled, + actions.addToQueue({ tracks: [track(4)] }) + ) + expect(added.queue).toHaveLength(4) + expect(added.queue[3]).toEqual(track(4)) + expect(added.shuffleOriginalQueue).toHaveLength(4) + expect(added.shuffleOriginalQueue[3]).toEqual(track(4)) + }) + + it('appendPage while shuffled mirrors into original queue', () => { + const tracks = [track(1), track(2)] + const seeded = playbackReducer( + initialState, + actions.playFrom({ tracks, startIndex: 0 }) + ) + const shuffled = playbackReducer( + seeded, + actions.setShuffle({ enable: true }) + ) + const appended = playbackReducer( + shuffled, + actions.appendPage({ tracks: [track(3), track(4)] }) + ) + expect(appended.queue).toHaveLength(4) + expect(appended.shuffleOriginalQueue).toHaveLength(4) + expect(appended.shuffleOriginalIndices).toHaveLength(4) + }) + + it('reorder while shuffled keeps shuffleOriginalQueue intact', () => { + const tracks = [track(1), track(2), track(3)] + const seeded = playbackReducer( + initialState, + actions.playFrom({ tracks, startIndex: 0 }) + ) + const shuffled = playbackReducer( + seeded, + actions.setShuffle({ enable: true }) + ) + const reordered = playbackReducer( + shuffled, + actions.reorder({ orderedIndices: [2, 0, 1] }) + ) + expect(reordered.queue).toEqual([ + shuffled.queue[2], + shuffled.queue[0], + shuffled.queue[1] + ]) + // Original queue is unchanged. + expect(reordered.shuffleOriginalQueue).toEqual(tracks) + // shuffleOriginalIndices follow their tracks. + expect(reordered.shuffleOriginalIndices).toEqual([ + shuffled.shuffleOriginalIndices[2], + shuffled.shuffleOriginalIndices[0], + shuffled.shuffleOriginalIndices[1] + ]) + }) + + it('playFrom while shuffled re-shuffles the new queue', () => { + const seeded = playbackReducer( + { ...initialState, shuffle: true }, + actions.playFrom({ + tracks: [track(1), track(2), track(3), track(4)], + startIndex: 1 + }) + ) + expect(seeded.shuffle).toBe(true) + expect(seeded.index).toBe(0) + // Track originally at startIndex sits at visible position 0. + expect(seeded.queue[0]).toEqual(track(2)) + expect(seeded.shuffleOriginalQueue).toHaveLength(4) + }) + + it('clearUpcoming while shuffled keeps current track and clears state', () => { + const tracks = [track(1), track(2), track(3)] + const seeded = playbackReducer( + initialState, + actions.playFrom({ tracks, startIndex: 0 }) + ) + const shuffled = playbackReducer( + seeded, + actions.setShuffle({ enable: true }) + ) + const cleared = playbackReducer(shuffled, actions.clearUpcoming()) + expect(cleared.queue).toHaveLength(1) + expect(cleared.index).toBe(0) + expect(cleared.shuffleOriginalQueue).toEqual([cleared.queue[0]]) + expect(cleared.shuffleOriginalIndices).toEqual([0]) + }) + }) }) diff --git a/packages/common/src/store/playback/slice.ts b/packages/common/src/store/playback/slice.ts index 11e1ecfbe75..8ddd547a38f 100644 --- a/packages/common/src/store/playback/slice.ts +++ b/packages/common/src/store/playback/slice.ts @@ -26,21 +26,48 @@ export const initialState: PlaybackState = { playbackRate: '1x', repeat: RepeatMode.OFF, shuffle: false, - shuffleOrder: [], - shuffleIndex: -1, + shuffleOriginalQueue: [], + shuffleOriginalIndices: [], querySource: null, retries: 0, overshot: false, undershot: false } -const generateShuffleOrder = (queueLength: number, currentIndex: number) => { - const availableIndices = Array.from( - { length: queueLength }, - (_, i) => i - ).filter((i) => i !== currentIndex) - const shuffled = availableIndices.sort(() => Math.random() - 0.5) - return currentIndex >= 0 ? [currentIndex, ...shuffled] : shuffled +// Build a permutation of [0..length-1] with `currentIndex` (when valid) +// pinned at position 0 — so the currently-playing track stays "current" +// when shuffle toggles on. +const buildShufflePermutation = (length: number, currentIndex: number) => { + const indices = Array.from({ length }, (_, i) => i).filter( + (i) => i !== currentIndex + ) + for (let i = indices.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)) + ;[indices[i], indices[j]] = [indices[j], indices[i]] + } + return currentIndex >= 0 && currentIndex < length + ? [currentIndex, ...indices] + : indices +} + +// Apply a permutation (an array of original indices) to a source array, +// returning a new array in the permuted order. +const applyPermutation = (source: T[], permutation: number[]): T[] => + permutation.map((i) => source[i]) + +// Drop the entry at `position` from `originalIndices` and decrement any +// remaining entries that pointed past it, since shuffleOriginalQueue just +// shrunk by one. +const removeFromOriginalIndices = ( + originalIndices: number[], + visibleIndex: number +) => { + const removedOriginalIndex = originalIndices[visibleIndex] + const next = originalIndices.filter((_, i) => i !== visibleIndex) + for (let i = 0; i < next.length; i++) { + if (next[i] > removedOriginalIndex) next[i] -= 1 + } + return next } type PlayFromPayload = { @@ -97,8 +124,7 @@ type ReorderPayload = { } type SetIndexPayload = { - index?: number - shuffleIndex?: number + index: number } type NextPayload = { skip?: boolean } | undefined @@ -147,36 +173,38 @@ const slice = createSlice({ reducers: { playFrom: (state, action: PayloadAction) => { const { tracks, startIndex, querySource } = action.payload - state.queue = tracks - state.index = Math.max(0, Math.min(startIndex, tracks.length - 1)) + const clampedStart = Math.max(0, Math.min(startIndex, tracks.length - 1)) + if (state.shuffle && tracks.length > 0) { + const permutation = buildShufflePermutation(tracks.length, clampedStart) + state.shuffleOriginalQueue = tracks + state.shuffleOriginalIndices = permutation + state.queue = applyPermutation(tracks, permutation) + state.index = 0 + } else { + state.queue = tracks + state.index = clampedStart + state.shuffleOriginalQueue = [] + state.shuffleOriginalIndices = [] + } state.querySource = querySource ?? null state.counter += 1 state.retries = 0 state.seek = null state.overshot = false state.undershot = false - if (state.shuffle) { - state.shuffleOrder = generateShuffleOrder( - state.queue.length, - state.index - ) - state.shuffleIndex = 0 - } }, playTrackAt: (state, action: PayloadAction) => { const { index } = action.payload if (index < 0 || index >= state.queue.length) return + // Queue is already in playable order (shuffled or not), so we just + // jump to the chosen position. state.index = index state.counter += 1 state.retries = 0 state.seek = null state.overshot = false state.undershot = false - if (state.shuffle) { - state.shuffleOrder = generateShuffleOrder(state.queue.length, index) - state.shuffleIndex = 0 - } }, // Resume / load. The saga handles the load+play cycle and sets retries. @@ -217,30 +245,15 @@ const slice = createSlice({ state.undershot = false return } - if (state.shuffle) { - const nextShuffle = state.shuffleIndex + 1 - if (nextShuffle >= state.shuffleOrder.length) { - if (state.repeat === RepeatMode.ALL) { - state.shuffleIndex = 0 - } else { - state.overshot = true - return - } + if (state.index + 1 >= state.queue.length) { + if (state.repeat === RepeatMode.ALL) { + state.index = 0 } else { - state.shuffleIndex = nextShuffle + state.overshot = true + return } - state.index = state.shuffleOrder[state.shuffleIndex] } else { - if (state.index + 1 >= state.queue.length) { - if (state.repeat === RepeatMode.ALL) { - state.index = 0 - } else { - state.overshot = true - return - } - } else { - state.index = state.index + 1 - } + state.index = state.index + 1 } state.counter += 1 state.retries = 0 @@ -251,26 +264,11 @@ const slice = createSlice({ previous: (state) => { if (state.queue.length === 0) return - if (state.shuffle) { - const prevShuffle = state.shuffleIndex - 1 - if (prevShuffle < 0) { - if (state.repeat === RepeatMode.ALL) { - state.shuffleIndex = state.shuffleOrder.length - 1 - } else { - state.undershot = true - return - } - } else { - state.shuffleIndex = prevShuffle - } - state.index = state.shuffleOrder[state.shuffleIndex] - } else { - if (state.index - 1 < 0) { - state.undershot = true - return - } - state.index = state.index - 1 + if (state.index - 1 < 0) { + state.undershot = true + return } + state.index = state.index - 1 state.counter += 1 state.retries = 0 state.seek = null @@ -280,17 +278,30 @@ const slice = createSlice({ addToQueue: (state, action: PayloadAction) => { const { tracks, index } = action.payload - if (index === undefined) { - state.queue = [...state.queue, ...tracks] - return - } - const insertAt = Math.max(0, Math.min(index, state.queue.length)) + if (tracks.length === 0) return + const insertAt = + index === undefined + ? state.queue.length + : Math.max(0, Math.min(index, state.queue.length)) + const next = [...state.queue] next.splice(insertAt, 0, ...tracks) state.queue = next - if (state.index >= insertAt) { + if (insertAt <= state.index) { state.index += tracks.length } + + if (state.shuffle) { + // New tracks are appended to originalQueue (they have no "natural" + // position pre-shuffle). Their original indices then point at the + // newly-appended slots. + const baseOriginalIndex = state.shuffleOriginalQueue.length + state.shuffleOriginalQueue = [...state.shuffleOriginalQueue, ...tracks] + const newOriginalIndices = tracks.map((_, i) => baseOriginalIndex + i) + const nextOriginal = [...state.shuffleOriginalIndices] + nextOriginal.splice(insertAt, 0, ...newOriginalIndices) + state.shuffleOriginalIndices = nextOriginal + } }, playNext: (state, action: PayloadAction) => { @@ -298,11 +309,34 @@ const slice = createSlice({ const next = [...state.queue] next.splice(insertAt, 0, action.payload.track) state.queue = next + + if (state.shuffle) { + const baseOriginalIndex = state.shuffleOriginalQueue.length + state.shuffleOriginalQueue = [ + ...state.shuffleOriginalQueue, + action.payload.track + ] + const nextOriginal = [...state.shuffleOriginalIndices] + nextOriginal.splice(insertAt, 0, baseOriginalIndex) + state.shuffleOriginalIndices = nextOriginal + } }, removeFromQueue: (state, action: PayloadAction) => { const { index } = action.payload if (index < 0 || index >= state.queue.length) return + + if (state.shuffle && state.shuffleOriginalIndices.length > 0) { + const removedOriginalIdx = state.shuffleOriginalIndices[index] + state.shuffleOriginalIndices = removeFromOriginalIndices( + state.shuffleOriginalIndices, + index + ) + state.shuffleOriginalQueue = state.shuffleOriginalQueue.filter( + (_, i) => i !== removedOriginalIdx + ) + } + const next = [...state.queue] next.splice(index, 1) state.queue = next @@ -323,18 +357,38 @@ const slice = createSlice({ currentIndex >= 0 ? Math.max(0, orderedIndices.indexOf(currentIndex)) : -1 + + if (state.shuffle && state.shuffleOriginalIndices.length > 0) { + // The reorder rearranges visible positions; original-position + // mappings move with their tracks. shuffleOriginalQueue itself is + // untouched — its purpose is to remember the pre-shuffle order. + state.shuffleOriginalIndices = orderedIndices + .map((i) => state.shuffleOriginalIndices[i]) + .filter((v): v is number => v !== undefined) + } }, appendPage: (state, action: PayloadAction) => { + const { tracks } = action.payload + if (tracks.length === 0) return // Used by the saga when the backing tanquery fetches a next page. - state.queue = [...state.queue, ...action.payload.tracks] + state.queue = [...state.queue, ...tracks] + + if (state.shuffle) { + const baseOriginalIndex = state.shuffleOriginalQueue.length + state.shuffleOriginalQueue = [...state.shuffleOriginalQueue, ...tracks] + state.shuffleOriginalIndices = [ + ...state.shuffleOriginalIndices, + ...tracks.map((_, i) => baseOriginalIndex + i) + ] + } }, clearQueue: (state) => { state.queue = [] state.index = -1 - state.shuffleOrder = [] - state.shuffleIndex = -1 + state.shuffleOriginalQueue = [] + state.shuffleOriginalIndices = [] state.querySource = null }, @@ -345,12 +399,20 @@ const slice = createSlice({ if (state.index < 0 || state.index >= state.queue.length) { state.queue = [] state.index = -1 + state.shuffleOriginalQueue = [] + state.shuffleOriginalIndices = [] } else { - state.queue = [state.queue[state.index]] + const current = state.queue[state.index] + state.queue = [current] state.index = 0 + if (state.shuffle) { + state.shuffleOriginalQueue = [current] + state.shuffleOriginalIndices = [0] + } else { + state.shuffleOriginalQueue = [] + state.shuffleOriginalIndices = [] + } } - state.shuffleOrder = state.shuffle && state.queue.length > 0 ? [0] : [] - state.shuffleIndex = state.shuffle && state.queue.length > 0 ? 0 : -1 state.querySource = null }, @@ -369,16 +431,40 @@ const slice = createSlice({ setShuffle: (state, action: PayloadAction) => { const { enable } = action.payload + if (enable === state.shuffle) return state.shuffle = enable - if (enable && state.queue.length > 0) { - state.shuffleOrder = generateShuffleOrder( + + if (enable) { + if (state.queue.length === 0) { + state.shuffleOriginalQueue = [] + state.shuffleOriginalIndices = [] + return + } + const permutation = buildShufflePermutation( state.queue.length, state.index ) - state.shuffleIndex = 0 - } else if (!enable) { - state.shuffleOrder = [] - state.shuffleIndex = -1 + state.shuffleOriginalQueue = [...state.queue] + state.shuffleOriginalIndices = permutation + state.queue = applyPermutation(state.shuffleOriginalQueue, permutation) + // currentIndex was pinned to position 0 when valid. + state.index = + state.index >= 0 && state.index < state.shuffleOriginalQueue.length + ? 0 + : state.index + } else { + if (state.shuffleOriginalQueue.length === 0) { + state.shuffleOriginalIndices = [] + return + } + const currentOriginalIndex = + state.index >= 0 && state.index < state.shuffleOriginalIndices.length + ? state.shuffleOriginalIndices[state.index] + : -1 + state.queue = state.shuffleOriginalQueue + state.index = currentOriginalIndex + state.shuffleOriginalQueue = [] + state.shuffleOriginalIndices = [] } }, @@ -402,9 +488,8 @@ const slice = createSlice({ }, setIndex: (state, action: PayloadAction) => { - const { index, shuffleIndex } = action.payload + const { index } = action.payload if (typeof index === 'number') state.index = index - if (typeof shuffleIndex === 'number') state.shuffleIndex = shuffleIndex }, reset: (_state, _action: PayloadAction) => { diff --git a/packages/common/src/store/playback/types.ts b/packages/common/src/store/playback/types.ts index a22039db054..e782260f893 100644 --- a/packages/common/src/store/playback/types.ts +++ b/packages/common/src/store/playback/types.ts @@ -128,8 +128,14 @@ export type PlaybackState = { repeat: RepeatMode shuffle: boolean - shuffleOrder: number[] - shuffleIndex: number + // The pre-shuffle queue, captured when shuffle is enabled. Empty when + // shuffle is off. Mutations (add/remove/reorder) keep this in sync so + // disabling shuffle restores a coherent original order. + shuffleOriginalQueue: PlaybackTrack[] + // Parallel array to `queue` while shuffle is on: + // shuffleOriginalIndices[i] is the position of queue[i] in + // shuffleOriginalQueue. Empty when shuffle is off. + shuffleOriginalIndices: number[] querySource: PlaybackQuerySource | null diff --git a/packages/mobile/src/components/audio/AudioPlayer.tsx b/packages/mobile/src/components/audio/AudioPlayer.tsx index 7e1aa179cbd..1572b5f8287 100644 --- a/packages/mobile/src/components/audio/AudioPlayer.tsx +++ b/packages/mobile/src/components/audio/AudioPlayer.tsx @@ -86,8 +86,7 @@ const { getPlaybackQueue, getCurrentSource: getSource, getCollectionId, - getRepeat, - getShuffle + getRepeat } = playbackSelectors const { getIsReachable } = reachabilitySelectors const { getNftAccessSignatureMap } = gatedContentSelectors @@ -175,7 +174,6 @@ const useQueueSync = (isAudioSetup: boolean) => { const dispatch = useDispatch() const queueIndex = useSelector(getIndex) - const queueShuffle = useSelector(getShuffle) const queueOrder = useSelector(getPlaybackQueue) const queueSource = useSelector(getSource) const queueCollectionId = useSelector(getCollectionId) @@ -482,7 +480,6 @@ const useQueueSync = (isAudioSetup: boolean) => { return { queueIndex, - queueShuffle, queueTracks, queueIdxChangeJobRef, makeTrackData, @@ -497,14 +494,12 @@ const useQueueSync = (isAudioSetup: boolean) => { /** Handles all RNTP events: errors, remote controls, track changes. */ const usePlaybackEvents = ({ queueIndex, - queueShuffle, queueTracks, makeTrackData, retries, currentUserId }: { queueIndex: number - queueShuffle: boolean queueTracks: QueueableTrack[] makeTrackData: (t: QueueableTrack, retries?: number) => Promise retries: number @@ -645,49 +640,46 @@ const usePlaybackEvents = ({ const playerIndex = await TrackPlayer.getActiveTrackIndex() if (playerIndex === undefined) return - // RNTP auto-advanced to next track + // RNTP auto-advanced to next track. The redux queue is always in + // playable order (shuffled or not), so RNTP and redux indices align. if (playerIndex > queueIndex) { - if (queueShuffle) { + const { track: nextTrack, playerBehavior: nextBehavior } = + queueTracks[playerIndex] ?? {} + const { shouldSkip, shouldPreview } = calculatePlayerBehavior( + nextTrack, + nextBehavior + ) + + if (!nextTrack || shouldSkip) { dispatch(playbackActions.next()) } else { - const { track: nextTrack, playerBehavior: nextBehavior } = - queueTracks[playerIndex] ?? {} - const { shouldSkip, shouldPreview } = calculatePlayerBehavior( - nextTrack, - nextBehavior + dispatch(playbackActions.setIndex({ index: playerIndex })) + dispatch( + playbackActions.set({ + previewing: shouldPreview, + trackId: nextTrack.track_id, + index: playerIndex + }) ) - if (!nextTrack || shouldSkip) { - dispatch(playbackActions.next()) - } else { - dispatch(playbackActions.setIndex({ index: playerIndex })) + const trackPosition = trackPositions?.[nextTrack.track_id] + if (trackPosition?.status === 'IN_PROGRESS') { dispatch( - playbackActions.set({ - previewing: shouldPreview, + playbackActions.seekTo({ + seconds: trackPosition.playbackPosition + }) + ) + } else if (isLongFormContent(nextTrack)) { + dispatch( + setTrackPosition({ + userId: currentUserId, trackId: nextTrack.track_id, - index: playerIndex + positionInfo: { + status: 'IN_PROGRESS', + playbackPosition: 0 + } }) ) - - const trackPosition = trackPositions?.[nextTrack.track_id] - if (trackPosition?.status === 'IN_PROGRESS') { - dispatch( - playbackActions.seekTo({ - seconds: trackPosition.playbackPosition - }) - ) - } else if (isLongFormContent(nextTrack)) { - dispatch( - setTrackPosition({ - userId: currentUserId, - trackId: nextTrack.track_id, - positionInfo: { - status: 'IN_PROGRESS', - playbackPosition: 0 - } - }) - ) - } } } } @@ -850,7 +842,6 @@ export const AudioPlayer = () => { const { queueIndex, - queueShuffle, queueTracks, queueIdxChangeJobRef, makeTrackData, @@ -860,7 +851,6 @@ export const AudioPlayer = () => { const { setSeekPosition } = usePlaybackEvents({ queueIndex, - queueShuffle, queueTracks, makeTrackData, retries,