Update events for contestants and host

This commit is contained in:
Dane Johnson 2023-02-25 10:50:28 -06:00
parent de65fddba2
commit 96cba06c60
4 changed files with 56 additions and 8 deletions

View File

@ -11,10 +11,23 @@ const Contestant = () => {
const signature = useAppSelector(selectSignature); const signature = useAppSelector(selectSignature);
const [canBuzz, setCanBuzz] = useState<boolean>(false); const [canBuzz, setCanBuzz] = useState<boolean>(false);
const [active, setActive] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
socket.emit("contestant-join", { room, signature }); socket.emit("contestant-join", { room, signature });
socket.on("clue-clock-on", () => setCanBuzz(true)); 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(() => { const handleBuzz = debounce(() => {
@ -30,7 +43,7 @@ const Contestant = () => {
cx={50} cx={50}
cy={50} cy={50}
r={30} r={30}
fill={canBuzz ? "red" : "grey"} fill={active ? "green" : canBuzz ? "red" : "grey"}
stroke="black" stroke="black"
onClick={handleBuzz} onClick={handleBuzz}
/> />

View File

@ -2,8 +2,12 @@ import { useEffect } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { socket } from "./socket"; import { socket } from "./socket";
import { useAppSelector } from "./hooks"; import { useAppSelector, useAppDispatch } from "./hooks";
import { selectCategories, selectActiveClue } from "./store/cluesSlice"; import {
selectCategories,
selectActiveClue,
clearActiveClue,
} from "./store/cluesSlice";
import Pregame from "./host/Pregame"; import Pregame from "./host/Pregame";
import ActiveClue from "./host/ActiveClue"; import ActiveClue from "./host/ActiveClue";
import CluesDisplay from "./host/CluesDisplay"; import CluesDisplay from "./host/CluesDisplay";
@ -11,11 +15,15 @@ import CluesDisplay from "./host/CluesDisplay";
const Host = () => { const Host = () => {
const { room } = useParams(); const { room } = useParams();
const dispatch = useAppDispatch();
const activeClue = useAppSelector(selectActiveClue); const activeClue = useAppSelector(selectActiveClue);
const categories = useAppSelector(selectCategories); const categories = useAppSelector(selectCategories);
useEffect(() => { useEffect(() => {
socket.emit("host-join", { room }); socket.emit("host-join", { room });
socket.on("contestant-scores", () => dispatch(clearActiveClue()));
socket.on("clue-clock-off", () => dispatch(clearActiveClue()));
}, []); }, []);
if (categories.length < 6) { if (categories.length < 6) {

View File

@ -1,22 +1,45 @@
import { useState, useEffect } from "react";
import { Container, Stack, Button } from "react-bootstrap"; import { Container, Stack, Button } from "react-bootstrap";
import type { Clue } from "../store/cluesSlice"; import type { Clue } from "../store/cluesSlice";
import { socket } from "../socket"; import { socket } from "../socket";
import { debounce } from "../utils";
interface Props { interface Props {
activeClue: Clue; activeClue: Clue;
} }
// TODO implement timer type Mode = "reading" | "running" | "buzzed";
const ActiveClue = ({ activeClue }: Props) => { const ActiveClue = ({ activeClue }: Props) => {
const [mode, setMode] = useState<Mode>("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 ( return (
<Container> <Container>
<p>{activeClue.question}</p> <p>{activeClue.question}</p>
<Stack gap={3} className="text-center"> <Stack gap={3} className="text-center">
<Button onClick={() => socket.emit("start-clue-clock")}> {mode === "reading" && (
Start Timer <Button onClick={startTimer}>Start Timer</Button>
</Button> )}
{mode === "buzzed" && (
<>
<Button onClick={contestantCorrect}>Correct</Button>
<Button onClick={contestantIncorrect}>Incorrect</Button>
</>
)}
</Stack> </Stack>
</Container> </Container>
); );

View File

@ -38,10 +38,14 @@ export const cluesSlice = createSlice({
setActiveClue: (state, { payload }: PayloadAction<Clue | null>) => { setActiveClue: (state, { payload }: PayloadAction<Clue | null>) => {
state.activeClue = payload; 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 selectCategories = (state: RootState) => state.clues.categories;
export const selectActiveClue = (state: RootState) => state.clues.activeClue; export const selectActiveClue = (state: RootState) => state.clues.activeClue;