formatting pass

This commit is contained in:
2026-09-02 18:23:22 +02:00
parent d7999785c8
commit 9c3fd4c1a2
7 changed files with 56 additions and 49 deletions
+2 -1
View File
@@ -9,7 +9,8 @@ const db = new Database(dbName);
export function getStreams(): StreamSummary[] {
const indexData = db
.prepare(
'SELECT id, stream_date, filename, title, tags, length_seconds ' + 'FROM Stream ORDER BY id DESC'
'SELECT id, stream_date, filename, title, tags, length_seconds ' +
'FROM Stream ORDER BY id DESC'
)
.all() as Record<string, unknown>[];
return indexData.map((stream) => ({
+34 -34
View File
@@ -2,46 +2,46 @@ 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[] = [];
streams: StreamSummary[];
current = $state<Stream | null>(null);
songIndex = $state<number | null>(null);
#timestamps: number[] = [];
constructor(streams: StreamSummary[]) {
this.streams = streams;
}
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;
}
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;
}
clearCurrent() {
this.current = null;
this.songIndex = null;
}
getSongAtTime(time: number): number {
return this.#locationOf(time, this.#timestamps) - 1;
}
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);
}
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);
}
#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>();
+6 -3
View File
@@ -13,10 +13,13 @@
<div class="description-bubble">
<p>Hello, there, welcome to V1.6.</p>
<p>
<u>2026-03-16 update:</u> you can now cache streams offline for playback in low-connectivity environments (and to prevent buffering)!<br>
Simply click on the download icon in the stream list (and click again to remove them from cache). You can also filter by cached streams at the top. This all goes into your browser storage, and a stream is generally 100~250MB depending on its length.
<u>2026-03-16 update:</u> you can now cache streams offline for playback in low-connectivity
environments (and to prevent buffering)!<br />
Simply click on the download icon in the stream list (and click again to remove them from cache).
You can also filter by cached streams at the top. This all goes into your browser storage, and
a stream is generally 100~250MB depending on its length.
</p>
<hr>
<hr />
<p>
Still in construction. The design is responsive now, so phones should work well enough!
Needs touch events though.
@@ -46,9 +46,7 @@ export function load({ params }) {
error(404);
}
result.descriptionHtml = Bun.markdown.html(
result.description || 'No description available.'
);
result.descriptionHtml = Bun.markdown.html(result.description || 'No description available.');
if (dev) {
// pass raw JSON for metadata editor
+8 -4
View File
@@ -230,7 +230,6 @@
}
});
});
</script>
<svelte:window
@@ -263,15 +262,20 @@
</button>
<progress
bind:this={songBar}
value={seeking && pendingSeekTime != null ? pendingSeekTime : (currentTime || 0)}
value={seeking && pendingSeekTime != null ? pendingSeekTime : currentTime || 0}
max={duration}
onmousedown={(e) => { seeking = true; updateSeekVisual(e); }}
onmousedown={(e) => {
seeking = true;
updateSeekVisual(e);
}}
onmouseenter={() => (showTooltip = true)}
onmouseleave={() => (showTooltip = false)}
style="--primary-color:{barPrimaryColor}; --secondary-color:{barSecondaryColor}"
class="song-progress"
></progress>
<div class="control-times">{formatSeconds(currentTime, duration >= 3600)}/{formatSeconds(duration)}</div>
<div class="control-times">
{formatSeconds(currentTime, duration >= 3600)}/{formatSeconds(duration)}
</div>
<button
style="--icon-color:{iconColor}"
class="material-icons"
@@ -5,9 +5,7 @@
const ctx = getStreamContext();
let formattedStreamDate = $derived(
ctx.current ? formatDate(ctx.current.stream_date) : ''
);
let formattedStreamDate = $derived(ctx.current ? formatDate(ctx.current.stream_date) : '');
</script>
<svelte:head>