Files
Rahoot/packages/web/src/components/game/states/Responses.tsx
T

124 lines
3.4 KiB
TypeScript

"use client"
import { ManagerStatusDataMap } from "@rahoot/common/types/game/status"
import AnswerButton from "@rahoot/web/components/AnswerButton"
import QuestionMedia from "@rahoot/web/components/game/QuestionMedia"
import {
ANSWERS_COLORS,
ANSWERS_ICONS,
SFX_ANSWERS_MUSIC,
SFX_RESULTS_SOUND,
} from "@rahoot/web/utils/constants"
import { calculatePercentages } from "@rahoot/web/utils/score"
import clsx from "clsx"
import { useEffect, useState } from "react"
import useSound from "use-sound"
type Props = {
data: ManagerStatusDataMap["SHOW_RESPONSES"]
}
const Responses = ({
data: { question, answers, responses, correct, image, media },
}: Props) => {
const [percentages, setPercentages] = useState<Record<string, string>>({})
const [isMusicPlaying, setIsMusicPlaying] = useState(false)
const [isMediaPlaying, setIsMediaPlaying] = useState(false)
const [sfxResults] = useSound(SFX_RESULTS_SOUND, {
volume: 0.2,
})
const [playMusic, { stop: stopMusic, sound: answersMusic }] = useSound(
SFX_ANSWERS_MUSIC,
{
volume: 0.2,
onplay: () => {
setIsMusicPlaying(true)
},
onend: () => {
setIsMusicPlaying(false)
},
},
)
useEffect(() => {
stopMusic()
sfxResults()
setPercentages(calculatePercentages(responses))
}, [responses, playMusic, stopMusic, sfxResults])
useEffect(() => {
if (!isMusicPlaying) {
playMusic()
}
}, [isMusicPlaying, playMusic])
useEffect(() => {
if (!answersMusic) {
return
}
answersMusic.volume(isMediaPlaying ? 0.05 : 0.2)
}, [answersMusic, isMediaPlaying])
useEffect(() => {
stopMusic()
}, [playMusic, stopMusic])
return (
<div className="flex h-full flex-1 flex-col justify-between">
<div className="mx-auto inline-flex h-full w-full max-w-7xl flex-1 flex-col items-center justify-center gap-5">
<h2 className="text-center text-2xl font-bold text-white drop-shadow-lg md:text-4xl lg:text-5xl">
{question}
</h2>
<QuestionMedia
media={media || (image ? { type: "image", url: image } : undefined)}
alt={question}
onPlayChange={(playing) => setIsMediaPlaying(playing)}
/>
<div
className={`mt-8 grid h-40 w-full max-w-3xl gap-4 px-2`}
style={{ gridTemplateColumns: `repeat(${answers.length}, 1fr)` }}
>
{answers.map((_, key) => (
<div
key={key}
className={clsx(
"flex flex-col justify-end self-end overflow-hidden rounded-md",
ANSWERS_COLORS[key],
)}
style={{ height: percentages[key] }}
>
<span className="w-full bg-black/10 text-center text-lg font-bold text-white drop-shadow-md">
{responses[key] || 0}
</span>
</div>
))}
</div>
</div>
<div>
<div className="mx-auto mb-4 grid w-full max-w-7xl grid-cols-2 gap-1 rounded-full px-2 text-lg font-bold text-white md:text-xl">
{answers.map((answer, key) => (
<AnswerButton
key={key}
className={clsx(ANSWERS_COLORS[key], {
"opacity-65": responses && correct !== key,
})}
icon={ANSWERS_ICONS[key]}
>
{answer}
</AnswerButton>
))}
</div>
</div>
</div>
)
}
export default Responses