Fix bug with no random + prevent user from starting game + ENV vars

This commit is contained in:
Lucien Astié 2024-08-12 11:47:59 +02:00
parent f80ff9c60d
commit 1f3b6ec70a
6 changed files with 66 additions and 30 deletions

View file

@ -1,7 +0,0 @@
'use client'
import { useState } from 'react'
export default function UseForceUpdate() {
const [value, setValue] = useState(0); // integer state
return () => setValue(value => value + 1); // update state to force render
}

View file

@ -1,6 +1,7 @@
'use client' 'use client'
import { useState, useEffect, useRef } from 'react' import { useState, useEffect, useRef } from 'react'
import { Socket, io } from "socket.io-client" import { Socket, io } from "socket.io-client"
import getSocketUrl from './socket'
import { getRandomQuestion, playModes } from "./questions" import { getRandomQuestion, playModes } from "./questions"
import { IconCrown, IconPhotoUp, IconCamera } from "@tabler/icons-react" import { IconCrown, IconPhotoUp, IconCamera } from "@tabler/icons-react"
import { defaultAvatarImage } from '../avatarImage' import { defaultAvatarImage } from '../avatarImage'
@ -19,6 +20,7 @@ interface roomProps {
export default function GameRoom({ params }: roomProps) { export default function GameRoom({ params }: roomProps) {
const [isConnected, setIsConnected] = useState<boolean>(false) const [isConnected, setIsConnected] = useState<boolean>(false)
const [forceUpdate, setForceUpdate] = useState<number>(0) const [forceUpdate, setForceUpdate] = useState<number>(0)
const [socketURL, setSocketURL] = useState<string>("")
const [role, setRole] = useState<string|null>("") const [role, setRole] = useState<string|null>("")
const [name, setName] = useState<string|null>("") const [name, setName] = useState<string|null>("")
@ -45,6 +47,8 @@ export default function GameRoom({ params }: roomProps) {
const duration = 15 const duration = 15
const questionLimit = 10 const questionLimit = 10
getSocketUrl().then((url) => {setSocketURL(url)})
const { id } = params const { id } = params
const roomNameDisplay = id.substring(0,3) + " " + id.substring(3,6) const roomNameDisplay = id.substring(0,3) + " " + id.substring(3,6)
@ -60,11 +64,15 @@ export default function GameRoom({ params }: roomProps) {
setCustomQuestions(localCustomQuestions == null ? [] : localCustomQuestions) setCustomQuestions(localCustomQuestions == null ? [] : localCustomQuestions)
// Listen for incoming setMessages // Listen for incoming setMessages
socketRef.current = io("ws://localhost:3000"); }, []);
useEffect(() => {
if(socketURL != ""){
socketRef.current = io(socketURL);
socketRef.current!.on("connect", () => { socketRef.current!.on("connect", () => {
setIsConnected(true) setIsConnected(true)
socketRef.current!.emit('room_connect', {id: id, name: localName, avatar: localAvatar, browserId: localBrowserId}) socketRef.current!.emit('room_connect', {id: id, name: name, avatar: avatar, browserId: browserId})
}); });
socketRef.current!.on("new_player", (params) => { socketRef.current!.on("new_player", (params) => {
@ -112,7 +120,9 @@ export default function GameRoom({ params }: roomProps) {
return () => { return () => {
socketRef.current!.disconnect(); socketRef.current!.disconnect();
}; };
}, []); }
}, [socketURL])
function forceUpdateFunc(){ function forceUpdateFunc(){
setForceUpdate(fu => fu + 1) setForceUpdate(fu => fu + 1)
@ -130,8 +140,10 @@ export default function GameRoom({ params }: roomProps) {
}) })
forceUpdateFunc() forceUpdateFunc()
}; };
if(socketRef.current != undefined){
socketRef.current!.on("player_choice", eventListener) socketRef.current!.on("player_choice", eventListener)
return () => {socketRef.current!.off("player_choice", eventListener)} return () => {socketRef.current!.off("player_choice", eventListener)}
}
}, [possibleChoice]) }, [possibleChoice])
useEffect(() => { useEffect(() => {
@ -214,6 +226,7 @@ export default function GameRoom({ params }: roomProps) {
function setAndSaveCustomQuestions(data: any){ function setAndSaveCustomQuestions(data: any){
setCustomQuestions(data) setCustomQuestions(data)
localStorage.setItem("customQuestions", JSON.stringify(data)) localStorage.setItem("customQuestions", JSON.stringify(data))
forceUpdateFunc()
} }
return ( return (
@ -244,7 +257,10 @@ export default function GameRoom({ params }: roomProps) {
{ playModes[selectedMode].name == "Custom" && { playModes[selectedMode].name == "Custom" &&
<> <>
<EditCustomQuestions dataRef={editCustomQuestionsRef} questionList={customQuestions} setQuestions={(data: any) => setAndSaveCustomQuestions(data)} /> <EditCustomQuestions dataRef={editCustomQuestionsRef} questionList={customQuestions} setQuestions={(data: any) => setAndSaveCustomQuestions(data)} />
<button className="btn btn-primary" onClick={() => editCustomQuestionsRef.current!.showModal()}>Edit questions...</button> <div className="flex flex-col items-center w-full space-y-4">
<p>You have {customQuestions!.length} custom questions</p>
<button className="btn btn-primary w-full" onClick={() => editCustomQuestionsRef.current!.showModal()}>Edit questions...</button>
</div>
</> </>
} }
</> </>
@ -274,7 +290,7 @@ export default function GameRoom({ params }: roomProps) {
})} })}
</div> </div>
{ role == "owner" && { role == "owner" &&
<button className="btn btn-primary" onClick={startGame}>Start game</button> <button className="btn btn-primary" onClick={startGame} disabled={players!.length <= 1 || (customQuestions!.length == 0 && playModes[selectedMode].name == "Custom")}>Start game</button>
} }
</div> </div>
} }
@ -325,7 +341,7 @@ export default function GameRoom({ params }: roomProps) {
</div> </div>
)})} )})}
</div> </div>
{ (questionDisplayed.type == "photo" && possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].browserId == browserId) && { (questionDisplayed!.type == "photo" && possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].browserId == browserId) &&
<> <>
{ questionReply.photo == undefined && { questionReply.photo == undefined &&
<div className="flex flex-col items-center space-y-4"> <div className="flex flex-col items-center space-y-4">
@ -345,7 +361,7 @@ export default function GameRoom({ params }: roomProps) {
} }
</> </>
} }
{ (questionDisplayed.type == "photo" && possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].browserId != browserId) && { (questionDisplayed!.type == "photo" && possibleChoice.sort((a,b) => b.nbrVotes - a.nbrVotes)[0].browserId != browserId) &&
<> <>
{ questionReply.photo == undefined && { questionReply.photo == undefined &&
<div> <div>

11
app/[id]/socket.ts Normal file
View file

@ -0,0 +1,11 @@
'use server'
export default async function getSocketUrl() {
const ssl = process.env.USE_SSL == undefined ? false : process.env.USE_SSL
const url = process.env.URL == undefined ? "localhost:3000" : process.env.URL
const protocol = ssl ? "wss://" : "ws://"
console.log(protocol + url)
return protocol + url
}

View file

@ -5,6 +5,7 @@ import { useState, useEffect, useRef } from 'react'
import { IconPencilMinus, IconDice6 } from "@tabler/icons-react" import { IconPencilMinus, IconDice6 } from "@tabler/icons-react"
import { defaultAvatarImage } from './avatarImage' import { defaultAvatarImage } from './avatarImage'
import { getUsername } from './usernameGenerate' import { getUsername } from './usernameGenerate'
import { redirect, useRouter } from 'next/navigation'
import { resizeBase64Image, getBase64OfImage } from './utils' import { resizeBase64Image, getBase64OfImage } from './utils'
import WebcamPhoto from '@/components/webcamPhoto' import WebcamPhoto from '@/components/webcamPhoto'
@ -17,6 +18,7 @@ export default function Home() {
const modal = useRef<any>() const modal = useRef<any>()
const inputName = useRef<any>() const inputName = useRef<any>()
const inputProfilePicRef = useRef<any>() const inputProfilePicRef = useRef<any>()
const { push } = useRouter()
function setUsername() { function setUsername() {
setName(inputName.current!.value) setName(inputName.current!.value)
@ -43,6 +45,16 @@ export default function Home() {
setShowWebcam(false) setShowWebcam(false)
} }
function moveToRandomRoom(){
let roomNumber = ""
for(let i = 0; i < 6; i++) {
roomNumber += Math.floor(Math.random() * 9.99)
}
console.log("Hello")
push('/' + roomNumber.toString())
//redirect('/' + roomNumber.toString())
}
useEffect(() => { useEffect(() => {
let localName = localStorage.getItem("name") let localName = localStorage.getItem("name")
let localAvatar = localStorage.getItem("avatar") let localAvatar = localStorage.getItem("avatar")
@ -119,7 +131,7 @@ export default function Home() {
</div> </div>
</div> </div>
<div className="flex flex-col space-y-4 items-center"> <div className="flex flex-col space-y-4 items-center">
<a href="/random" className="btn btn-primary">Create a room</a> <button onClick={moveToRandomRoom} className="btn btn-primary">Create a room</button>
<div className="divider"></div> <div className="divider"></div>
<form action={navigate} className="flex flex-col space-y-4"> <form action={navigate} className="flex flex-col space-y-4">
<input type="text" name="id" placeholder="Room pin" className="input input-bordered w-full max-w-xs" /> <input type="text" name="id" placeholder="Room pin" className="input input-bordered w-full max-w-xs" />

View file

@ -1,9 +0,0 @@
import { redirect } from 'next/navigation'
export default function Home() {
let roomNumber = ""
for(let i = 0; i < 6; i++) {
roomNumber += Math.floor(Math.random() * 9.99)
}
redirect('/' + roomNumber.toString())
}

View file

@ -52,18 +52,30 @@ app.prepare().then(() => {
console.log("User connected " + socket.id) console.log("User connected " + socket.id)
socket.on('room_connect', (params) => { socket.on('room_connect', (params) => {
// IF ROOM DOESN'T EXISTS
if(!Object.keys(active_rooms).includes(params.id)){ if(!Object.keys(active_rooms).includes(params.id)){
console.log("First person joined " + params.id + " ! " + params.name + " is owner.") console.log("First person joined " + params.id + " ! " + params.name + " is owner.")
active_rooms[params.id] = { users: [{id: socket.id, name: params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "owner", vote: ""}]} active_rooms[params.id] = { gameStarted: false, users: [{id: socket.id, name: params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "owner", vote: ""}]}
socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: "owner"}) socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: "owner"})
} else { }
// IF ROOM EXISTS
else {
let userIndexByBrowserId = findUserByBrowserId(params.id, params.browserId) let userIndexByBrowserId = findUserByBrowserId(params.id, params.browserId)
// IF USER ALREADY CONNECTED
if(userIndexByBrowserId != null) { if(userIndexByBrowserId != null) {
active_rooms[params.id].users[userIndexByBrowserId].connected = true active_rooms[params.id].users[userIndexByBrowserId].connected = true
active_rooms[params.id].users[userIndexByBrowserId].id = socket.id active_rooms[params.id].users[userIndexByBrowserId].id = socket.id
socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: active_rooms[params.id].users[userIndexByBrowserId].role}) socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: active_rooms[params.id].users[userIndexByBrowserId].role})
if(active_rooms[params.id].gameStarted){
socket.emit("start_game",{possibleChoice: active_rooms[params.id].possibleChoice, question: active_rooms[params.id].question, questionNbr: active_rooms[params.id].questionNbr, duration: 15}) socket.emit("start_game",{possibleChoice: active_rooms[params.id].possibleChoice, question: active_rooms[params.id].question, questionNbr: active_rooms[params.id].questionNbr, duration: 15})
} else { }
}
// IF USER DIDN'T CONNECT ONCE
else {
socket.to(params.id).emit("new_player",{"id": socket.id, "name": params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "player"}) socket.to(params.id).emit("new_player",{"id": socket.id, "name": params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "player"})
active_rooms[params.id].users.push({id: socket.id, name: params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "player", vote: ""}) active_rooms[params.id].users.push({id: socket.id, name: params.name, avatar: params.avatar, browserId: params.browserId, connected: true, role: "player", vote: ""})
socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: "player"}) socket.emit("room_joined", {"room_users": active_rooms[params.id].users, role: "player"})
@ -78,6 +90,7 @@ app.prepare().then(() => {
active_rooms[params.roomId].questionNbr = 1 active_rooms[params.roomId].questionNbr = 1
active_rooms[params.roomId].possibleChoice = params.possibleChoice active_rooms[params.roomId].possibleChoice = params.possibleChoice
active_rooms[params.roomId].duration = params.duration active_rooms[params.roomId].duration = params.duration
active_rooms[params.roomId].gameStarted = true
socket.to(params.roomId).emit("start_game",{possibleChoice: params.possibleChoice, question: params.question, questionNbr: 1, duration: params.duration}) socket.to(params.roomId).emit("start_game",{possibleChoice: params.possibleChoice, question: params.question, questionNbr: 1, duration: params.duration})
}) })