mirror of
https://github.com/remvze/moodist.git
synced 2025-12-17 08:54:13 +00:00
feat: add basic fading effect
This commit is contained in:
parent
7c57fb686b
commit
6ce766af47
4 changed files with 47 additions and 12 deletions
|
|
@ -2,6 +2,7 @@ import { useEffect, useState, useRef, useMemo } from 'react';
|
||||||
|
|
||||||
import { Modal } from '@/components/modal';
|
import { Modal } from '@/components/modal';
|
||||||
import { Timer } from '@/components/timer';
|
import { Timer } from '@/components/timer';
|
||||||
|
import { dispatch } from '@/lib/event';
|
||||||
import { useSoundStore } from '@/store';
|
import { useSoundStore } from '@/store';
|
||||||
import { cn } from '@/helpers/styles';
|
import { cn } from '@/helpers/styles';
|
||||||
|
|
||||||
|
|
@ -56,7 +57,9 @@ export function SleepTimerModal({ onClose, show }: SleepTimerModalProps) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (timeLeft === 0) {
|
if (timeLeft === 0) {
|
||||||
setRunning(false);
|
setRunning(false);
|
||||||
pause();
|
// pause();
|
||||||
|
dispatch('fadeOut', { duration: 5000 });
|
||||||
|
|
||||||
setTimeSpent(0);
|
setTimeSpent(0);
|
||||||
|
|
||||||
if (timerId.current) clearInterval(timerId.current);
|
if (timerId.current) clearInterval(timerId.current);
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
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 { useSoundStore, useLoadingStore } from '@/store';
|
||||||
|
import { subscribe } from '@/lib/event';
|
||||||
import { useSSR } from './use-ssr';
|
import { useSSR } from './use-ssr';
|
||||||
|
|
||||||
export function useSound(
|
export function useSound(
|
||||||
src: string,
|
src: string,
|
||||||
options: { loop?: boolean; volume?: number } = {},
|
options: { loop?: boolean; volume?: number } = {},
|
||||||
) {
|
) {
|
||||||
|
const pauseAll = useSoundStore(state => state.pause);
|
||||||
|
|
||||||
const [hasLoaded, setHasLoaded] = useState(false);
|
const [hasLoaded, setHasLoaded] = useState(false);
|
||||||
const isLoading = useLoadingStore(state => state.loaders[src]);
|
const isLoading = useLoadingStore(state => state.loaders[src]);
|
||||||
const setIsLoading = useLoadingStore(state => state.set);
|
const setIsLoading = useLoadingStore(state => state.set);
|
||||||
|
|
@ -62,9 +65,28 @@ export function useSound(
|
||||||
if (sound) sound.pause();
|
if (sound) sound.pause();
|
||||||
}, [sound]);
|
}, [sound]);
|
||||||
|
|
||||||
|
const fadeOut = useCallback(
|
||||||
|
(duration: number) => {
|
||||||
|
sound?.fade(sound.volume(), 0, duration);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
pauseAll();
|
||||||
|
|
||||||
|
sound?.volume(options.volume || 0.5);
|
||||||
|
}, duration);
|
||||||
|
},
|
||||||
|
[options.volume, sound, pauseAll],
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const listener = (e: { duration: number }) => fadeOut(e.duration);
|
||||||
|
|
||||||
|
return subscribe('fadeOut', listener);
|
||||||
|
}, [fadeOut]);
|
||||||
|
|
||||||
const control = useMemo(
|
const control = useMemo(
|
||||||
() => ({ isLoading, pause, play, stop }),
|
() => ({ fadeOut, isLoading, pause, play, stop }),
|
||||||
[play, stop, pause, isLoading],
|
[play, stop, pause, isLoading, fadeOut],
|
||||||
);
|
);
|
||||||
|
|
||||||
return control;
|
return control;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,23 @@
|
||||||
export function dispatch(eventName: string) {
|
export function dispatch<T>(eventName: string, detail?: T) {
|
||||||
const event = new Event(eventName);
|
const event = new CustomEvent(eventName, { detail });
|
||||||
|
|
||||||
document.dispatchEvent(event);
|
document.dispatchEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function subscribe(eventName: string, listener: () => void) {
|
export function subscribe<T>(eventName: string, listener: (e: T) => void) {
|
||||||
document.addEventListener(eventName, listener);
|
const handler = (event: Event) => {
|
||||||
|
if ('detail' in event) {
|
||||||
|
const payload = event.detail as T;
|
||||||
|
|
||||||
|
listener(payload);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener(eventName, handler);
|
||||||
|
|
||||||
|
return () => unsubscribe(eventName, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function unsubscribe(eventName: string, listener: () => void) {
|
export function unsubscribe(eventName: string, listener: (e: Event) => void) {
|
||||||
document.removeEventListener(eventName, listener);
|
document.removeEventListener(eventName, listener);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
import { dispatch, subscribe, unsubscribe } from './event';
|
import { dispatch, subscribe } from './event';
|
||||||
|
|
||||||
export function closeModals() {
|
export function closeModals() {
|
||||||
dispatch('closeModals');
|
dispatch('closeModals');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onCloseModals(listener: () => void) {
|
export function onCloseModals(listener: () => void) {
|
||||||
subscribe('closeModals', listener);
|
const unsubscribe = subscribe('closeModals', listener);
|
||||||
|
|
||||||
return () => unsubscribe('closeModals', listener);
|
return unsubscribe;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue