40 lines
1.4 KiB
TypeScript
40 lines
1.4 KiB
TypeScript
import { derived, writable } from 'svelte/store';
|
|
import { createTimeFormatter, DEFAULT_TIME_ZONE, validTimeZone } from '$lib/time-zone.js';
|
|
|
|
export const TIME_ZONE_STORAGE_KEY = 'electric-cherry:time-zone';
|
|
export const timeZone = writable(DEFAULT_TIME_ZONE);
|
|
export const timeFormat = derived(timeZone, createTimeFormatter);
|
|
export const timeZonePersistenceError = writable(false);
|
|
|
|
/** Called only on mount so server rendering never shares a user's preference. */
|
|
export function startTimeZonePreference(): () => void {
|
|
let saved: string | null = null;
|
|
try {
|
|
saved = localStorage.getItem(TIME_ZONE_STORAGE_KEY);
|
|
} catch {
|
|
/* Use the default. */
|
|
}
|
|
timeZone.set(validTimeZone(saved) ? saved : DEFAULT_TIME_ZONE);
|
|
const unsubscribe = timeZone.subscribe((value) => {
|
|
try {
|
|
localStorage.setItem(TIME_ZONE_STORAGE_KEY, value);
|
|
timeZonePersistenceError.set(false);
|
|
} catch {
|
|
timeZonePersistenceError.set(true);
|
|
}
|
|
});
|
|
function onStorage(event: StorageEvent) {
|
|
if (
|
|
event.storageArea !== localStorage ||
|
|
(event.key !== TIME_ZONE_STORAGE_KEY && event.key !== null)
|
|
)
|
|
return;
|
|
timeZone.set(validTimeZone(event.newValue) ? event.newValue : DEFAULT_TIME_ZONE);
|
|
}
|
|
window.addEventListener('storage', onStorage);
|
|
return () => {
|
|
unsubscribe();
|
|
window.removeEventListener('storage', onStorage);
|
|
};
|
|
}
|