'use client' import { useState, useEffect, useRef } from 'react' import Image from 'next/image' import { Socket, io } from "socket.io-client" import { getRandomQuestion, playModes } from "./questions" import { IconCrown, IconPhotoUp, IconCamera } from "@tabler/icons-react" import { defaultAvatarImage } from '../avatarImage' import { resizeBase64Image, getBase64OfImage } from '../utils' import ModeCard from '@/components/modeCard' import EditCustomQuestions from '@/components/editCustomQuestions' import Webcam from 'react-webcam' import { PlayerChoice } from '@/utils/types' interface roomProps { params: { id: string; }; } export default function GameRoom({ params }: roomProps) { const [isConnected, setIsConnected] = useState(false) const [forceUpdate, setForceUpdate] = useState(0) const [role, setRole] = useState("") const [name, setName] = useState("") const [avatar, setAvatar] = useState(defaultAvatarImage) const [browserId, setBrowserId] = useState("") const [gameStarted, setGameStarted] = useState(false) const [gameEnded, setGameEnded] = useState(false) const [questionReply, setQuestionReply] = useState({}) const [questionDisplayed, setQuestionDisplayed] = useState({}) const [possibleChoice, setPossibleChoice] = useState([]) const [totalVotes, setTotalVotes] = useState(0) const [choice, setChoice] = useState("") const [countdown, setCountdown] = useState(0) const [players, setPlayers] = useState([]) const [questionNbr, setQuestionNbr] = useState(0) const [questionAlreadyDone, setQuestionAlreadyDone] = useState([]) const [selectedMode, setSelectedMode] = useState(0) const [customQuestions, setCustomQuestions] = useState([]) const socketRef = useRef() // eslint-disable-line const inputPhotoRef = useRef() const editCustomQuestionsRef = useRef() const duration = 15 const questionLimit = 10 const { id } = params const roomNameDisplay = id.substring(0,3) + " " + id.substring(3,6) useEffect(() => { const localName = localStorage.getItem('name') setName(localName) const localAvatar = localStorage.getItem('avatar') setAvatar(localAvatar) const localBrowserId = localStorage.getItem("browserId") setBrowserId(localBrowserId) const localCustomQuestionsString = localStorage.getItem("customQuestions") const localCustomQuestions = JSON.parse(localCustomQuestionsString != null ? localCustomQuestionsString : "") setCustomQuestions(localCustomQuestions == null ? [] : localCustomQuestions) // Listen for incoming setMessages socketRef.current = io("ws://localhost:3000"); socketRef.current!.on("connect", () => { setIsConnected(true) socketRef.current!.emit('room_connect', {id: id, name: localName, avatar: localAvatar, browserId: localBrowserId}) }); socketRef.current!.on("new_player", (params) => { setPlayers(oldPlayers => [...oldPlayers, params]) }) socketRef.current!.on("start_game", (params) => { setQuestionNbr(params.questionNbr) setGameStarted(true) setQuestionDisplayed(params.question) setPossibleChoice(params.possibleChoice) setCountdown(params.duration) }) socketRef.current!.on("next_question", (params) => { setQuestionNbr(oldQ => oldQ + 1) setChoice("") setQuestionDisplayed(params.question) setPossibleChoice(params.possibleChoice) setCountdown(params.duration) setTotalVotes(0) }) socketRef.current!.on("question_reply", (params) => { console.log(params) setQuestionReply(params) }) socketRef.current!.on("reset_game", (params) => { setGameStarted(false) setCountdown(0) setPossibleChoice([]) setQuestionDisplayed("") setChoice("") setQuestionNbr(0) setTotalVotes(0) }) socketRef.current!.on("room_joined", (params) => { setPlayers(params.room_users) setRole(params.role) }) // Clean up the socket connection on unmount return () => { socketRef.current!.disconnect(); }; }, []); function forceUpdateFunc(){ setForceUpdate(fu => fu + 1) } useEffect(() => { const eventListener = (params: any) => { setTotalVotes(oldTotal => oldTotal += 1) console.log(params) let temp_possibleChoice = possibleChoice temp_possibleChoice!.forEach((playerChoice) => { if(playerChoice.name == params.choice) { playerChoice.nbrVotes += 1 } }) forceUpdateFunc() }; socketRef.current!.on("player_choice", eventListener) return () => {socketRef.current!.off("player_choice", eventListener)} }, [possibleChoice]) useEffect(() => { countdown > 0 && setTimeout(() => setCountdown(countdown - 1), 1000); }, [countdown]); function getPossibleChoice() { let choice1 = Math.floor(Math.random() * players.length) console.log(players.length) let choice2 = Math.floor(Math.random() * players.length) console.log(choice2) while(choice2 == choice1){ choice2 = Math.floor(Math.random() * players.length) } let playerChoice1 = players[choice1] playerChoice1.nbrVotes = 0 let playerChoice2 = players[choice2] playerChoice2.nbrVotes = 0 return [playerChoice1, playerChoice2] } function startGame() { let possibleChoice = getPossibleChoice() let questionObj = getRandomQuestion(playModes[selectedMode], [], customQuestions) let question = questionObj.question setQuestionAlreadyDone(questionObj.alreadyDone) socketRef.current!.emit("start_game", {roomId: id, question: question, possibleChoice: possibleChoice, duration: duration}) setCountdown(duration) setPossibleChoice(possibleChoice) setQuestionDisplayed(question) setGameStarted(true) setQuestionNbr(oldQ => oldQ + 1) } function nextQuestion() { let possibleChoice = getPossibleChoice() let questionObj = getRandomQuestion(playModes[selectedMode],questionAlreadyDone, customQuestions) let question = questionObj.question setQuestionAlreadyDone(questionObj.alreadyDone) socketRef.current!.emit("next_question", {roomId: id, question: question, possibleChoice: possibleChoice, duration: duration}) setCountdown(duration) setPossibleChoice(possibleChoice) setQuestionDisplayed(question) setChoice("") setQuestionNbr(oldQ => oldQ + 1) setTotalVotes(0) } function resetGame() { socketRef.current!.emit("reset_game", {roomId: id}) setGameStarted(false) setCountdown(0) setPossibleChoice([]) setQuestionDisplayed("") setChoice("") setQuestionNbr(0) setTotalVotes(0) } function setAndSendChoice(playerName: any) { setChoice(playerName) setTotalVotes(oldTotal => oldTotal += 1) let temp_possibleChoice = possibleChoice temp_possibleChoice.forEach((playerChoice) => { if(playerChoice.name == playerName) { playerChoice.nbrVotes += 1 } }) setPossibleChoice(temp_possibleChoice) socketRef.current!.emit("player_choice", {roomId: id, choice: playerName, player: name}) } function setAndSendPhoto(){ getBase64OfImage(inputPhotoRef.current!.files[0], (data: any) => resizeBase64Image(data).then((data: any) =>{ setQuestionReply({photo: data}) socketRef.current!.emit("question_reply", { roomId: id, data:{photo: data}}) })) } function setAndSaveCustomQuestions(data: any){ setCustomQuestions(data) localStorage.setItem("customQuestions", JSON.stringify(data)) } return (
{ !gameStarted && <>

{roomNameDisplay}

{ !isConnected &&

Connecting to room...

} { isConnected && <> { role == "owner" && <>

Choose game mode

{ playModes.map((mode, index) => { return( setSelectedMode(index)} selected={selectedMode === index} /> ) })}
{ playModes[selectedMode].name == "Custom" && <> setAndSaveCustomQuestions(data)} /> } }

Players

{ players.length == 0 &&

Waiting for players to join...

} { players.length > 0 &&
{ players.map((player) => { return ( <>
{player.role == "owner" && }

{player.name}

) })}
{ role == "owner" && }
}
}
} { gameStarted && <>

{questionDisplayed!.text}

{questionNbr}/{questionLimit}
{ countdown > 0 && <>
{ choice == "" && <> { possibleChoice.map((playerChoice, index) => ( ))} } { choice != "" && Waiting }
} { countdown == 0 && <>
{ possibleChoice.map((playerChoice, index) => { console.log(totalVotes) console.log(playerChoice.nbrVotes / totalVotes) let percent = Math.floor((playerChoice.nbrVotes / totalVotes) * 100) return (
{percent}%

{playerChoice.name}

)})}
{ (questionDisplayed.type == "photo" && possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].browserId == browserId) && <> { questionReply.photo == undefined &&
À toi d'envoyer une photo !
} { questionReply.photo != undefined &&
Photo received from {possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].name}...
} } { (questionDisplayed.type == "photo" && possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].browserId != browserId) && <> { questionReply.photo == undefined &&
Waiting for {possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].name}...
} { questionReply.photo != undefined &&
Photo received from {possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].name}...
} } { (role == "owner" && questionNbr < questionLimit) && } { (role == "owner" && questionNbr == questionLimit) && } } }
); }