diff --git a/app/[id]/page.tsx b/app/[id]/page.tsx index 2384c88..bafc567 100644 --- a/app/[id]/page.tsx +++ b/app/[id]/page.tsx @@ -1,11 +1,12 @@ 'use client' import { useState, useEffect, useRef } from 'react' import { io } from "socket.io-client" -import { getRandomQuestion } from "./questions" -import { useForceUpdate } from "./forceUpdate" +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' interface roomProps { @@ -14,7 +15,7 @@ interface roomProps { }; } -export default function Home({ params }: roomProps) { +export default function GameRoom({ params }: roomProps) { const [isConnected, setIsConnected] = useState(false) const [forceUpdate, setForceUpdate] = useState(0) @@ -34,11 +35,12 @@ export default function Home({ params }: roomProps) { 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() const inputPhotoRef = useRef() - const photoModalRef = useRef() - const webcamRef = useRef() + const editCustomQuestionsRef = useRef() const duration = 15 const questionLimit = 10 @@ -52,6 +54,9 @@ export default function Home({ params }: roomProps) { setAvatar(localAvatar) const localBrowserId = localStorage.getItem("browserId") setBrowserId(localBrowserId) + const localCustomQuestions = JSON.parse(localStorage.getItem("customQuestions")) + console.log(localCustomQuestions) + setCustomQuestions(localCustomQuestions == null ? [] : localCustomQuestions) // Listen for incoming setMessages socketRef.current = io("ws://localhost:3000"); @@ -149,7 +154,7 @@ export default function Home({ params }: roomProps) { function startGame() { let possibleChoice = getPossibleChoice() - let questionObj = getRandomQuestion() + 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}) @@ -162,7 +167,7 @@ export default function Home({ params }: roomProps) { function nextQuestion() { let possibleChoice = getPossibleChoice() - let questionObj = getRandomQuestion(questionAlreadyDone) + 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}) @@ -198,71 +203,82 @@ export default function Home({ params }: roomProps) { socketRef.current.emit("player_choice", {roomId: id, choice: playerName, player: name}) } - function setAndSendPhoto(mode){ - console.log(mode) - if(mode == "webcam"){ - const imageSrc = webcamRef.current.getScreenshot() - resizeBase64Image(imageSrc).then((data) => { - setQuestionReply({photo: data}) - socketRef.current.emit("question_reply", { roomId: id, data:{photo: data}}) - }) - } - if(mode == "file"){ - getBase64OfImage(inputPhotoRef.current.files[0], (data) => resizeBase64Image(data).then((data) =>{ - setQuestionReply({photo: data}) - socketRef.current.emit("question_reply", { roomId: id, data:{photo: data}}) - })) - } + function setAndSendPhoto(){ + getBase64OfImage(inputPhotoRef.current.files[0], (data) => resizeBase64Image(data).then((data) =>{ + setQuestionReply({photo: data}) + socketRef.current.emit("question_reply", { roomId: id, data:{photo: data}}) + })) + } + + function setAndSaveCustomQuestions(data){ + setCustomQuestions(data) + localStorage.setItem("customQuestions", JSON.stringify(data)) } return ( -
- -
- -
-
- {/* if there is a button, it will close the modal */} - -
-
-
-
+
{ !gameStarted && <>
-

{roomNameDisplay}

+

{roomNameDisplay}

-
+
{ !isConnected &&

Connecting to room...

} - { (isConnected && players.length == 0) && -

Waiting for players to join...

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

{player.name}

-
- - ) - })} + { isConnected && + <> + { role == "owner" && + <> +
+

Choose game mode

+
+ { playModes.map((mode, index) => { + return( + setSelectedMode(index)} selected={selectedMode === index} /> + ) + })} +
- { role == "owner" && - + { 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" && + + } +
+ }
+ }
@@ -313,10 +329,9 @@ export default function Home({ params }: roomProps) { { questionReply.photo == undefined &&
À toi d'envoyer une photo ! - setAndSendPhoto("file")} className="hidden" /> +
-
} diff --git a/app/[id]/questions.ts b/app/[id]/questions.ts index f0caf0f..5793313 100644 --- a/app/[id]/questions.ts +++ b/app/[id]/questions.ts @@ -1,107 +1,120 @@ -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 ?", +import { IconCrown, IconWind, IconPencil } from "@tabler/icons-react" + +const questionsClassic = [ + { text: "Qui organiserait le mieux des vacances ?", type: "text"}, + { text: "Qui serait plus susceptible de vivre à Paris", type: "text"}, + { text: "Qui est le/la plus gourmand·e ?", type: "text"}, + { text: "Qui a vote le plus à droite ?", type: "text"}, + { text: "Qui cuisine le mieux ?", type: "text"}, + { text: "Qui pourrait passer son temps à dormir ?", type: "text"}, + { text: "Qui est la plus petite tasse ?", type: "text"}, + { text: "Qui est le/la plus sportif·ve ?", type: "text"}, + { text: "Qui a le meilleur sens de l'humour ?", type: "text"}, + { text: "Qui est le/la plus ponctuel·le ?", type: "text"}, + { text: "Qui est le/la plus aventureux·se ?", type: "text"}, + { text: "Qui cuisine le mieux ?", type: "text"}, + { text: "Qui a le plus de connaissances en musique ?", type: "text"}, + { text: "Qui est le/la plus artistique ?", type: "text"}, + { text: "Qui est le/la plus sociable ?", type: "text"}, + { text: "Qui est le/la plus compétitif·ve ?", type: "text"}, + { text: "Qui est le/la plus susceptible de devenir célèbre ?", type: "text"}, + { text: "Qui est le/la plus généreux·se ?", type: "text"}, + { text: "Qui a le plus de chances de voyager dans l'espace ?", type: "text"}, + { text: "Qui a les meilleures compétences en survie ?", type: "text"}, + { text: "Qui a le plus d'animaux de compagnie ?", type: "text"}, + { text: "Qui est le/la plus organisé·e ?", type: "text"}, + { text: "Qui est le/la plus romantique ?", type: "text"}, + { text: "Qui est le/la plus économe ?", type: "text"}, + { text: "Qui a le plus de style vestimentaire ?", type: "text"}, + { text: "Qui est le/la plus fêtard·e ?", type: "text"}, + { text: "Qui a le plus de talents cachés ?", type: "text"}, + { text: "Qui est le/la plus technophile ?", type: "text"}, + { text: "Qui est le/la plus écolo ?", type: "text"}, + { text: "Qui est le/la plus doué·e pour les langues étrangères ?", type: "text"}, + { text: "Qui a le plus de chances de gagner un marathon ?", type: "text"}, + { text: "Qui est le/la plus passionné·e de lecture ?", type: "text"}, + { text: "Qui est le/la plus doué·e pour le bricolage ?", type: "text"}, + { text: "Qui est le/la plus susceptible de réussir en affaires ?", type: "text"}, + { text: "Qui a le plus de connaissances en cinéma ?", type: "text"}, + { text: "Qui est le/la plus spirituel·le ?", type: "text"}, + { text: "Qui est le/la plus susceptible de vivre à l'étranger ?", type: "text"}, + { text: "Qui est le/la plus drôle ?", type: "text"}, + { text: "Qui est le/la plus susceptible de participer à une émission de télé-réalité ?", type: "text"}, + { text: "Qui a le plus de patience ?", type: "text"}, + { text: "Qui est le/la plus passionné·e de jeux vidéo ?", type: "text"}, + { text: "Qui est le/la plus susceptible de devenir un·e chef·fe renommé·e ?", type: "text"}, + { text: "Qui est le/la plus doué·e pour les jeux de société ?", type: "text"}, + { text: "Qui a le plus de connaissances historiques ?", type: "text"}, + { text: "Qui est le/la plus passionné·e de jardinage ?", type: "text"}, + { text: "Qui a les meilleurs talents d'acteur·rice ?", type: "text"}, +] + +const questionsLeVent = [ { text: "Qui va sauter dans la piscine ?", type: "text"}, { text: "Qui date le plus âgé ?", type: "text"}, - { text: "Qui est le plus flexible avec démonstration ?", type: "text"}, + { text: "Qui est le/la plus flexible avec démonstration ?", type: "text"}, { text: "Qui va faire un striptease ?", type:"text"}, - { text: "Qui sera la pire parent ?", type:"text"}, - { text: "Qui est le plus alcoolique ?", type:"text"}, + { text: "Qui sera la/le pire parent ?", type:"text"}, + { text: "Qui est le/la plus alcoolique ?", type:"text"}, { text: "Qui serait capable de chier dans la seine ?", type:"text"}, - { text: "Qui va montrer son dernier message envoyé ?", type:"text"}, + { text: "Qui va montrer son dernier message envoyé ?", type:"photo"}, { text: "Qui va faire une roulette de photos ?", type:"text"}, { text: "Qui a déjà bouffé les deux boules d'un mec ?", type:"text"}, { text: "Qui va nous décrire son crush ?", type: "text"}, - { text: "Qui est le plus addict ?", type: "text"}, - { text: "Qui est le plus croquant ?", type: "text"}, + { text: "Qui est la/le plus addict ?", type: "text"}, + { text: "Qui est le/la plus croquant·e ?", type: "text"}, { text: "Qui s'auto-suce le plus ?", type: "text"}, { text: "Qui va prendre une fessée avec la tongue de l'archi Vergnaud ?", type: "text"}, - { text: "Qui est le plus à droite ?", type: "text"}, + { text: "Qui est le/la plus à droite ?", type: "text"}, { text: "Qui conduit le mieux ?", type: "text"}, { text: "Qui gagne au bras de fer ? (Preuve)", type: "text"}, { text: "Qui va faire une roulade ?", type: "text"}, - { text: "Qui a le plus une tête de con•ne ?", type: "text"}, - { text: "Qui est le meilleur menteur ?", type: "text"}, + { text: "Qui est le/la meilleur·e menteur·euse ?", type: "text"}, { text: "Qui rikou ?", type: "text"}, { text: "Qui va boire un shot d'huile ?", type: "text"}, { text: "Qui va manger une cuillère a soupe de mayonnaise ?", type: "text"}, { text: "Qui va choisir ce que l'autre va manger ?", type: "text"}, { text: "Qui va nous organiser les prochaines vacances ?", type: "text"}, { text: "Qui a la plus belle fesse ?", type: "text"}, - { text: "Qui est le plus intrusif ?", type: "text"}, { text: "Qui a le plus haut bodycount ?", type: "text"}, { text: "Qui va imiter Nicolas Pham ?", type: "text"}, { text: "Qui va dire vinaigrette sans Vi ?", type: "text"}, { text: "Qui va faire son âge divisé par deux en pompes ?", type: "text"}, { text: "Qui va faire l'intro pour le dernier tiktok ?", type: "text"}, - { text: "Qui va faire une photo sexy avec son voisin de droite ?", type: "photo"}, + { text: "Qui va faire une photo sexy avec son/sa voisin·e de droite ?", type: "photo"}, { text: "Qui va brouter de l'herbe ?", type: "text"}, { text: "Qui va boire un Ricard piscine ?", type: "text"}, { text: "Qui est susceptible de se marier ?", type: "text"}, { text: "À qui donneriez vous vos enfants ?", type: "text"}, - { text: "Qui serait le meilleur DDP ?", type: "text"}, + { text: "Qui serait le/la meilleur·e DDP ?", type: "text"}, { text: "À qui tu te confierais le plus ?", type: "text"}, - { text: "Qui est le plus béru ?", type: "text"}, - { text: "Qui est le plus kinky ?", type: "text"}, + { text: "Qui est le/la plus béru·e ?", type: "text"}, + { text: "Qui est le/la plus kinky ?", type: "text"}, { text: "Qui va nous chanter le menu ?", type: "text"}, { text: "Qui lance un monôme tout nu ?", type: "text"}, - { text: "Qui est le plus rapide ?", type: "text"}, - { text: "Qui est le plus susceptible d'être célèbre ?", type: "text"}, - { text: "Qui est le plus romantique ?", type: "text"}, + { text: "Qui est le/la plus rapide ?", type: "text"}, + { text: "Qui est le/la plus susceptible d'être célèbre ?", type: "text"}, + { text: "Qui est le/la plus romantique ?", type: "text"}, { text: "Qui va raconter la chose la plus folle de sa vie ?", type: "text"}, { text: "Qui se masturbe le plus ?", type: "text"}, - { text: "Qui est le plus gros fan de star wars ?", type: "text"}, + { text: "Qui est le/la plus gros·se fan de star wars ?", type: "text"}, { text: "Qui a pleuré en dernier ?", type: "text"}, ] -export function getRandomQuestion(alreadyDone = []){ - let questionIndex = Math.floor(Math.random() * questions.length) - while(alreadyDone.includes(questionIndex)){ - questionIndex = Math.floor(Math.random() * questions.length) +export const playModes = [ + { name: "Classic", icon: IconCrown, questions: questionsClassic }, + { name: "Le vent", icon: IconWind, questions: questionsLeVent}, + { name: "Custom", icon: IconPencil, questions: []}, +] + +export function getRandomQuestion(mode, alreadyDone = [], customQuestions){ + let questionList = mode.questions + if(mode.name == "Custom") { + questionList = customQuestions } - return {alreadyDone: [...alreadyDone, questionIndex], question: questions[questionIndex]} + let questionIndex = Math.floor(Math.random() * questionList.length) + while(alreadyDone.includes(questionIndex)){ + questionIndex = Math.floor(Math.random() * questionList.length) + } + return {alreadyDone: [...alreadyDone, questionIndex], question: questionList[questionIndex]} } diff --git a/app/layout.tsx b/app/layout.tsx index 3314e47..602dd4c 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -5,8 +5,8 @@ import "./globals.css"; const inter = Inter({ subsets: ["latin"] }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "✨ Tapage ✨", + description: "Created by Lucien", }; export default function RootLayout({ @@ -15,7 +15,7 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - + {children} ); diff --git a/app/page.tsx b/app/page.tsx index 2f464c9..6823a1a 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -16,6 +16,7 @@ export default function Home() { const webcamRef = useRef() const modal = useRef() const inputName = useRef() + const inputProfilePicRef = useRef() function setUsername() { setName(inputName.current.value) @@ -65,7 +66,7 @@ export default function Home() { }, []) return ( -
+
@@ -79,10 +80,11 @@ export default function Home() { } { !showWebcam && - <> +
- {getBase64OfImage(e.target.files[0], (data) => setAndStoreAvatar(data))}} className="file-input w-full max-w-xs"/> - + + {getBase64OfImage(e.target.files[0], (data) => setAndStoreAvatar(data))}} className="hidden"/> +
}
-

Bazaar

+

✨ Tapage ✨

diff --git a/components/editCustomQuestions.tsx b/components/editCustomQuestions.tsx new file mode 100644 index 0000000..49ba763 --- /dev/null +++ b/components/editCustomQuestions.tsx @@ -0,0 +1,47 @@ +import { useState } from 'react' +import { IconSquareX } from '@tabler/icons-react' + +export default function EditCustomQuestions({dataRef, questionList = [], setQuestions}){ + let questionTemp = questionList + console.log(questionTemp) + const [forceUpdate, setForceUpdate] = useState(0) + + function addQuestion(){ + questionTemp.push({text: "", type:"text"}) + setForceUpdate(oldFu => oldFu + 1) + } + + function removeQuestion(index){ + questionTemp.splice(index, 1) + setForceUpdate(oldFu => oldFu + 1) + } + + return <> + +
+

Edit custom questions!

+
+ { questionTemp.map((question, index) => { + return( +
+ {questionTemp[index].text = e.target.value}}/> + + removeQuestion(index)} className="w-12 h-12"/> +
+ ) + })} +
+ +
+
+ {/* if there is a button in form, it will close the modal */} + +
+
+
+
+ +} diff --git a/components/modeCard.tsx b/components/modeCard.tsx new file mode 100644 index 0000000..b78e72e --- /dev/null +++ b/components/modeCard.tsx @@ -0,0 +1,9 @@ +export default function ModeCard({ mode, selected, onChange }){ + const Icon = mode.icon + return <> +
+ +

{mode.name}

+
+ +}