From 96cba06c60762d8228f7c0046cbe1d730fe370f9 Mon Sep 17 00:00:00 2001 From: Dane Johnson Date: Sat, 25 Feb 2023 10:50:28 -0600 Subject: [PATCH] Update events for contestants and host --- src/Contestant.tsx | 15 ++++++++++++++- src/Host.tsx | 12 ++++++++++-- src/host/ActiveClue.tsx | 31 +++++++++++++++++++++++++++---- src/store/cluesSlice.ts | 6 +++++- 4 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/Contestant.tsx b/src/Contestant.tsx index 108319a..f9c49e2 100644 --- a/src/Contestant.tsx +++ b/src/Contestant.tsx @@ -11,10 +11,23 @@ const Contestant = () => { const signature = useAppSelector(selectSignature); const [canBuzz, setCanBuzz] = useState(false); + const [active, setActive] = useState(false); useEffect(() => { socket.emit("contestant-join", { room, signature }); socket.on("clue-clock-on", () => setCanBuzz(true)); + socket.on("clue-clock-off", () => setCanBuzz(false)); + socket.on("contestant-buzzed", ({ sid }) => { + setCanBuzz(false); + if (sid === socket.id) { + setActive(true); + } + }); + socket.on("contestant-scores", () => setActive(false)); + socket.on("contestant-penalized", () => { + setActive(false); + setCanBuzz(true); + }); }, []); const handleBuzz = debounce(() => { @@ -30,7 +43,7 @@ const Contestant = () => { cx={50} cy={50} r={30} - fill={canBuzz ? "red" : "grey"} + fill={active ? "green" : canBuzz ? "red" : "grey"} stroke="black" onClick={handleBuzz} /> diff --git a/src/Host.tsx b/src/Host.tsx index deda5ef..8fec7b9 100644 --- a/src/Host.tsx +++ b/src/Host.tsx @@ -2,8 +2,12 @@ import { useEffect } from "react"; import { useParams } from "react-router-dom"; import { socket } from "./socket"; -import { useAppSelector } from "./hooks"; -import { selectCategories, selectActiveClue } from "./store/cluesSlice"; +import { useAppSelector, useAppDispatch } from "./hooks"; +import { + selectCategories, + selectActiveClue, + clearActiveClue, +} from "./store/cluesSlice"; import Pregame from "./host/Pregame"; import ActiveClue from "./host/ActiveClue"; import CluesDisplay from "./host/CluesDisplay"; @@ -11,11 +15,15 @@ import CluesDisplay from "./host/CluesDisplay"; const Host = () => { const { room } = useParams(); + const dispatch = useAppDispatch(); + const activeClue = useAppSelector(selectActiveClue); const categories = useAppSelector(selectCategories); useEffect(() => { socket.emit("host-join", { room }); + socket.on("contestant-scores", () => dispatch(clearActiveClue())); + socket.on("clue-clock-off", () => dispatch(clearActiveClue())); }, []); if (categories.length < 6) { diff --git a/src/host/ActiveClue.tsx b/src/host/ActiveClue.tsx index 36dec1f..eed1877 100644 --- a/src/host/ActiveClue.tsx +++ b/src/host/ActiveClue.tsx @@ -1,22 +1,45 @@ +import { useState, useEffect } from "react"; import { Container, Stack, Button } from "react-bootstrap"; import type { Clue } from "../store/cluesSlice"; import { socket } from "../socket"; +import { debounce } from "../utils"; interface Props { activeClue: Clue; } -// TODO implement timer +type Mode = "reading" | "running" | "buzzed"; const ActiveClue = ({ activeClue }: Props) => { + const [mode, setMode] = useState("reading"); + useEffect(() => { + socket.on("clue-clock-on", () => { + setMode("running"); + }); + socket.on("contestant-buzzed", () => { + setMode("buzzed"); + }); + }, []); + const startTimer = debounce(() => socket.emit("start-clue-clock")); + const contestantCorrect = debounce(() => socket.emit("contestant-correct")); + const contestantIncorrect = debounce(() => { + setMode("running"); + socket.emit("contestant-incorrect"); + }); return (

{activeClue.question}

- + {mode === "reading" && ( + + )} + {mode === "buzzed" && ( + <> + + + + )}
); diff --git a/src/store/cluesSlice.ts b/src/store/cluesSlice.ts index d57988c..0a6b816 100644 --- a/src/store/cluesSlice.ts +++ b/src/store/cluesSlice.ts @@ -38,10 +38,14 @@ export const cluesSlice = createSlice({ setActiveClue: (state, { payload }: PayloadAction) => { state.activeClue = payload; }, + clearActiveClue: (state) => { + state.activeClue = null; + }, }, }); -export const { setCategories, setActiveClue } = cluesSlice.actions; +export const { setCategories, setActiveClue, clearActiveClue } = + cluesSlice.actions; export const selectCategories = (state: RootState) => state.clues.categories; export const selectActiveClue = (state: RootState) => state.clues.activeClue;