From fe67f020eb71e2c6a695a1247232c12db1c71ed2 Mon Sep 17 00:00:00 2001 From: "C. Fuhrman" Date: Sun, 9 Mar 2025 00:54:21 -0500 Subject: [PATCH] =?UTF-8?q?[BUG]=20=C3=A9tudiant=20qui=20se=20joint=20?= =?UTF-8?q?=C3=A0=20une=20salle=20apr=C3=A8s=20le=20d=C3=A9marrage=20du=20?= =?UTF-8?q?quiz=20est=20bloqu=C3=A9=20Fixes=20#283=20Valeurs=20de=20l'?= =?UTF-8?q?=C3=A9tat=20de=20la=20page=20(quizStarted)=20n'ont=20pas=20leur?= =?UTF-8?q?=20valeur=20actuelle=20dans=20un=20on().=20Alors,=20on=20d?= =?UTF-8?q?=C3=A9place=20la=20logique=20du=20traitement=20du=20nouvel=20?= =?UTF-8?q?=C3=A9tudiant=20dans=20un=20useEffect=20et=20on=20provoque=20le?= =?UTF-8?q?=20useEffect=20dans=20le=20on()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/Student/JoinRoom/JoinRoom.tsx | 5 +- .../pages/Teacher/ManageRoom/ManageRoom.tsx | 69 +++++++++++++------ 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/client/src/pages/Student/JoinRoom/JoinRoom.tsx b/client/src/pages/Student/JoinRoom/JoinRoom.tsx index dc7e80c..96d1241 100644 --- a/client/src/pages/Student/JoinRoom/JoinRoom.tsx +++ b/client/src/pages/Student/JoinRoom/JoinRoom.tsx @@ -39,9 +39,8 @@ const JoinRoom: React.FC = () => { }, []); useEffect(() => { - // init the answers array, one for each question - setAnswers(Array(questions.length).fill({} as AnswerSubmissionToBackendType)); console.log(`JoinRoom: useEffect: questions: ${JSON.stringify(questions)}`); + setAnswers(questions ? Array(questions.length).fill({} as AnswerSubmissionToBackendType) : []); }, [questions]); @@ -64,6 +63,7 @@ const JoinRoom: React.FC = () => { console.log('on(launch-teacher-mode): Received launch-teacher-mode:', questions); setQuizMode('teacher'); setIsWaitingForTeacher(true); + setQuestions([]); // clear out from last time (in case quiz is repeated) setQuestions(questions); // wait for next-question }); @@ -72,6 +72,7 @@ const JoinRoom: React.FC = () => { setQuizMode('student'); setIsWaitingForTeacher(false); + setQuestions([]); // clear out from last time (in case quiz is repeated) setQuestions(questions); setQuestion(questions[0]); }); diff --git a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx index bcdc80d..f9d3791 100644 --- a/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx +++ b/client/src/pages/Teacher/ManageRoom/ManageRoom.tsx @@ -36,8 +36,40 @@ const ManageRoom: React.FC = () => { const [quizMode, setQuizMode] = useState<'teacher' | 'student'>('teacher'); const [connectingError, setConnectingError] = useState(''); const [currentQuestion, setCurrentQuestion] = useState(undefined); - const [quizStarted, setQuizStarted] = useState(false); + const [quizStarted, setQuizStarted] = useState(false); const [formattedRoomName, setFormattedRoomName] = useState(""); + const [newlyConnectedUser, setNewlyConnectedUser] = useState(null); + + // Handle the newly connected user in useEffect, because it needs state info + // not available in the socket.on() callback + useEffect(() => { + if (newlyConnectedUser) { + console.log(`Handling newly connected user: ${newlyConnectedUser.name}`); + setStudents((prevStudents) => [...prevStudents, newlyConnectedUser]); + + // only send nextQuestion if the quiz has started + if (!quizStarted) { + console.log(`!quizStarted: returning.... `); + return; + } + + if (quizMode === 'teacher') { + webSocketService.nextQuestion({ + roomName: formattedRoomName, + questions: quizQuestions, + questionIndex: Number(currentQuestion?.question.id) - 1, + isLaunch: true // started late + }); + } else if (quizMode === 'student') { + webSocketService.launchStudentModeQuiz(formattedRoomName, quizQuestions); + } else { + console.error('Invalid quiz mode:', quizMode); + } + + // Reset the newly connected user state + setNewlyConnectedUser(null); + } + }, [newlyConnectedUser, quizStarted, quizMode, formattedRoomName, quizQuestions, currentQuestion]); useEffect(() => { const verifyLogin = async () => { @@ -110,6 +142,17 @@ const ManageRoom: React.FC = () => { const roomNameUpper = roomName.toUpperCase(); setFormattedRoomName(roomNameUpper); console.log(`Creating WebSocket room named ${roomNameUpper}`); + + /** + * ATTENTION: Lire les variables d'état dans + * les .on() n'est pas une bonne pratique. + * Les valeurs sont celles au moment de la création + * de la fonction et non au moment de l'exécution. + * Il faut utiliser des refs pour les valeurs qui + * changent fréquemment. Sinon, utiliser un trigger + * de useEffect pour mettre déclencher un traitement + * (voir user-joined plus bas). + */ socket.on('connect', () => { webSocketService.createRoom(roomNameUpper); }); @@ -124,23 +167,9 @@ const ManageRoom: React.FC = () => { }); socket.on('user-joined', (student: StudentType) => { - console.log(`Student joined: name = ${student.name}, id = ${student.id}, quizMode = ${quizMode}, quizStarted = ${quizStarted}`); - - setStudents((prevStudents) => [...prevStudents, student]); - - // only send nextQuestion if the quiz has started - if (!quizStarted) return; - - if (quizMode === 'teacher') { - webSocketService.nextQuestion( - {roomName: formattedRoomName, - questions: quizQuestions, - questionIndex: Number(currentQuestion?.question.id) - 1, - isLaunch: false}); - } else if (quizMode === 'student') { - webSocketService.launchStudentModeQuiz(formattedRoomName, quizQuestions); - } + setNewlyConnectedUser(student); }); + socket.on('join-failure', (message) => { setConnectingError(message); setSocket(null); @@ -286,21 +315,19 @@ const ManageRoom: React.FC = () => { }; const launchQuiz = () => { + setQuizStarted(true); if (!socket || !formattedRoomName || !quiz?.content || quiz?.content.length === 0) { // TODO: This error happens when token expires! Need to handle it properly console.log( `Error launching quiz. socket: ${socket}, roomName: ${formattedRoomName}, quiz: ${quiz}` ); - setQuizStarted(true); - return; } + console.log(`Launching quiz in ${quizMode} mode...`); switch (quizMode) { case 'student': - setQuizStarted(true); return launchStudentMode(); case 'teacher': - setQuizStarted(true); return launchTeacherMode(); } };