mirror of
https://github.com/remvze/moodist.git
synced 2025-12-17 08:54:13 +00:00
feat: add loader for favorites
This commit is contained in:
parent
a33ae450cf
commit
f682a910da
4 changed files with 26 additions and 7 deletions
|
|
@ -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({
|
|||
>
|
||||
<Favorite id={id} />
|
||||
<div className={styles.icon}>
|
||||
{sound.isLoading ? (
|
||||
{isLoading ? (
|
||||
<span className={styles.spinner}>
|
||||
<ImSpinner9 />
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -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<Howl | null>(() => {
|
||||
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();
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
export { useSoundStore } from './sound';
|
||||
export { useLoadingStore } from './loading';
|
||||
|
|
|
|||
13
src/store/loading/index.ts
Normal file
13
src/store/loading/index.ts
Normal file
|
|
@ -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 } });
|
||||
},
|
||||
}));
|
||||
Loading…
Add table
Reference in a new issue