feat(app): banner, style tweaks

This commit is contained in:
rektdeckard
2023-03-03 22:39:42 -07:00
parent baeec27267
commit d379cea5bc
15 changed files with 215 additions and 40 deletions

View File

@@ -0,0 +1,40 @@
import { useCallback, useState, Dispatch, SetStateAction } from "react";
import { STORAGE_KEY } from "@/state";
type Initializer<S> = () => S;
type Setter<S> = (prev: S) => S;
type Action<S> = S | Setter<S> | Initializer<S>;
function expand<S extends object>(action: Action<S>, prev?: S) {
if (typeof action === "function") {
return (action as Setter<S>)(prev!);
} else {
return action;
}
}
export default function useLocalStorage<S extends object>(
key: string,
fallbackState: S | (() => S)
): [S, Dispatch<SetStateAction<S>>, (partial: Partial<S>) => void] {
const [value, setValue] = useState<S>(() => {
let val = localStorage.getItem(STORAGE_KEY + key);
if (val) return JSON.parse(val) as S;
return expand(fallbackState);
});
const set: Dispatch<SetStateAction<S>> = useCallback((val) => {
setValue((prev) => {
const next = expand(val, prev);
localStorage.setItem(STORAGE_KEY + key, JSON.stringify(next));
return next;
});
}, []);
const insert = useCallback(
(partial: Partial<S>) => set((value) => ({ ...value, ...partial })),
[]
);
return [value, set, insert];
}