diff --git a/src/components/sound/sound.module.css b/src/components/sound/sound.module.css
index 3d0e2db..5073802 100644
--- a/src/components/sound/sound.module.css
+++ b/src/components/sound/sound.module.css
@@ -77,6 +77,14 @@
& .icon {
color: #34d399;
+
+ & .spinner {
+ animation-duration: 1s;
+ animation-iteration-count: infinite;
+ animation-name: spinner;
+ animation-timing-function: linear;
+ line-height: 0;
+ }
}
}
@@ -89,3 +97,13 @@
line-height: 1.6;
}
}
+
+@keyframes spinner {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(360deg);
+ }
+}
diff --git a/src/components/sound/sound.tsx b/src/components/sound/sound.tsx
index 93742bc..92d441b 100644
--- a/src/components/sound/sound.tsx
+++ b/src/components/sound/sound.tsx
@@ -1,4 +1,5 @@
import { useCallback, useEffect } from 'react';
+import { ImSpinner9 } from 'react-icons/im/index';
import { Range } from './range';
import { Favorite } from './favorite';
@@ -78,7 +79,15 @@ export function Sound({
onKeyDown={toggle}
>
-
{icon}
+
+ {sound.isLoading ? (
+
+
+
+ ) : (
+ icon
+ )}
+
{label}
diff --git a/src/hooks/use-sound.ts b/src/hooks/use-sound.ts
index dae8f39..3221853 100644
--- a/src/hooks/use-sound.ts
+++ b/src/hooks/use-sound.ts
@@ -1,4 +1,4 @@
-import { useMemo, useEffect, useCallback } from 'react';
+import { useMemo, useEffect, useCallback, useState } from 'react';
import { Howl } from 'howler';
import { useSSR } from './use-ssr';
@@ -7,12 +7,21 @@ export function useSound(
src: string,
options: { loop?: boolean; volume?: number } = {},
) {
+ const [hasLoaded, setHasLoaded] = useState(false);
+ const [isLoading, setIsLoading] = useState(false);
const { isBrowser } = useSSR();
const sound = useMemo(() => {
let sound: Howl | null = null;
if (isBrowser) {
- sound = new Howl({ preload: false, src: src });
+ sound = new Howl({
+ onload: () => {
+ setIsLoading(false);
+ setHasLoaded(true);
+ },
+ preload: false,
+ src: src,
+ });
}
return sound;
@@ -31,10 +40,14 @@ export function useSound(
const play = useCallback(() => {
if (sound) {
- sound.load();
+ if (!hasLoaded) {
+ setIsLoading(true);
+ sound.load();
+ }
+
sound.play();
}
- }, [sound]);
+ }, [sound, hasLoaded]);
const stop = useCallback(() => {
if (sound) sound.stop();
@@ -44,7 +57,10 @@ export function useSound(
if (sound) sound.pause();
}, [sound]);
- const control = useMemo(() => ({ pause, play, stop }), [play, stop, pause]);
+ const control = useMemo(
+ () => ({ isLoading, pause, play, stop }),
+ [play, stop, pause, isLoading],
+ );
return control;
}