48 lines
1.4 KiB
TypeScript
48 lines
1.4 KiB
TypeScript
import { createContext } from 'svelte';
|
|
import type { Stream, StreamSummary } from './types.ts';
|
|
|
|
export class StreamContext {
|
|
streams: StreamSummary[];
|
|
current = $state<Stream | null>(null);
|
|
songIndex = $state<number | null>(null);
|
|
#timestamps: number[] = [];
|
|
|
|
constructor(streams: StreamSummary[]) {
|
|
this.streams = streams;
|
|
}
|
|
|
|
setCurrent(stream: Stream) {
|
|
this.current = stream;
|
|
this.#timestamps = [-Infinity, ...stream.tracks.map((t) => t[0]), Infinity];
|
|
this.songIndex = 0;
|
|
}
|
|
|
|
clearCurrent() {
|
|
this.current = null;
|
|
this.songIndex = null;
|
|
}
|
|
|
|
getSongAtTime(time: number): number {
|
|
return this.#locationOf(time, this.#timestamps) - 1;
|
|
}
|
|
|
|
updateCurrentSong(currentTime: number, songIndex: number) {
|
|
const ts = this.#timestamps;
|
|
const recurse = (idx: number): number => {
|
|
if (currentTime >= ts[idx + 2]) return recurse(idx + 1);
|
|
if (currentTime < ts[idx + 1]) return recurse(idx - 1);
|
|
return idx;
|
|
};
|
|
this.songIndex = recurse(songIndex);
|
|
}
|
|
|
|
#locationOf(element: number, array: number[], start = 0, end = array.length): number {
|
|
const pivot = Math.floor(start + (end - start) / 2);
|
|
if (end - start <= 1 || array[pivot] === element) return pivot;
|
|
if (array[pivot] < element) return this.#locationOf(element, array, pivot, end);
|
|
return this.#locationOf(element, array, start, pivot);
|
|
}
|
|
}
|
|
|
|
export const [getStreamContext, setStreamContext] = createContext<StreamContext>();
|