feat: add basic fading effect

This commit is contained in:
MAZE 2024-04-30 17:47:49 +03:30
parent 7c57fb686b
commit 6ce766af47
4 changed files with 47 additions and 12 deletions

View file

@ -2,6 +2,7 @@ import { useEffect, useState, useRef, useMemo } from 'react';
import { Modal } from '@/components/modal';
import { Timer } from '@/components/timer';
import { dispatch } from '@/lib/event';
import { useSoundStore } from '@/store';
import { cn } from '@/helpers/styles';
@ -56,7 +57,9 @@ export function SleepTimerModal({ onClose, show }: SleepTimerModalProps) {
useEffect(() => {
if (timeLeft === 0) {
setRunning(false);
pause();
// pause();
dispatch('fadeOut', { duration: 5000 });
setTimeSpent(0);
if (timerId.current) clearInterval(timerId.current);

View file

@ -1,13 +1,16 @@
import { useMemo, useEffect, useCallback, useState } from 'react';
import { Howl } from 'howler';
import { useLoadingStore } from '@/store';
import { useSoundStore, useLoadingStore } from '@/store';
import { subscribe } from '@/lib/event';
import { useSSR } from './use-ssr';
export function useSound(
src: string,
options: { loop?: boolean; volume?: number } = {},
) {
const pauseAll = useSoundStore(state => state.pause);
const [hasLoaded, setHasLoaded] = useState(false);
const isLoading = useLoadingStore(state => state.loaders[src]);
const setIsLoading = useLoadingStore(state => state.set);
@ -62,9 +65,28 @@ export function useSound(
if (sound) sound.pause();
}, [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(
() => ({ isLoading, pause, play, stop }),
[play, stop, pause, isLoading],
() => ({ fadeOut, isLoading, pause, play, stop }),
[play, stop, pause, isLoading, fadeOut],
);
return control;

View file

@ -1,13 +1,23 @@
export function dispatch(eventName: string) {
const event = new Event(eventName);
export function dispatch<T>(eventName: string, detail?: T) {
const event = new CustomEvent(eventName, { detail });
document.dispatchEvent(event);
}
export function subscribe(eventName: string, listener: () => void) {
document.addEventListener(eventName, listener);
export function subscribe<T>(eventName: string, listener: (e: T) => void) {
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);
}

View file

@ -1,11 +1,11 @@
import { dispatch, subscribe, unsubscribe } from './event';
import { dispatch, subscribe } from './event';
export function closeModals() {
dispatch('closeModals');
}
export function onCloseModals(listener: () => void) {
subscribe('closeModals', listener);
const unsubscribe = subscribe('closeModals', listener);
return () => unsubscribe('closeModals', listener);
return unsubscribe;
}