modify id to index map imperatively
This commit is contained in:
@@ -29,14 +29,17 @@ class PlayerStore {
|
||||
// Debounce timer for save()
|
||||
private _saveTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
// O(1) index: track.id → index in queue
|
||||
private idToIndex = $derived.by(() => {
|
||||
// O(1) index: track.id → index in queue (maintained imperatively)
|
||||
private idToIndex = $state(new Map<number, number>());
|
||||
|
||||
/** Rebuild the full index from the queue array. */
|
||||
private rebuildIndex() {
|
||||
const map = new Map<number, number>();
|
||||
for (let i = 0; i < this.queue.length; i++) {
|
||||
map.set(this.queue[i].id, i);
|
||||
}
|
||||
return map;
|
||||
});
|
||||
this.idToIndex = map;
|
||||
}
|
||||
|
||||
// Derived
|
||||
currentTrack = $derived.by(() => {
|
||||
@@ -52,9 +55,7 @@ class PlayerStore {
|
||||
|
||||
displayQueue = $derived(
|
||||
this.isShuffled
|
||||
? this.shuffledIndices
|
||||
.map((i) => this.queue[i])
|
||||
.filter((t) => t !== undefined)
|
||||
? this.shuffledIndices.map((i) => this.queue[i])
|
||||
: this.queue,
|
||||
);
|
||||
|
||||
@@ -80,6 +81,7 @@ class PlayerStore {
|
||||
if (state.volume !== undefined) this.volume = state.volume;
|
||||
if (state.isMuted !== undefined) this.isMuted = state.isMuted;
|
||||
if (state.minimized !== undefined) this.uiOpen = !state.minimized;
|
||||
this.rebuildIndex();
|
||||
}
|
||||
|
||||
load() {
|
||||
@@ -95,6 +97,7 @@ class PlayerStore {
|
||||
this.repeatMode = data.repeatMode || "off";
|
||||
this.volume = data.volume ?? 1;
|
||||
this.isMuted = data.isMuted || false;
|
||||
this.rebuildIndex();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to load player state", e);
|
||||
@@ -139,6 +142,7 @@ class PlayerStore {
|
||||
} else {
|
||||
// Add to end
|
||||
this.queue.push(track);
|
||||
this.idToIndex.set(track.id, this.queue.length - 1);
|
||||
|
||||
if (this.isShuffled) {
|
||||
this.shuffledIndices.push(this.queue.length - 1);
|
||||
@@ -166,6 +170,8 @@ class PlayerStore {
|
||||
const insertIdx = currentIdx === -1 ? 0 : currentIdx + 1;
|
||||
|
||||
this.queue.splice(insertIdx, 0, targetTrack);
|
||||
// Rebuild index — splice shifts everything after insertIdx
|
||||
this.rebuildIndex();
|
||||
|
||||
if (this.isShuffled) {
|
||||
// Shift indices that are >= insertIdx because we inserted a new item
|
||||
@@ -199,6 +205,10 @@ class PlayerStore {
|
||||
|
||||
const startIdx = this.queue.length;
|
||||
this.queue.push(...newTracks);
|
||||
// Only index the newly added tracks
|
||||
for (let i = 0; i < newTracks.length; i++) {
|
||||
this.idToIndex.set(newTracks[i].id, startIdx + i);
|
||||
}
|
||||
|
||||
if (this.isShuffled) {
|
||||
const newIndices = newTracks.map((_, i) => startIdx + i);
|
||||
@@ -224,6 +234,8 @@ class PlayerStore {
|
||||
const wasCurrent = this.currentId === id;
|
||||
|
||||
this.queue.splice(idx, 1);
|
||||
// Rebuild index — splice shifts everything after idx
|
||||
this.rebuildIndex();
|
||||
|
||||
if (wasCurrent) {
|
||||
this.currentId = null; // Or auto-advance?
|
||||
@@ -240,6 +252,7 @@ class PlayerStore {
|
||||
|
||||
clearQueue() {
|
||||
this.queue = [];
|
||||
this.idToIndex = new Map();
|
||||
this.currentId = null;
|
||||
this.shuffledIndices = [];
|
||||
this.history = [];
|
||||
@@ -271,6 +284,7 @@ class PlayerStore {
|
||||
const [item] = q.splice(fromIdx, 1);
|
||||
q.splice(toIdx, 0, item);
|
||||
this.queue = q;
|
||||
this.rebuildIndex();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user