bedtime-story-generator / src /hooks /useAudioPlayer.ts
Xenova's picture
Xenova HF Staff
Upload application
59c3ada verified
import { useState, useRef, useCallback } from "react";
type AudioKeys = "pop" | "hover" | "music";
interface AudioPlayer {
initAudio: () => boolean;
playPopSound: () => void;
playHoverSound: () => void;
toggleMusic: () => void;
playMusic: () => void;
isMusicPlaying: boolean;
isAudioReady: boolean;
}
const useAudioPlayer = (): AudioPlayer => {
const audioRefs = useRef<Record<AudioKeys, HTMLAudioElement | null>>({
pop: null,
hover: null,
music: null,
});
const [isReady, setIsReady] = useState<boolean>(false);
const [isMusicPlaying, setIsMusicPlaying] = useState<boolean>(false);
const initAudio = useCallback(() => {
if (isReady) return true;
try {
audioRefs.current.pop = new Audio("/bubble.mp3");
audioRefs.current.hover = new Audio("/hover.mp3");
audioRefs.current.music = new Audio("/music.mp3");
audioRefs.current.music.loop = true;
audioRefs.current.music.volume = 0.1;
setIsReady(true);
return true;
} catch {
return false;
}
}, [isReady]);
const playMusic = useCallback(() => {
if (isReady && !isMusicPlaying) {
audioRefs.current.music?.play().catch(() => {});
setIsMusicPlaying(true);
}
}, [isReady, isMusicPlaying]);
const toggleMusic = useCallback(
(force?: boolean) => {
if (!isReady || !audioRefs.current.music) return;
const shouldBePlaying = force === undefined ? !isMusicPlaying : force;
if (shouldBePlaying === isMusicPlaying) return;
if (shouldBePlaying) {
audioRefs.current.music?.play().catch(() => {});
} else {
audioRefs.current.music?.pause();
}
setIsMusicPlaying(shouldBePlaying);
},
[isReady, isMusicPlaying],
);
const playPopSound = useCallback(() => {
if (!isReady || !audioRefs.current.pop) return;
audioRefs.current.pop.currentTime = 0;
audioRefs.current.pop.play().catch(() => {});
}, [isReady]);
const playHoverSound = useCallback(() => {
if (!isReady || !audioRefs.current.hover) return;
audioRefs.current.hover.currentTime = 0;
audioRefs.current.hover.play().catch(() => {});
}, [isReady]);
return {
initAudio,
playPopSound,
playHoverSound,
toggleMusic,
playMusic,
isMusicPlaying,
isAudioReady: isReady,
};
};
export default useAudioPlayer;