diff --git a/src/components/sound/sound.tsx b/src/components/sound/sound.tsx index 92d441b..c6fc1eb 100644 --- a/src/components/sound/sound.tsx +++ b/src/components/sound/sound.tsx @@ -5,7 +5,7 @@ import { Range } from './range'; import { Favorite } from './favorite'; import { useSound } from '@/hooks/use-sound'; -import { useSoundStore } from '@/store'; +import { useSoundStore, useLoadingStore } from '@/store'; import { cn } from '@/helpers/styles'; import styles from './sound.module.css'; @@ -37,6 +37,8 @@ export function Sound({ const volume = useSoundStore(state => state.sounds[id].volume); const isSelected = useSoundStore(state => state.sounds[id].isSelected); + const isLoading = useLoadingStore(state => state.loaders[src]); + const sound = useSound(src, { loop: true, volume }); useEffect(() => { @@ -80,7 +82,7 @@ export function Sound({ >
- {sound.isLoading ? ( + {isLoading ? ( diff --git a/src/hooks/use-sound.ts b/src/hooks/use-sound.ts index c6fbde9..eb1e501 100644 --- a/src/hooks/use-sound.ts +++ b/src/hooks/use-sound.ts @@ -1,6 +1,7 @@ import { useMemo, useEffect, useCallback, useState } from 'react'; import { Howl } from 'howler'; +import { useLoadingStore } from '@/store'; import { useSSR } from './use-ssr'; export function useSound( @@ -8,7 +9,9 @@ export function useSound( options: { loop?: boolean; volume?: number } = {}, ) { const [hasLoaded, setHasLoaded] = useState(false); - const [isLoading, setIsLoading] = useState(false); + const isLoading = useLoadingStore(state => state.loaders[src]); + const setIsLoading = useLoadingStore(state => state.set); + const { isBrowser } = useSSR(); const sound = useMemo(() => { let sound: Howl | null = null; @@ -16,7 +19,7 @@ export function useSound( if (isBrowser) { sound = new Howl({ onload: () => { - setIsLoading(false); + setIsLoading(src, false); setHasLoaded(true); }, preload: false, @@ -25,7 +28,7 @@ export function useSound( } return sound; - }, [src, isBrowser]); + }, [src, isBrowser, setIsLoading]); useEffect(() => { if (sound) { @@ -41,7 +44,7 @@ export function useSound( const play = useCallback(() => { if (sound) { if (!hasLoaded && !isLoading) { - setIsLoading(true); + setIsLoading(src, true); sound.load(); } @@ -49,7 +52,7 @@ export function useSound( sound.play(); } } - }, [sound, hasLoaded, isLoading]); + }, [src, setIsLoading, sound, hasLoaded, isLoading]); const stop = useCallback(() => { if (sound) sound.stop(); diff --git a/src/store/index.ts b/src/store/index.ts index faff52a..dc1e1bb 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1 +1,2 @@ export { useSoundStore } from './sound'; +export { useLoadingStore } from './loading'; diff --git a/src/store/loading/index.ts b/src/store/loading/index.ts new file mode 100644 index 0000000..5a6e87d --- /dev/null +++ b/src/store/loading/index.ts @@ -0,0 +1,13 @@ +import { create } from 'zustand'; + +interface LoadingStore { + loaders: Record; + set: (id: string, value: boolean) => void; +} + +export const useLoadingStore = create()((set, get) => ({ + loaders: {}, + set(id: string, value: boolean) { + set({ loaders: { ...get().loaders, [id]: value } }); + }, +}));