simplify useStoredTheme

This commit is contained in:
Vinzenz Schroeter 2024-04-14 15:16:32 +02:00
parent 16d3cd1545
commit 35256ba88d
3 changed files with 37 additions and 24 deletions

View file

@ -34,7 +34,7 @@ export default function App() {
return <Column className='flex-grow'> return <Column className='flex-grow'>
<Row> <Row>
<h1 className='flex-grow'>CCCB-Tanks!</h1> <h1 className='flex-grow'>CCCB-Tanks!</h1>
<Button text='change colors' onClick={() => setTheme(getRandomTheme())} /> <Button text='change colors' onClick={() => setTheme(_ => getRandomTheme())}/>
<Button <Button
onClick={() => window.open('https://github.com/kaesaecracker/cccb-tanks-cs', '_blank')?.focus()} onClick={() => window.open('https://github.com/kaesaecracker/cccb-tanks-cs', '_blank')?.focus()}
text='GitHub'/> text='GitHub'/>

View file

@ -50,10 +50,9 @@ function angle(a: number) {
return ((a % 360.0) + 360) % 360; return ((a % 360.0) + 360) % 360;
} }
const goldenAngle = 180 * (3 - Math.sqrt(5));
export function getRandomTheme(): Theme { export function getRandomTheme(): Theme {
const goldenAngle = 180 * (3 - Math.sqrt(5));
const background = getRandomHsl({maxSaturation: 50, minLightness: 10, maxLightness: 40}); const background = getRandomHsl({maxSaturation: 50, minLightness: 10, maxLightness: 40});
const primary = getRandomHsl({minSaturation: background.s * 1.2, minLightness: background.l + 20}); const primary = getRandomHsl({minSaturation: background.s * 1.2, minLightness: background.l + 20});
@ -65,16 +64,16 @@ export function getRandomTheme(): Theme {
return {background, primary, secondary}; return {background, primary, secondary};
} }
export function useStoredTheme(): [Theme, (theme: Theme) => void] { function applyTheme(theme: Theme) {
const [theme, setSavedTheme] = useStoredObjectState<Theme>('theme', getRandomTheme); console.log('apply theme', theme);
function setTheme(theme: Theme) {
console.log('set theme', theme);
rootStyle.setProperty('--color-primary', hslToString(theme.primary)); rootStyle.setProperty('--color-primary', hslToString(theme.primary));
rootStyle.setProperty('--color-secondary', hslToString(theme.secondary)); rootStyle.setProperty('--color-secondary', hslToString(theme.secondary));
rootStyle.setProperty('--color-background', hslToString(theme.background)); rootStyle.setProperty('--color-background', hslToString(theme.background));
setSavedTheme(_ => theme); }
}
export function useStoredTheme() {
return [theme, setTheme]; return useStoredObjectState<Theme>('theme', getRandomTheme, {
load: applyTheme,
save: applyTheme
});
} }

View file

@ -13,23 +13,37 @@ export function useStoredState(storageKey: string, initialState: () => string):
export function useStoredObjectState<T>( export function useStoredObjectState<T>(
storageKey: string, storageKey: string,
initialState: () => T initialState: () => T,
options?: {
load?: (value: T) => void;
save?: (value: T) => void;
}
): [T, (mutator: (oldState: T) => T) => void] { ): [T, (mutator: (oldState: T) => T) => void] {
const getInitialState = () => { const getInitialState = () => {
const localStorageJson = localStorage.getItem(storageKey); const localStorageJson = localStorage.getItem(storageKey);
if (localStorageJson !== null && localStorageJson !== '') {
return JSON.parse(localStorageJson) as T;
}
return initialState(); let result = (localStorageJson !== null && localStorageJson !== '')
? JSON.parse(localStorageJson) as T
: initialState();
if (options?.load)
options.load(result);
return result;
}; };
const [state, setState] = useState<T>(getInitialState); const [state, setState] = useState<T>(getInitialState);
const setSavedState = (mut: (oldState: T) => T) => { const setSavedState = (mut: (oldState: T) => T) => {
const newState = mut(state); setState(prevState => {
const newState = mut(prevState);
if (options?.save)
options.save(newState);
localStorage.setItem(storageKey, JSON.stringify(newState)); localStorage.setItem(storageKey, JSON.stringify(newState));
setState(newState); return newState;
});
}; };
return [state, setSavedState]; return [state, setSavedState];