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 { Favorite } from './favorite';
|
||||||
|
|
||||||
import { useSound } from '@/hooks/use-sound';
|
import { useSound } from '@/hooks/use-sound';
|
||||||
import { useSoundStore } from '@/store';
|
import { useSoundStore, useLoadingStore } from '@/store';
|
||||||
import { cn } from '@/helpers/styles';
|
import { cn } from '@/helpers/styles';
|
||||||
|
|
||||||
import styles from './sound.module.css';
|
import styles from './sound.module.css';
|
||||||
|
|
@ -37,6 +37,8 @@ export function Sound({
|
||||||
const volume = useSoundStore(state => state.sounds[id].volume);
|
const volume = useSoundStore(state => state.sounds[id].volume);
|
||||||
const isSelected = useSoundStore(state => state.sounds[id].isSelected);
|
const isSelected = useSoundStore(state => state.sounds[id].isSelected);
|
||||||
|
|
||||||
|
const isLoading = useLoadingStore(state => state.loaders[src]);
|
||||||
|
|
||||||
const sound = useSound(src, { loop: true, volume });
|
const sound = useSound(src, { loop: true, volume });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -80,7 +82,7 @@ export function Sound({
|
||||||
>
|
>
|
||||||
<Favorite id={id} />
|
<Favorite id={id} />
|
||||||
<div className={styles.icon}>
|
<div className={styles.icon}>
|
||||||
{sound.isLoading ? (
|
{isLoading ? (
|
||||||
<span className={styles.spinner}>
|
<span className={styles.spinner}>
|
||||||
<ImSpinner9 />
|
<ImSpinner9 />
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMemo, useEffect, useCallback, useState } from 'react';
|
import { useMemo, useEffect, useCallback, useState } from 'react';
|
||||||
import { Howl } from 'howler';
|
import { Howl } from 'howler';
|
||||||
|
|
||||||
|
import { useLoadingStore } from '@/store';
|
||||||
import { useSSR } from './use-ssr';
|
import { useSSR } from './use-ssr';
|
||||||
|
|
||||||
export function useSound(
|
export function useSound(
|
||||||
|
|
@ -8,7 +9,9 @@ export function useSound(
|
||||||
options: { loop?: boolean; volume?: number } = {},
|
options: { loop?: boolean; volume?: number } = {},
|
||||||
) {
|
) {
|
||||||
const [hasLoaded, setHasLoaded] = useState(false);
|
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 { isBrowser } = useSSR();
|
||||||
const sound = useMemo<Howl | null>(() => {
|
const sound = useMemo<Howl | null>(() => {
|
||||||
let sound: Howl | null = null;
|
let sound: Howl | null = null;
|
||||||
|
|
@ -16,7 +19,7 @@ export function useSound(
|
||||||
if (isBrowser) {
|
if (isBrowser) {
|
||||||
sound = new Howl({
|
sound = new Howl({
|
||||||
onload: () => {
|
onload: () => {
|
||||||
setIsLoading(false);
|
setIsLoading(src, false);
|
||||||
setHasLoaded(true);
|
setHasLoaded(true);
|
||||||
},
|
},
|
||||||
preload: false,
|
preload: false,
|
||||||
|
|
@ -25,7 +28,7 @@ export function useSound(
|
||||||
}
|
}
|
||||||
|
|
||||||
return sound;
|
return sound;
|
||||||
}, [src, isBrowser]);
|
}, [src, isBrowser, setIsLoading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (sound) {
|
if (sound) {
|
||||||
|
|
@ -41,7 +44,7 @@ export function useSound(
|
||||||
const play = useCallback(() => {
|
const play = useCallback(() => {
|
||||||
if (sound) {
|
if (sound) {
|
||||||
if (!hasLoaded && !isLoading) {
|
if (!hasLoaded && !isLoading) {
|
||||||
setIsLoading(true);
|
setIsLoading(src, true);
|
||||||
sound.load();
|
sound.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,7 +52,7 @@ export function useSound(
|
||||||
sound.play();
|
sound.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [sound, hasLoaded, isLoading]);
|
}, [src, setIsLoading, sound, hasLoaded, isLoading]);
|
||||||
|
|
||||||
const stop = useCallback(() => {
|
const stop = useCallback(() => {
|
||||||
if (sound) sound.stop();
|
if (sound) sound.stop();
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
export { useSoundStore } from './sound';
|
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