diff --git a/src/components/sound/sound.tsx b/src/components/sound/sound.tsx index 5266820..d0b0846 100644 --- a/src/components/sound/sound.tsx +++ b/src/components/sound/sound.tsx @@ -1,4 +1,5 @@ -import { useState, useEffect } from 'react'; +import { useCallback, useEffect } from 'react'; +import { useLocalStorage } from '@/hooks/use-local-storage'; import { useSound } from '@/hooks/use-sound'; import { usePlay } from '@/contexts/play'; @@ -13,16 +14,15 @@ interface SoundProps { export function Sound({ label, src }: SoundProps) { const { isPlaying } = usePlay(); - const [isSelected, setIsSelected] = useState(false); - const [volume, setVolume] = useState(0.5); + const [isSelected, setIsSelected] = useLocalStorage( + `${label}-is-selected`, + false, + ); + const [volume, setVolume] = useLocalStorage(`${label}-volume`, 0.5); const sound = useSound(src, { loop: true, volume }); useEffect(() => { - if (!isSelected) { - setVolume(0.5); - } - if (isSelected && isPlaying) { sound?.play(); } else { @@ -30,11 +30,16 @@ export function Sound({ label, src }: SoundProps) { } }, [isSelected, sound, isPlaying]); + const toggle = useCallback(() => { + setIsSelected(prev => !prev); + setVolume(0.5); + }, [setIsSelected, setVolume]); + return (
setIsSelected(prev => !prev)} - onKeyDown={() => setIsSelected(prev => !prev)} + onClick={toggle} + onKeyDown={toggle} >

{label}

= Dispatch>; + +export function useLocalStorage(key: string, fallback: T): [T, SetValue] { + const [value, setValue] = useState(fallback); + + useEffect(() => { + const value = localStorage.getItem(key); + + if (!value) return; + + let parsed; + + try { + parsed = JSON.parse(value); + } catch (error) { + parsed = fallback; + } + + setValue(parsed); + }, [key, fallback]); + + useEffect(() => { + localStorage.setItem(key, JSON.stringify(value)); + }, [value, key]); + + return [value, setValue]; +}