Update events for contestants and host
This commit is contained in:
parent
de65fddba2
commit
96cba06c60
@ -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}
|
||||||
/>
|
/>
|
||||||
|
12
src/Host.tsx
12
src/Host.tsx
@ -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) {
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user