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 } });
+ },
+}));