fix(queue): batch queue splice invocations when reordering items to avoid currentIndex being dumped down due to clamping

This commit is contained in:
Kasper Seweryn 2023-05-06 14:33:47 +02:00 committed by jo
parent 1f44cb8e6f
commit a8b7e07a86
No known key found for this signature in database
GPG Key ID: B2FEC9B22722B984
1 changed files with 18 additions and 12 deletions

View File

@ -92,7 +92,7 @@ const queue = computed<QueueTrack[]>(() => {
}) })
// Current Index // Current Index
export const currentIndex = useClamp(useStorage('queue:index', 0), 0, () => tracks.value.length - 1) export const currentIndex = useClamp(useStorage('queue:index', 0), 0, () => Math.max(0, tracks.value.length - 1))
export const currentTrack = computed(() => queue.value[currentIndex.value]) export const currentTrack = computed(() => queue.value[currentIndex.value])
// Use Queue // Use Queue
@ -133,10 +133,10 @@ export const useQueue = createGlobalState(() => {
const isTrack = (track: Track | boolean): track is Track => typeof track !== 'boolean' const isTrack = (track: Track | boolean): track is Track => typeof track !== 'boolean'
// Adding tracks // Adding tracks
async function enqueueAt (index: number, ...newTracks: Track[]): Promise<void> async function enqueueAt(index: number, ...newTracks: Track[]): Promise<void>
// NOTE: Only last boolean of newTracks is considered as skipFetch // NOTE: Only last boolean of newTracks is considered as skipFetch
async function enqueueAt (index: number, ...newTracks: (Track | boolean)[]) : Promise<void> async function enqueueAt(index: number, ...newTracks: (Track | boolean)[]): Promise<void>
async function enqueueAt (index: number, ...newTracks: (Track | boolean)[]) : Promise<void> { async function enqueueAt(index: number, ...newTracks: (Track | boolean)[]): Promise<void> {
let skipFetch = false let skipFetch = false
if (!isTrack(newTracks[newTracks.length - 1])) { if (!isTrack(newTracks[newTracks.length - 1])) {
skipFetch = newTracks.pop() as boolean skipFetch = newTracks.pop() as boolean
@ -161,10 +161,10 @@ export const useQueue = createGlobalState(() => {
} }
} }
async function enqueue (...newTracks: Track[]): Promise<void> async function enqueue(...newTracks: Track[]): Promise<void>
// NOTE: Only last boolean of newTracks is considered as skipFetch // NOTE: Only last boolean of newTracks is considered as skipFetch
async function enqueue (...newTracks: (Track | boolean)[]): Promise<void> async function enqueue(...newTracks: (Track | boolean)[]): Promise<void>
async function enqueue (...newTracks: (Track | boolean)[]): Promise<void> { async function enqueue(...newTracks: (Track | boolean)[]): Promise<void> {
return enqueueAt(tracks.value.length, ...newTracks) return enqueueAt(tracks.value.length, ...newTracks)
} }
@ -253,10 +253,14 @@ export const useQueue = createGlobalState(() => {
? shuffledIds ? shuffledIds
: tracks : tracks
const [id] = list.value.splice(from, 1)
list.value.splice(to, 0, id)
const current = currentIndex.value const current = currentIndex.value
// NOTE: We're batching the changes to avoid reactivity issues related to the currentIndex being clamped at list length
const listCopy = list.value.slice()
const [id] = listCopy.splice(from, 1)
listCopy.splice(to, 0, id)
list.value = listCopy
if (current === from) { if (current === from) {
currentIndex.value = to currentIndex.value = to
return return
@ -327,6 +331,8 @@ export const useQueue = createGlobalState(() => {
const lastTracks = [...tracks.value] const lastTracks = [...tracks.value]
tracks.value.length = 0 tracks.value.length = 0
await delMany(lastTracks) await delMany(lastTracks)
currentIndex.value = 0
} }
// Radio queue populating // Radio queue populating
@ -365,7 +371,7 @@ export const useQueue = createGlobalState(() => {
const radios = JSON.parse(oldRadios) const radios = JSON.parse(oldRadios)
store.commit('radios/current', radios.radios.current) store.commit('radios/current', radios.radios.current)
store.commit('radios/running', radios.radios.running) store.commit('radios/running', radios.radios.running)
} catch (err) {} } catch (err) { }
currentIndex.value = index currentIndex.value = index
delete localStorage.queue delete localStorage.queue
@ -374,7 +380,7 @@ export const useQueue = createGlobalState(() => {
if (localStorage.player) { if (localStorage.player) {
try { try {
const { player: { looping: loopingMode, volume } } = JSON.parse(localStorage.player) as { player: { looping: LoopingMode, volume: number }} const { player: { looping: loopingMode, volume } } = JSON.parse(localStorage.player) as { player: { looping: LoopingMode, volume: number } }
looping.value = loopingMode ?? 0 looping.value = loopingMode ?? 0
setGain(volume ?? 0.7) setGain(volume ?? 0.7)
delete localStorage.player delete localStorage.player