First commit
This commit is contained in:
commit
48866cc6ab
20 changed files with 6301 additions and 0 deletions
7
app/[id]/forceUpdate.tsx
Normal file
7
app/[id]/forceUpdate.tsx
Normal file
|
@ -0,0 +1,7 @@
|
|||
'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
|
||||
}
|
274
app/[id]/page.tsx
Normal file
274
app/[id]/page.tsx
Normal file
|
@ -0,0 +1,274 @@
|
|||
'use client'
|
||||
import { useState, useEffect, useRef } from 'react'
|
||||
import { io } from "socket.io-client"
|
||||
import { getRandomQuestion } from "./questions"
|
||||
import { useForceUpdate } from "./forceUpdate"
|
||||
import { IconCrown } from "@tabler/icons-react"
|
||||
|
||||
interface roomProps {
|
||||
params: {
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default function Home({ params }: roomProps) {
|
||||
const [isConnected, setIsConnected] = useState(false)
|
||||
const [forceUpdate, setForceUpdate] = useState(0)
|
||||
|
||||
const [role, setRole] = useState("")
|
||||
const [name, setName] = useState("")
|
||||
|
||||
const [gameStarted, setGameStarted] = useState(false)
|
||||
const [gameEnded, setGameEnded] = useState(false)
|
||||
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 socketRef = useRef()
|
||||
const duration = 15
|
||||
const questionLimit = 10
|
||||
|
||||
const { id } = params
|
||||
const roomNameDisplay = id.substring(0,3) + " " + id.substring(3,6)
|
||||
|
||||
useEffect(() => {
|
||||
const username = localStorage.getItem('name')
|
||||
setName(username)
|
||||
// Listen for incoming setMessages
|
||||
socketRef.current = io("ws://localhost:3000");
|
||||
|
||||
socketRef.current.on("connect", () => {
|
||||
setIsConnected(true)
|
||||
socketRef.current.emit('room_connect', {"id": id, "name": username})
|
||||
});
|
||||
|
||||
socketRef.current.on("new_player", (params) => {
|
||||
setPlayers(oldPlayers => [...oldPlayers, params])
|
||||
})
|
||||
|
||||
socketRef.current.on("start_game", (params) => {
|
||||
setQuestionNbr(oldQ => oldQ + 1)
|
||||
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("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) => {
|
||||
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()
|
||||
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(questionAlreadyDone)
|
||||
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) {
|
||||
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})
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center space-y-16 p-4">
|
||||
{ !gameStarted &&
|
||||
<>
|
||||
<div className="flex flex-col">
|
||||
<h1 className="text-3xl">{roomNameDisplay}</h1>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-4">
|
||||
{ !isConnected &&
|
||||
<p>Connecting to room...</p>
|
||||
}
|
||||
{ (isConnected && players.length == 0) &&
|
||||
<p>Waiting for players to join...</p>
|
||||
}
|
||||
{ (isConnected && players.length > 0) &&
|
||||
<div className="flex flex-col space-y-16">
|
||||
<div>
|
||||
{ players.map((player) => {
|
||||
console.log(player)
|
||||
if(player.role == "player") {
|
||||
return (
|
||||
<p>{player.name}</p>
|
||||
)
|
||||
}
|
||||
if(player.role == "owner") {
|
||||
return (
|
||||
<p className="flex flex-row">{player.name}<IconCrown /></p>
|
||||
)
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
{ role == "owner" &&
|
||||
<button className="btn btn-primary" onClick={startGame}>Start game</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
{ gameStarted &&
|
||||
<>
|
||||
<div className="flex flex-col space-y-4 items-center">
|
||||
<h1 className="text-3xl">{questionDisplayed}</h1>
|
||||
<span className="indicator-item badge indicator-bottom indicator-center opacity-30">{questionNbr}/{questionLimit}</span>
|
||||
</div>
|
||||
{ countdown > 0 &&
|
||||
<>
|
||||
<span className="countdown">
|
||||
<span style={{"--value":countdown.toString()}}></span>
|
||||
</span>
|
||||
<div className="flex flex-row space-x-4">
|
||||
{ choice == "" &&
|
||||
<>
|
||||
{ possibleChoice.map((playerChoice) => (
|
||||
<button className="btn btn-primary" disabled={choice != ""} onClick={() => {setAndSendChoice(playerChoice.name)}}>{playerChoice.name}</button>
|
||||
))}
|
||||
</>
|
||||
}
|
||||
{ choice != "" &&
|
||||
<span>Waiting <span className="loading loading-dots loading-xs"></span></span>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
{ countdown == 0 &&
|
||||
<>
|
||||
<div className="flex flex-row space-x-4">
|
||||
{ possibleChoice.map((playerChoice) => {
|
||||
console.log(totalVotes)
|
||||
console.log(playerChoice.nbrVotes / totalVotes)
|
||||
let percent = Math.floor((playerChoice.nbrVotes / totalVotes) * 100)
|
||||
return (
|
||||
<div className="flex items-center space-y-4 flex-col">
|
||||
<div className="radial-progress text-primary" style={{ "--value": percent }} role="progressbar">
|
||||
{percent}%
|
||||
</div>
|
||||
<h1>{playerChoice.name}</h1>
|
||||
</div>
|
||||
)})}
|
||||
</div>
|
||||
{ (role == "owner" && questionNbr < questionLimit) &&
|
||||
<button className="btn btn-primary" onClick={nextQuestion}>Next question</button>
|
||||
}
|
||||
{ (role == "owner" && questionNbr == questionLimit) &&
|
||||
<button className="btn btn-primary" onClick={resetGame}>Replay</button>
|
||||
}
|
||||
</>
|
||||
}
|
||||
</>
|
||||
}
|
||||
</main>
|
||||
);
|
||||
}
|
107
app/[id]/questions.ts
Normal file
107
app/[id]/questions.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
export const questions = [
|
||||
//"Qui organiserait le mieux des vacances ?",
|
||||
//"Qui serait plus susceptible de vivre à Paris",
|
||||
//"Qui est le/la plus gourmand·e ?",
|
||||
//"Qui a vote le plus à droite ?",
|
||||
//"Qui cuisine le mieux ?",
|
||||
//"Qui pourrait passer son temps à dormir ?",
|
||||
//"Qui est la plus petite tasse ?",
|
||||
//"Qui est le/la plus sportif·ve ?",
|
||||
//"Qui a le meilleur sens de l'humour ?",
|
||||
//"Qui est le/la plus ponctuel·le ?",
|
||||
//"Qui est le/la plus aventureux·se ?",
|
||||
//"Qui cuisine le mieux ?",
|
||||
//"Qui a le plus de connaissances en musique ?",
|
||||
//"Qui est le/la plus artistique ?",
|
||||
//"Qui est le/la plus sociable ?",
|
||||
//"Qui est le/la plus compétitif·ve ?",
|
||||
//"Qui est le/la plus susceptible de devenir célèbre ?",
|
||||
//"Qui est le/la plus généreux·se ?",
|
||||
//"Qui a le plus de chances de voyager dans l'espace ?",
|
||||
//"Qui a les meilleures compétences en survie ?",
|
||||
//"Qui a le plus d'animaux de compagnie ?",
|
||||
//"Qui est le/la plus organisé·e ?",
|
||||
//"Qui est le/la plus romantique ?",
|
||||
//"Qui est le/la plus économe ?",
|
||||
//"Qui a le plus de style vestimentaire ?",
|
||||
//"Qui est le/la plus fêtard·e ?",
|
||||
//"Qui a le plus de talents cachés ?",
|
||||
//"Qui est le/la plus technophile ?",
|
||||
//"Qui est le/la plus écolo ?",
|
||||
//"Qui est le/la plus doué·e pour les langues étrangères ?",
|
||||
//"Qui a le plus de chances de gagner un marathon ?",
|
||||
//"Qui est le/la plus passionné·e de lecture ?",
|
||||
//"Qui est le/la plus doué·e pour le bricolage ?",
|
||||
//"Qui est le/la plus susceptible de réussir en affaires ?",
|
||||
//"Qui a le plus de connaissances en cinéma ?",
|
||||
//"Qui est le/la plus spirituel·le ?",
|
||||
//"Qui est le/la plus susceptible de vivre à l'étranger ?",
|
||||
//"Qui est le/la plus drôle ?",
|
||||
//"Qui est le/la plus susceptible de participer à une émission de télé-réalité ?",
|
||||
//"Qui a le plus de patience ?",
|
||||
//"Qui est le/la plus passionné·e de jeux vidéo ?",
|
||||
//"Qui est le/la plus susceptible de devenir un·e chef·fe renommé·e ?",
|
||||
//"Qui est le/la plus doué·e pour les jeux de société ?",
|
||||
//"Qui a le plus de connaissances historiques ?",
|
||||
//"Qui est le/la plus passionné·e de jardinage ?",
|
||||
//"Qui a les meilleurs talents d'acteur·rice ?",
|
||||
"Qui va sauter dans la piscine ?",
|
||||
"Qui date le plus âgé ?",
|
||||
"Qui est le plus flexible avec démonstration ?",
|
||||
"Qui va faire un striptease ?",
|
||||
"Qui sera la pire parent ?",
|
||||
"Qui est le plus alcoolique ?",
|
||||
"Qui serait capable de chier dans la seine ?",
|
||||
"Qui va montrer son dernier message envoyé ?",
|
||||
"Qui va faire une roulette de photos ?",
|
||||
"Qui a déjà bouffé les deux boules d'un mec ?",
|
||||
"Qui va nous décrire son crush ?",
|
||||
"Qui est le plus addict ?",
|
||||
"Qui est le plus croquant ?",
|
||||
"Qui s'auto-suce le plus ?",
|
||||
"Qui va prendre une fessée avec la tongue de l'archi Vergnaud ?",
|
||||
"Qui est le plus à droite ?",
|
||||
"Qui conduit le mieux ?",
|
||||
"Qui gagne au bras de fer ? (Preuve)",
|
||||
"Qui va faire une roulade ?",
|
||||
"Qui a le plus une tête de con•ne ?",
|
||||
"Qui est le meilleur menteur ?",
|
||||
"Qui rikou ?",
|
||||
"Qui va boire un shot d'huile ?",
|
||||
"Qui va manger une cuillère a soupe de mayonnaise ?",
|
||||
"Qui va choisir ce que l'autre va manger ?",
|
||||
"Qui va nous organiser les prochaines vacances ?",
|
||||
"Qui a la plus belle fesse ?",
|
||||
"Qui est le plus intrusif ?",
|
||||
"Qui a le plus haut bodycount ?",
|
||||
"Qui va imiter Nicolas Pham ?",
|
||||
"Qui va dire vinaigrette sans Vi ?",
|
||||
"Qui va faire son âge divisé par deux en pompes ?",
|
||||
"Qui va faire l'intro pour le dernier tiktok ?",
|
||||
"Qui va faire une photo sexy avec son voisin de droite ?",
|
||||
"Qui va brouter de l'herbe ?",
|
||||
"Qui va boire un Ricard piscine ?",
|
||||
"Qui est susceptible de se marier ?",
|
||||
"À qui donneriez vous vos enfants ?",
|
||||
"Qui serait le meilleur DDP ?",
|
||||
"À qui tu te confierais le plus ?",
|
||||
"Qui est le plus béru ?",
|
||||
"Qui est le plus kinky ?",
|
||||
"Qui va nous chanter le menu ?",
|
||||
"Qui lance un monôme tout nu ?",
|
||||
"Qui est le plus rapide ?",
|
||||
"Qui est le plus susceptible d'être célèbre ?",
|
||||
"Qui est le plus romantique ?",
|
||||
"Qui va raconter la chose la plus folle de sa vie ?",
|
||||
"Qui se masturbe le plus ?",
|
||||
"Qui est le plus gros fan de star wars ?",
|
||||
"Qui a pleuré en dernier ?",
|
||||
]
|
||||
|
||||
export function getRandomQuestion(alreadyDone = []){
|
||||
let questionIndex = Math.floor(Math.random() * questions.length)
|
||||
while(alreadyDone.includes(questionIndex)){
|
||||
questionIndex = Math.floor(Math.random() * questions.length)
|
||||
}
|
||||
return {alreadyDone: [...alreadyDone, questionIndex], question: questions[questionIndex]}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue