better UI

This commit is contained in:
Joeri Exelmans 2025-10-20 16:29:48 +02:00
parent 44fb8726ca
commit 1f9379df7f
16 changed files with 440 additions and 248 deletions

View file

@ -0,0 +1,38 @@
import { Dispatch, SetStateAction, useState } from "react";
// like useState, but it is persisted in localStorage
// important: values must be JSON-(de-)serializable
export function usePersistentState<T>(key: string, initial: T): [T, Dispatch<SetStateAction<T>>] {
const [state, setState] = useState(() => {
const recovered = localStorage.getItem(key);
let parsed;
if (recovered !== null) {
try {
parsed = JSON.parse(recovered);
return parsed;
} catch (e) {
// console.warn(`failed to recover state for option '${key}'`, e,
// '(this is normal when running the app for the first time)');
}
}
return initial;
});
function setStateWrapped(val: SetStateAction<T>) {
setState((oldState: T) => {
let newVal;
if (typeof val === 'function') {
// @ts-ignore: i don't understand why 'val' might not be callable
newVal = val(oldState);
}
else {
newVal = val;
}
const serialized = JSON.stringify(newVal);
localStorage.setItem(key, serialized);
return newVal;
});
}
return [state, setStateWrapped];
}