Skip to content

Commit

Permalink
feat: add alarm for pomodoro timer
Browse files Browse the repository at this point in the history
  • Loading branch information
remvze committed Feb 29, 2024
1 parent 110356b commit 0eb47ba
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
Binary file added public/sounds/alarm.mp3
Binary file not shown.
7 changes: 6 additions & 1 deletion src/components/toolbox/pomodoro/pomodoro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Button } from './button';
import { Setting } from './setting';

import { useLocalStorage } from '@/hooks/use-local-storage';
import { useSoundEffect } from '@/hooks/use-sound-effect';
import { usePomodoroStore } from '@/store';

import styles from './pomodoro.module.css';
Expand All @@ -29,6 +30,8 @@ export function Pomodoro({ onClose, show }: PomodoroProps) {
const [timer, setTimer] = useState(0);
const interval = useRef<ReturnType<typeof setInterval> | null>(null);

const alarm = useSoundEffect('/sounds/alarm.mp3');

const defaultTimes = useMemo(
() => ({
long: 15 * 60,
Expand Down Expand Up @@ -74,13 +77,15 @@ export function Pomodoro({ onClose, show }: PomodoroProps) {
if (timer <= 0 && running) {
if (interval.current) clearInterval(interval.current);

alarm.play();

setRunning(false);
setCompletions(prev => ({
...prev,
[selectedTab]: prev[selectedTab] + 1,
}));
}
}, [timer, selectedTab, running, setRunning]);
}, [timer, selectedTab, running, setRunning, alarm]);

useEffect(() => {
const time = times[selectedTab] || 10;
Expand Down
45 changes: 45 additions & 0 deletions src/hooks/use-sound-effect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useMemo, useEffect, useCallback } from 'react';
import { Howl } from 'howler';

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

export function useSoundEffect(src: string, volume: number = 1) {
const { isBrowser } = useSSR();

const sound = useMemo<Howl | null>(() => {
let sound: Howl | null = null;

if (isBrowser) {
sound = new Howl({
html5: true,
src: src,
});
}

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

useEffect(() => {
if (sound) sound.volume(typeof volume === 'number' ? volume : 1);
}, [sound, volume]);

const play = useCallback(() => {
if (sound) {
if (!sound.playing()) {
sound.play();
}
}
}, [sound]);

const stop = useCallback(() => {
if (sound) sound.stop();
}, [sound]);

const pause = useCallback(() => {
if (sound) sound.pause();
}, [sound]);

const control = useMemo(() => ({ pause, play, stop }), [play, stop, pause]);

return control;
}

0 comments on commit 0eb47ba

Please sign in to comment.