Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 1x 15x | import React, { createContext, useCallback } from 'react';
import { useGameStateContext } from '@lib/providers/GameState';
import { Game } from '@uniquegood/realworld-web-interface/lib/models/game';
interface BgmProviderProps {
fileList: Game['fileList'];
children: React.ReactNode;
}
const BgmContext = createContext<{
isExistBgm: boolean;
isPlayingBgm: boolean;
setIsPlayingBgm: (value: boolean) => unknown;
}>({
isExistBgm: false,
isPlayingBgm: true,
setIsPlayingBgm: () => {
// pass
}
});
export const useBgmContext = () => React.useContext(BgmContext);
export function BgmProvider({ fileList, children }: BgmProviderProps) {
const { gameStateForRender } = useGameStateContext();
const [isPlayingBgm, setIsPlayingBgm] = React.useState(false);
const audioRef = React.useRef<HTMLAudioElement | null>(null);
React.useEffect(() => {
if (!audioRef.current) return;
if (isPlayingBgm) {
audioRef.current.play();
} else if (!isPlayingBgm) {
audioRef.current.pause();
}
}, [isPlayingBgm]);
const bgmAudioId = React.useMemo(
() => gameStateForRender.gameMeta.currentBgmAudioId,
[gameStateForRender.gameMeta.currentBgmAudioId]
);
React.useEffect(() => {
if (!bgmAudioId) return;
const src = fileList.find((file) => file.id === bgmAudioId)?.src;
if (src) {
if (!audioRef.current) {
const audio = new Audio();
audio.src = src;
audio.loop = true;
audioRef.current = audio;
audio
.play()
.then(() => {
setIsPlayingBgm(true);
})
.catch((e) => {
if (e.name === 'NotAllowedError') {
setIsPlayingBgm(false);
alert('우측 상단의 버튼을 눌러 BGM(배경음악)을 끄거나 켤 수 있습니다.');
}
});
} else {
audioRef.current.src = src;
if (isPlayingBgm) {
audioRef.current.play();
}
}
}
}, [bgmAudioId]);
const handleVisibilityChange = useCallback(() => {
if (!audioRef.current) return;
if (document.hidden) {
setIsPlayingBgm(false);
} else if (!document.hidden) {
setIsPlayingBgm(true);
}
}, [isPlayingBgm, document.hidden]);
// 다른 탭 이동 또는 비활성화 시 배경 음악 중단
React.useEffect(() => {
window.addEventListener('visibilitychange', handleVisibilityChange);
return () => {
window.removeEventListener('visibilitychange', handleVisibilityChange);
};
}, []);
const bgmContextValue = React.useMemo(
() => ({
isExistBgm: Boolean(bgmAudioId),
isPlayingBgm,
setIsPlayingBgm
}),
[isPlayingBgm, setIsPlayingBgm]
);
return <BgmContext.Provider value={bgmContextValue}>{children}</BgmContext.Provider>;
}
|