guard around potential crashes
This commit is contained in:
+2
-2
@@ -18,7 +18,7 @@ export function getStreams(): StreamSummary[] {
|
||||
stream_date: Date.parse(stream.stream_date as string),
|
||||
filename: stream.filename as string,
|
||||
title: stream.title as string | null,
|
||||
tags: JSON.parse(stream.tags as string) as string[],
|
||||
tags: (JSON.parse(stream.tags as string) as string[]) ?? [],
|
||||
length_seconds: stream.length_seconds as number
|
||||
}));
|
||||
}
|
||||
@@ -40,7 +40,7 @@ export function getStreamInfo(streamId: string): Stream | null {
|
||||
format: streamData.format as string,
|
||||
title: streamData.title as string | null,
|
||||
description: streamData.description as string | null,
|
||||
tags: JSON.parse(streamData.tags as string) as string[],
|
||||
tags: (JSON.parse(streamData.tags as string) as string[]) ?? [],
|
||||
length_seconds: streamData.length_seconds as number,
|
||||
tracks: JSON.parse(streamData.tracks as string)
|
||||
};
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { browser } from '$app/environment';
|
||||
import { SvelteSet } from 'svelte/reactivity';
|
||||
import { readStored, writeStored } from './utils.ts';
|
||||
|
||||
export const favoritedStreams = new SvelteSet<string>(
|
||||
JSON.parse((browser && localStorage.getItem('favoritedStreams')) || '[]')
|
||||
);
|
||||
export const favoritedStreams = new SvelteSet<string>(readStored('favoritedStreams', []));
|
||||
$effect.root(() => {
|
||||
$effect(() => {
|
||||
localStorage.setItem('favoritedStreams', JSON.stringify(Array.from(favoritedStreams)));
|
||||
writeStored('favoritedStreams', Array.from(favoritedStreams));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { browser } from '$app/environment';
|
||||
import { SvelteSet, SvelteMap } from 'svelte/reactivity';
|
||||
import { readStored, writeStored } from './utils.ts';
|
||||
import type { StreamSummary, PartialDownload } from './types.ts';
|
||||
|
||||
const STORAGE_KEY = 'cachedStreams';
|
||||
@@ -16,23 +17,21 @@ const CHUNK_SIZE = 8 * 1024 * 1024;
|
||||
// as the intent is to catch socket breakage during cellular network changes for example
|
||||
const CHUNK_TIMEOUT = 60_000;
|
||||
|
||||
export const cached = new SvelteSet<string>(
|
||||
browser ? JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]') : []
|
||||
);
|
||||
export const cached = new SvelteSet<string>(readStored<string[]>(STORAGE_KEY, []));
|
||||
export const downloading = new SvelteMap<string, number>();
|
||||
|
||||
// bytes already written to OPFS for each incomplete download
|
||||
export const partials = new SvelteMap<string, PartialDownload>(
|
||||
browser ? Object.entries(JSON.parse(localStorage.getItem(PARTIALS_KEY) || '{}')) : []
|
||||
Object.entries(readStored<Record<string, PartialDownload>>(PARTIALS_KEY, {}))
|
||||
);
|
||||
|
||||
if (browser) {
|
||||
$effect.root(() => {
|
||||
$effect(() => {
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify([...cached]));
|
||||
writeStored(STORAGE_KEY, [...cached]);
|
||||
});
|
||||
$effect(() => {
|
||||
localStorage.setItem(PARTIALS_KEY, JSON.stringify(Object.fromEntries(partials)));
|
||||
writeStored(PARTIALS_KEY, Object.fromEntries(partials));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,26 @@
|
||||
import { browser } from '$app/environment';
|
||||
import Sqids from 'sqids';
|
||||
|
||||
const sqids = new Sqids({ minLength: 6, alphabet: 'abcdefghijklmnopqrstuvwxyz0123456789' });
|
||||
|
||||
// browser blocks site data => localStorage throws
|
||||
// so we're wrapping our calls to ensure things running at module init
|
||||
// don't bring down the site render entirely
|
||||
export function readStored<T>(key: string, fallback: T): T {
|
||||
if (!browser) return fallback;
|
||||
try {
|
||||
return (JSON.parse(localStorage.getItem(key) ?? '') as T) ?? fallback;
|
||||
} catch {
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
export function writeStored(key: string, value: unknown) {
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
} catch {}
|
||||
}
|
||||
|
||||
export function hashcode(str: string): number {
|
||||
let h = 9;
|
||||
for (let i = 0; i < str.length; ) h = Math.imul(h ^ str.charCodeAt(i++), 9 ** 9);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import { onMount, untrack } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { getStreamContext } from '$lib/streamContext.svelte.ts';
|
||||
import { readStored, writeStored } from '$lib/utils.ts';
|
||||
import type { Track } from '$lib/types';
|
||||
|
||||
const ctx = getStreamContext();
|
||||
@@ -87,8 +88,7 @@
|
||||
isSafari = isIOS || isDesktopSafari;
|
||||
|
||||
// default volume
|
||||
const volumeData = localStorage.getItem('volume');
|
||||
volume = volumeData ? parseFloat(volumeData) : 0.67;
|
||||
volume = readStored('volume', 0.67);
|
||||
setVolume(volume);
|
||||
|
||||
// set actions for previous/next track media buttons
|
||||
@@ -181,7 +181,7 @@
|
||||
if (!volumeBar) return;
|
||||
volume = seek(event, volumeBar.getBoundingClientRect());
|
||||
setVolume(volume);
|
||||
localStorage.setItem('volume', volume.toString());
|
||||
writeStored('volume', volume);
|
||||
muted = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user