diff --git a/package.json b/package.json
index 158cdd8..715b6c7 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
- "start": "vite --host",
+ "start": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"pretty": "prettier -w src",
diff --git a/src/Contestant.tsx b/src/Contestant.tsx
index 0f58314..7fdb421 100644
--- a/src/Contestant.tsx
+++ b/src/Contestant.tsx
@@ -1,7 +1,7 @@
import { useEffect } from "react";
import { useParams } from "react-router-dom";
-import { debounce } from "lodash";
+import { debounce } from "./utils";
import { socket } from "./socket";
import { useAppSelector } from "./hooks";
import { selectCanBuzz, selectSignature } from "./store/contestantSlice";
@@ -16,15 +16,11 @@ const Contestant = () => {
socket.emit("contestant-join", { room, signature });
}, []);
- const handleBuzz = debounce(
- () => {
- if (canBuzz) {
- socket.emit("buzz");
- }
- },
- 1000,
- { leading: true, trailing: false }
- );
+ const handleBuzz = debounce(() => {
+ if (canBuzz) {
+ socket.emit("buzz");
+ }
+ });
return (
diff --git a/src/Host.tsx b/src/Host.tsx
index edff46f..deda5ef 100644
--- a/src/Host.tsx
+++ b/src/Host.tsx
@@ -3,13 +3,15 @@ import { useParams } from "react-router-dom";
import { socket } from "./socket";
import { useAppSelector } from "./hooks";
-import { selectCategories } from "./store/cluesSlice";
+import { selectCategories, selectActiveClue } from "./store/cluesSlice";
import Pregame from "./host/Pregame";
+import ActiveClue from "./host/ActiveClue";
import CluesDisplay from "./host/CluesDisplay";
const Host = () => {
const { room } = useParams();
+ const activeClue = useAppSelector(selectActiveClue);
const categories = useAppSelector(selectCategories);
useEffect(() => {
@@ -18,6 +20,8 @@ const Host = () => {
if (categories.length < 6) {
return
;
+ } else if (activeClue) {
+ return
;
} else {
return
;
}
diff --git a/src/host/ActiveClue.tsx b/src/host/ActiveClue.tsx
new file mode 100644
index 0000000..1914a74
--- /dev/null
+++ b/src/host/ActiveClue.tsx
@@ -0,0 +1,27 @@
+import { Container, Stack, Button } from "react-bootstrap";
+
+import { useAppDispatch } from "../hooks";
+import { setActiveClue } from "../store/cluesSlice";
+import type { Clue } from "../store/cluesSlice";
+
+interface Props {
+ activeClue: Clue;
+}
+
+// TODO implement timer
+
+const ActiveClue = ({ activeClue }: Props) => {
+ const dispatch = useAppDispatch();
+ return (
+
+ {activeClue.question}
+
+
+
+
+ );
+};
+
+export default ActiveClue;
diff --git a/src/host/CluesDisplay.tsx b/src/host/CluesDisplay.tsx
index 86b6bf7..15348f7 100644
--- a/src/host/CluesDisplay.tsx
+++ b/src/host/CluesDisplay.tsx
@@ -3,9 +3,16 @@ import { Container, Button, Stack } from "react-bootstrap";
import { useAppSelector } from "../hooks";
import { selectCategories } from "../store/cluesSlice";
+import { socket } from "../socket";
+import { debounce } from "../utils";
const CluesDisplay = () => {
const categories = useAppSelector(selectCategories);
+
+ const activateClue = debounce((name: string, value: number) => {
+ socket.emit("activate-clue", { name, value });
+ });
+
return (
@@ -13,7 +20,9 @@ const CluesDisplay = () => {
{name}
{[200, 400, 600, 800, 1000].map((value) => (
-
+
))}
))}
diff --git a/src/socket.ts b/src/socket.ts
index 3d74d1d..9c2eb03 100644
--- a/src/socket.ts
+++ b/src/socket.ts
@@ -2,7 +2,8 @@ import { io } from "socket.io-client";
import store from "./store";
import { setRoomCode } from "./store/socketSlice";
import { addContestant } from "./store/displaySlice";
-import { setCategories } from "./store/cluesSlice";
+import { setCategories, setActiveClue } from "./store/cluesSlice";
+import type { Clue } from "./store/cluesSlice";
export const socket = io(`${window.location.hostname}:5000`);
@@ -25,4 +26,8 @@ export const setup = () => {
socket.on("categories", (data: Record) => {
store.dispatch(setCategories(data));
});
+
+ socket.on("active-clue", (data: Clue) => {
+ store.dispatch(setActiveClue(data));
+ });
};
diff --git a/src/store/cluesSlice.ts b/src/store/cluesSlice.ts
index 5daba1a..a102ee8 100644
--- a/src/store/cluesSlice.ts
+++ b/src/store/cluesSlice.ts
@@ -1,32 +1,48 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import type { RootState } from "./";
+interface CluesState {
+ activeClue: Clue | null;
+ categories: Category[];
+}
+
interface Category {
name: string;
clues: Clue[];
}
-interface Clue {
+export interface Clue {
value: number;
question: string;
answer: string;
}
-const initialState: Category[] = [];
+const initialState: CluesState = {
+ activeClue: null,
+ categories: [],
+};
export const cluesSlice = createSlice({
name: "clues",
initialState,
reducers: {
- setCategories: (state, action: PayloadAction>) =>
- Object.entries(action.payload).map(([name, clues]) => ({
+ setCategories: (
+ state,
+ { payload }: PayloadAction>
+ ) => {
+ state.categories = Object.entries(payload).map(([name, clues]) => ({
name,
clues,
- })),
+ }));
+ },
+ setActiveClue: (state, { payload }: PayloadAction) => {
+ state.activeClue = payload;
+ },
},
});
-export const { setCategories } = cluesSlice.actions;
-export const selectCategories = (state: RootState) => state.clues;
+export const { setCategories, setActiveClue } = cluesSlice.actions;
+export const selectCategories = (state: RootState) => state.clues.categories;
+export const selectActiveClue = (state: RootState) => state.clues.activeClue;
export default cluesSlice.reducer;
diff --git a/src/utils.ts b/src/utils.ts
new file mode 100644
index 0000000..2f1cada
--- /dev/null
+++ b/src/utils.ts
@@ -0,0 +1,4 @@
+import { debounce as lodashDebounce } from "lodash";
+
+export const debounce = (fn: (...args: unknown[]) => unknown) =>
+ lodashDebounce(fn, 1000, { leading: true, trailing: false });
diff --git a/vite.config.ts b/vite.config.ts
index 5f53b69..02ea9a5 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,11 +1,19 @@
-import { defineConfig } from 'vite';
-import react from '@vitejs/plugin-react';
-import eslint from 'vite-plugin-eslint';
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+import eslint from "vite-plugin-eslint";
// https://vitejs.dev/config/
export default defineConfig({
+ server: {
+ host: true,
+ },
plugins: [
- {...react(), ...eslint(), apply: 'build'},
- {...react(), ...eslint({ failOnWarning: false, failOnError: false }), apply: 'serve', enforce: 'post'},
+ { ...react(), ...eslint(), apply: "build" },
+ {
+ ...react(),
+ ...eslint({ failOnWarning: false, failOnError: true }),
+ apply: "serve",
+ enforce: "post",
+ },
],
});