Skip to content

Commit

Permalink
feat: add loading state for sounds
Browse files Browse the repository at this point in the history
  • Loading branch information
remvze committed Nov 28, 2023
1 parent 85e42f3 commit aaccbee
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
18 changes: 18 additions & 0 deletions src/components/sound/sound.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}

Expand All @@ -89,3 +97,13 @@
line-height: 1.6;
}
}

@keyframes spinner {
0% {
transform: rotate(0deg);
}

100% {
transform: rotate(360deg);
}
}
11 changes: 10 additions & 1 deletion src/components/sound/sound.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useCallback, useEffect } from 'react';
import { ImSpinner9 } from 'react-icons/im/index';

import { Range } from './range';
import { Favorite } from './favorite';
Expand Down Expand Up @@ -78,7 +79,15 @@ export function Sound({
onKeyDown={toggle}
>
<Favorite id={id} />
<div className={styles.icon}>{icon}</div>
<div className={styles.icon}>
{sound.isLoading ? (
<span className={styles.spinner}>
<ImSpinner9 />
</span>
) : (
icon
)}
</div>
<h3 id={id}>{label}</h3>
<Range id={id} />
</div>
Expand Down
26 changes: 21 additions & 5 deletions src/hooks/use-sound.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<Howl | null>(() => {
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;
Expand All @@ -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();
Expand All @@ -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;
}

0 comments on commit aaccbee

Please sign in to comment.