Skip to content

Commit

Permalink
feat: add loader for favorites
Browse files Browse the repository at this point in the history
  • Loading branch information
remvze committed Jan 9, 2024
1 parent a33ae45 commit f682a91
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 7 deletions.
6 changes: 4 additions & 2 deletions src/components/sound/sound.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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(() => {
Expand Down Expand Up @@ -80,7 +82,7 @@ export function Sound({
>
<Favorite id={id} />
<div className={styles.icon}>
{sound.isLoading ? (
{isLoading ? (
<span className={styles.spinner}>
<ImSpinner9 />
</span>
Expand Down
13 changes: 8 additions & 5 deletions src/hooks/use-sound.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import { useMemo, useEffect, useCallback, useState } from 'react';
import { Howl } from 'howler';

import { useLoadingStore } from '@/store';
import { useSSR } from './use-ssr';

export function useSound(
src: string,
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<Howl | null>(() => {
let sound: Howl | null = null;

if (isBrowser) {
sound = new Howl({
onload: () => {
setIsLoading(false);
setIsLoading(src, false);
setHasLoaded(true);
},
preload: false,
Expand All @@ -25,7 +28,7 @@ export function useSound(
}

return sound;
}, [src, isBrowser]);
}, [src, isBrowser, setIsLoading]);

useEffect(() => {
if (sound) {
Expand All @@ -41,15 +44,15 @@ export function useSound(
const play = useCallback(() => {
if (sound) {
if (!hasLoaded && !isLoading) {
setIsLoading(true);
setIsLoading(src, true);
sound.load();
}

if (!sound.playing()) {
sound.play();
}
}
}, [sound, hasLoaded, isLoading]);
}, [src, setIsLoading, sound, hasLoaded, isLoading]);

const stop = useCallback(() => {
if (sound) sound.stop();
Expand Down
1 change: 1 addition & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { useSoundStore } from './sound';
export { useLoadingStore } from './loading';
13 changes: 13 additions & 0 deletions src/store/loading/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { create } from 'zustand';

interface LoadingStore {
loaders: Record<string, boolean>;
set: (id: string, value: boolean) => void;
}

export const useLoadingStore = create<LoadingStore>()((set, get) => ({
loaders: {},
set(id: string, value: boolean) {
set({ loaders: { ...get().loaders, [id]: value } });
},
}));

0 comments on commit f682a91

Please sign in to comment.