From 4d75dfe8d1cb74919130eda88f17133db4cd34fe Mon Sep 17 00:00:00 2001 From: intergrav Date: Fri, 24 Jul 2026 07:02:41 -0400 Subject: [PATCH] refactor: queue optimizations (llm-assisted) --- src/lib/Queue.svelte | 34 +++++++++++++++------------ src/lib/queue.svelte.ts | 51 +++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/lib/Queue.svelte b/src/lib/Queue.svelte index 75f8cba..d5a5932 100644 --- a/src/lib/Queue.svelte +++ b/src/lib/Queue.svelte @@ -191,12 +191,14 @@ const queueColumns = $derived.by((): QueueColumn[] => [ function measuredColumnTrack(column: QueueColumn) { let width = measureText(column.header); - for (let index = 0; index < queue.tracks.length; index++) { - width = Math.max( - width, - measureText(column.value(queue.tracks[index], index)), - ); - } + untrack(() => { + for (let index = 0; index < queue.tracks.length; index++) { + width = Math.max( + width, + measureText(column.value(queue.tracks[index], index)), + ); + } + }); return `minmax(0, ${width}px)`; } @@ -210,6 +212,8 @@ const visibleColumns = $derived([...textColumns, ...numericColumns]); const showDownloads = $derived(settings.downloads && settings.enableDownloads); const columnTemplate = $derived.by(() => { + queue.contentVersion; + queueFont; const template = settings.artSong > 0 ? [`${settings.artSong}px`] : []; template.push(`repeat(${Math.max(1, textColumns.length)}, minmax(0, 1fr))`); template.push(...numericColumns.map(measuredColumnTrack)); @@ -291,19 +295,19 @@ function animateEntries(keys: number[]) { function animateMoves(moves: QueueMove[], selected = new Set()) { if (!animationsEnabled()) return; - const netMoves = new Map(); - for (const move of moves) { - const previous = netMoves.get(move.key); - if (previous) { - previous.to = move.to; - previous.fullDistance ||= move.fullDistance; - } else netMoves.set(move.key, { ...move }); - } - void tick().then(() => requestAnimationFrame(() => { if (!animationsEnabled()) return; const rows = getMountedRows(); + const netMoves = new Map(); + for (const move of moves) { + if (!rows.has(move.key)) continue; + const previous = netMoves.get(move.key); + if (previous) { + previous.to = move.to; + previous.fullDistance ||= move.fullDistance; + } else netMoves.set(move.key, { ...move }); + } for (const { key, from, to, fullDistance } of netMoves.values()) { if (from === to) continue; const row = rows.get(key); diff --git a/src/lib/queue.svelte.ts b/src/lib/queue.svelte.ts index a8a25f8..0329dd3 100644 --- a/src/lib/queue.svelte.ts +++ b/src/lib/queue.svelte.ts @@ -31,6 +31,7 @@ export const queue = $state({ scrollRequest: null as { index: number; smooth: boolean } | null, moveRequest: null as QueueMove[] | null, entryRequest: null as number[] | null, + contentVersion: 0, }); const selectedIndices = $derived(new Set(queue.sel)); @@ -102,6 +103,7 @@ export const insertAt = ( })); queue.tracks.splice(index, 0, ...items); queue.keys.splice(index, 0, ...entryKeys); + queue.contentVersion++; requestMoves(moves); requestEntries(entryKeys); if (queue.pos >= index) queue.pos += items.length; @@ -155,6 +157,8 @@ const restoreHistory = (state: HistoryState, previous: HistoryState) => { }), ); requestEntries(entries); + if (entries.length || state.keys.length !== previous.keys.length) + queue.contentVersion++; queue.pos = state.pos; clearSel(); }; @@ -222,6 +226,31 @@ export const reorder = (direction: -1 | 1, steps = 1): QueueMove[] => { : queue.tracks.length - 1 - selected[selected.length - 1]; const stepCount = Math.min(Math.ceil(steps), distance); if (!stepCount) return []; + + if (stepCount === 1) { + const moves: QueueMove[] = []; + if (direction === 1) selected.reverse(); + for (const from of selected) { + const to = from + direction; + const movedKey = queue.keys[from]; + const displacedKey = queue.keys[to]; + [queue.tracks[from], queue.tracks[to]] = [ + queue.tracks[to], + queue.tracks[from], + ]; + [queue.keys[from], queue.keys[to]] = [displacedKey, movedKey]; + moves.push( + { key: movedKey, from, to }, + { key: displacedKey, from: to, to: from }, + ); + if (queue.pos === from) queue.pos = to; + else if (queue.pos === to) queue.pos = from; + } + if (selectedIndices.has(nav.anchor)) nav.anchor += direction; + if (selectedIndices.has(nav.head)) nav.head += direction; + queue.sel = queue.sel.map((index) => index + direction); + return moves; + } const shift = direction * stepCount; const length = queue.tracks.length; @@ -247,23 +276,12 @@ export const reorder = (direction: -1 | 1, steps = 1): QueueMove[] => { keys[to] = queue.keys[from]; } - const moveNavigationIndex = (index: number) => { - for (let step = 0; step < stepCount; step++) { - if (selectedIndices.has(index - direction * step)) index += direction; - } - return index; - }; - const selection = queue.sel.map((index) => oldToNew[index]); - const pos = queue.pos === -1 ? -1 : oldToNew[queue.pos]; - const anchor = nav.anchor === -1 ? -1 : moveNavigationIndex(nav.anchor); - const head = nav.head === -1 ? -1 : moveNavigationIndex(nav.head); - queue.tracks = tracks; queue.keys = keys; - queue.sel = selection; - queue.pos = pos; - nav.anchor = anchor; - nav.head = head; + if (queue.pos !== -1) queue.pos = oldToNew[queue.pos]; + if (selectedIndices.has(nav.anchor)) nav.anchor += shift; + if (selectedIndices.has(nav.head)) nav.head += shift; + queue.sel = queue.sel.map((index) => oldToNew[index]); return getMoves(positions, keys); }; @@ -284,6 +302,7 @@ export const remove = () => { .filter((index) => !selectedIndices.has(index)); queue.tracks = queue.tracks.filter((_, index) => !selectedIndices.has(index)); queue.keys = queue.keys.filter((_, index) => !selectedIndices.has(index)); + queue.contentVersion++; requestMoves(getMoves(positions, queue.keys)); if (playing) { @@ -526,6 +545,7 @@ export const clear = () => { if (queue.sel.length) return remove(); queue.tracks = []; queue.keys = []; + queue.contentVersion++; stop(); clearSel(); }; @@ -659,6 +679,7 @@ export const syncQueue = async () => { ); queue.tracks = entries; queue.keys = entries.map(() => nextTrackKey++); + queue.contentVersion++; requestEntries(queue.keys); if (saved.current != null) { let idx = queue.tracks.findIndex((t) => t.id === saved.current); -- 2.54.0