From 60f1bda04196a8abaa578eee3291c6401f5050e2 Mon Sep 17 00:00:00 2001 From: GOEPP THOMAS <thomas@saturne-digital.fr> Date: Thu, 16 Jan 2025 09:15:36 +0100 Subject: [PATCH 1/6] refactor: playing quiz with SSE --- models/CustomEventType.ts | 1 + models/Response/AnswerSSEResponse.ts | 11 ++ screens/Multiplayer/Lobby/Lobby.tsx | 41 +++++-- .../PlayingQuizMultiMode.tsx | 63 +++++++---- .../PlayingQuizMultiModeBody.tsx | 61 +++++----- .../PlayingQuizMultiModeHeader.tsx | 6 +- services/MultiService.ts | 107 +++++++++++++++++- 7 files changed, 226 insertions(+), 64 deletions(-) create mode 100644 models/CustomEventType.ts create mode 100644 models/Response/AnswerSSEResponse.ts diff --git a/models/CustomEventType.ts b/models/CustomEventType.ts new file mode 100644 index 0000000..49be365 --- /dev/null +++ b/models/CustomEventType.ts @@ -0,0 +1 @@ +export type CustomEventType = "userJoined" | "nextQuestion" | "generateRun" | "gameStarted" | "answerRevealed" diff --git a/models/Response/AnswerSSEResponse.ts b/models/Response/AnswerSSEResponse.ts new file mode 100644 index 0000000..56db05e --- /dev/null +++ b/models/Response/AnswerSSEResponse.ts @@ -0,0 +1,11 @@ +import {Answer} from "../Answer"; + +export interface AnswerSSEResponse { + id: number; + text: string; + type:string; + categoryId: number; + quizId: string; + order: number; + answers: Answer[]; +} \ No newline at end of file diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx index 8aaff52..d128e07 100644 --- a/screens/Multiplayer/Lobby/Lobby.tsx +++ b/screens/Multiplayer/Lobby/Lobby.tsx @@ -12,6 +12,7 @@ import BlueButton from "../../../components/buttons/BlueButton"; import WhiteButton from "../../../components/buttons/WhiteButton"; import ModalInvitePlayer from "../../../components/Multiplayer/ModalInvitePlayer"; import EventSource from "react-native-sse"; +import {CustomEventType} from "../../../models/CustomEventType"; interface Props { navigation: NavigationProp<any>; route: RouteProp<RoutePropsType, "Lobby">; @@ -26,7 +27,10 @@ type RoutePropsType = { }; }; -type CustomEventType = "userJoined" | "nextQuestion" +interface GenerateRunData { + runId: string; // ou number selon votre cas + // autres propriétés si nécessaire +} export default function Lobby({navigation, route}: Props) { @@ -37,8 +41,9 @@ export default function Lobby({navigation, route}: Props) { const [roomIdCreated, setRoomIdCreated] = useState<string | undefined>(roomId); const [runId, setRunId] = useState<string>(""); const [showModal, setShowModal] = useState<boolean>(false); + const [esUseState, setEsUseState] = useState<EventSource<CustomEventType>>(); - const {createParty} = useMultiService(); + const {createParty, generateRun, startParty} = useMultiService(); const userInvite = { id: 0, username: 'Invite', email: 'invite@email.com'} let goodId = roomId; @@ -55,9 +60,24 @@ export default function Lobby({navigation, route}: Props) { setRoomIdCreated(response); } console.log("User try to joined party with ID:", goodId); - console.log(`https://klebert-host.com:33037/party/join/${goodId}`) const es = new EventSource<CustomEventType>(`https://klebert-host.com:33037/party/join/${goodId}`); + setEsUseState(es); + + es.addEventListener("open", async (event) => { + console.log("open event"); + const responseGenerate = await generateRun(); + if(HttpError.isHttpError(responseGenerate)) { + console.log("zzzzzzzzz"); + return; + } + setRunId(responseGenerate); + }); + + es.addEventListener("gameStarted", async () => { + console.log("Game started event data:"); + navigation.navigate("PlayingQuizMultiMode", {runId: runId, socket: es, roomId: roomId}); + }); es.addEventListener("userJoined", (event) => { console.log("User joined event data:", event.data); @@ -70,15 +90,18 @@ export default function Lobby({navigation, route}: Props) { const filteredNewUsers = newUsers.filter((user) => !ids.has(user.id)); return [...prevPlayers, ...filteredNewUsers]; }); - - }); + es.addEventListener("error", (err) => { - console.error("Error with SSE:", err); + console.log("Error with SSE:", err); }); - return () => es.close(); + useEffect(() => { + return () => { + es.close(); + }; + }, []); }; useEffect(() => { @@ -111,8 +134,8 @@ export default function Lobby({navigation, route}: Props) { navigation.navigate("TabNavigator"); }; - const onPlayPressed = () => { - navigation.navigate("PlayingQuizMultiMode", {runId: runId, socket: socket, roomId: roomIdCreated}); + const onPlayPressed = async () => { + await startParty(); }; const onCancelPressed = () => { diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx index 78c1760..671935b 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx @@ -10,44 +10,55 @@ import PlayingQuizMultiModeBody from "./PlayingQuizMultiModeBody"; import {Socket} from "socket.io-client"; import {QuestionResponse} from "../../../../models/Response/QuestionResponse"; import {RunInformations} from "../../../../models/RunInformations"; +import EventSource from "react-native-sse"; +import {CustomEventType} from "../../../../models/CustomEventType"; +import {AnswerSSEResponse} from "../../../../models/Response/AnswerSSEResponse"; +import {useMultiService} from "../../../../services/MultiService"; type RoutePropsType = { PlayingQuizMultiMode: { runId: string; - socket: Socket; + es: EventSource<CustomEventType>; roomId: string; + isHost: boolean; }; }; +enum QuizState { + ANSWERING= "Answering", + LOADING= "Loading", + SHOWING_RESULTS= "ShowingResults", +} + interface Props { route: RouteProp<RoutePropsType, "PlayingQuizMultiMode">; navigation: NavigationProp<any>; } export default function PlayingQuizMultiMode({route, navigation}:Props) { - const {runId, socket, roomId} = route.params; - const { getQuizInformations, getRunsInfo } = useQuizService(); + const {runId, es, roomId, isHost} = route.params; + const {getQuizInformations, getRunsInfo} = useQuizService(); + const [quizState, setQuizState] = useState(QuizState.ANSWERING); const [quizInformations, setQuizInformations] = useState<QuizInformations | undefined>(undefined); const [runInformations, setRunInformations] = useState<RunInformations>(); - const [actualQuestion, setActualQuestion] = useState<QuestionResponse | undefined>(undefined); + const [actualQuestion, setActualQuestion] = useState<Question | undefined>(undefined); const [score, setScore] = useState(0); + const {nextQuestion} = useMultiService(); - const initSocket = async () => { - socket.on("gameStarted", (data) => { - console.log("Game started:", data); - }); - socket.on("newQuestion", (data) => { - const question: QuestionResponse = data as QuestionResponse + const initES = async () => { + es.addEventListener("nextQuestion", async (event) => { + if (!event.data) return; + const question: Question = JSON.parse(event.data); setActualQuestion(question); - // console.log(JSON.stringify(question, null, 2)); // Beautifie le JSON avec 2 espaces d'indentation + setQuizState(QuizState.ANSWERING); }); - } + } const fetchRuns = async () => { - if(runId === undefined) return; + if (runId === undefined) return; const runFetched = await getRunsInfo(runId); if (runFetched instanceof HttpError) { console.log("Error fetching runs info", runFetched); @@ -63,22 +74,24 @@ export default function PlayingQuizMultiMode({route, navigation}:Props) { }; useEffect(() => { - console.log("PlayingQuizMultiMode starting"); - initSocket(); + initES(); fetchRuns(); - setTimeout(() => { - socket.emit("startGame") - },500); - - setTimeout(() => { - socket.emit("nextQuestion"); - },2000); + console.log("fetching first question"); + nextQuestion(); }, []); return ( <TemplateDuo - childrenHeader={<PlayingQuizMultiModeHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score} navigation={navigation}></PlayingQuizMultiModeHeader>} - childrenBody={<PlayingQuizMultiModeBody runId={runId} actualQuestion={actualQuestion} socket={socket} fetchActualQuestion={()=>{}} roomId={roomId} navigation={navigation}></PlayingQuizMultiModeBody>} + childrenHeader={<PlayingQuizMultiModeHeader quizInformations={quizInformations} runId={runId} + actualQuestion={actualQuestion} score={score} + navigation={navigation}></PlayingQuizMultiModeHeader>} + childrenBody={<PlayingQuizMultiModeBody runId={runId} actualQuestion={actualQuestion} es={es} + fetchActualQuestion={() => { + }} roomId={roomId} isHost={isHost} + navigation={navigation} + quizState={quizState} + setQuizState={setQuizState}> + </PlayingQuizMultiModeBody>} /> ); -} \ No newline at end of file +} diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx index f7cda1a..50a55cb 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx @@ -13,14 +13,21 @@ import {QuestionResponse} from "../../../../models/Response/QuestionResponse"; import {RunInformations} from "../../../../models/RunInformations"; import {Socket} from "socket.io-client"; import {AnswerWsResponse} from "../../../../models/Response/AnswerWsResponse"; +import EventSource from "react-native-sse"; +import {CustomEventType} from "../../../../models/CustomEventType"; +import {AnswerSSEResponse} from "../../../../models/Response/AnswerSSEResponse"; +import {useMultiService} from "../../../../services/MultiService"; interface Props { runId?: string; - actualQuestion?: QuestionResponse; + actualQuestion?: Question; fetchActualQuestion: () => void; - socket: Socket; + es: EventSource<CustomEventType>; roomId: string; + isHost: boolean; + quizState: QuizState; + setQuizState: (quizState: QuizState) => void; navigation: NavigationProp<any>; } @@ -67,14 +74,14 @@ const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number | return styles.answerButton; } -export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchActualQuestion, roomId, socket, navigation }: Props) { +export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchActualQuestion, roomId, es,isHost, quizState,setQuizState, navigation }: Props) { const [selectedAnswerId, setSelectedAnswerId] = useState<number | null>(null); - const [quizState, setQuizState] = useState(QuizState.ANSWERING); const [correctAnswerId, setCorrectAnswerId] = useState<number | null>(null); const [isLastQuestion, setIsLastQuestion] = useState(false); const [quizInformations, setQuizInformations] = useState<QuizInformations>(); const [runInformations, setRunInformations] = useState<RunInformations>(); - const {answerQuestion, getRunsInfo, getQuizInformations} = useQuizService(); + const {getRunsInfo, getQuizInformations} = useQuizService(); + const {revealAnswer, answerQuestion, nextQuestion} = useMultiService(); const getCorrectAnswer = (answers: Answer[]): Answer => { const correctAnswer = answers.find((answer) => answer.isCorrect); if (!correctAnswer) return answers[0]; @@ -83,15 +90,17 @@ export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchAc const initSocket = async () => { console.log("init socket in body"); - socket.on("answersRevealed", (data: AnswerWsResponse) => { - const correctAnswerIdFetched = getCorrectAnswer(data.answers).id; - console.log("correctAnswerIdFetched", correctAnswerIdFetched); - setCorrectAnswerId(correctAnswerIdFetched); + es.addEventListener("answerRevealed", (event) => { + if(!event.data) return; + const answers: AnswerSSEResponse = JSON.parse(event.data); + setCorrectAnswerId(getCorrectAnswer(answers.answers).id); setQuizState(QuizState.SHOWING_RESULTS); }); - // socket.on("score", (data) => { - // console.log("Score:", data); - // }); + + es.addEventListener("nextQuestion", (event) => { + + }); + } useEffect(() => { @@ -104,22 +113,22 @@ export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchAc if(selectedAnswerId === null || actualQuestion === undefined) return; setQuizState(QuizState.LOADING); - socket.emit("submitAnswer", { - roomId, - runId, - questionId: actualQuestion.question.id, - answerId: selectedAnswerId, - }); + await answerQuestion(actualQuestion.id, selectedAnswerId); + + if(isHost) + { + revealAnswer(); + } - setTimeout(() => { - socket.emit("revealAnswer", {runId: runId}); - },500); }; const onContinue = () => { - socket.emit("nextQuestion"); - setQuizState(QuizState.ANSWERING); - setCorrectAnswerId(null); - setSelectedAnswerId(null); + if(isHost) + { + nextQuestion(); + setQuizState(QuizState.ANSWERING); + setCorrectAnswerId(null); + setSelectedAnswerId(null); + } } const onAnsweredButtonClicked = (answerId: number) => { @@ -133,7 +142,7 @@ export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchAc <View style={styles.buttonContainer}> {actualQuestion ? ( <> - {actualQuestion.question.answers.map((answer, index) => ( + {actualQuestion.answers.map((answer, index) => ( <AnswerButton key={index} text={answer.text} diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx index 427c8cd..d07c152 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx @@ -12,7 +12,7 @@ import {QuestionResponse} from "../../../../models/Response/QuestionResponse"; interface Props { quizInformations?: QuizInformations; runId?: string; - actualQuestion?: QuestionResponse; + actualQuestion?: Question; score: number; navigation: NavigationProp<any> } @@ -42,7 +42,7 @@ export default function PlayingQuizMultiModeHeader({quizInformations, runId, act <View style={styles.questionAndScoreContainer}> <View style={styles.InformationsContainer}> <Text style={TextsStyles.titleText}>{t("app.screens.question.question")}</Text> - <Text style={TextsStyles.titleText}>{actualQuestion ? actualQuestion.question.order + 1 :"?"}/{quizInformations ? quizInformations.questionCount : "?"}</Text> + <Text style={TextsStyles.titleText}>{actualQuestion ? actualQuestion.order + 1 :"?"}/{quizInformations ? quizInformations.questionCount : "?"}</Text> </View> <View style={styles.InformationsContainer}> <Text style={TextsStyles.titleText}>{t("app.screens.question.score")}</Text> @@ -50,7 +50,7 @@ export default function PlayingQuizMultiModeHeader({quizInformations, runId, act </View> </View> <View style={styles.QuizQuestionContainer}> - <Text style={TextsStyles.subtitleText}>{actualQuestion ? actualQuestion.question.text : "Loading..."}</Text> + <Text style={TextsStyles.subtitleText}>{actualQuestion ? actualQuestion.text : "Loading..."}</Text> </View> <ConfirmModal visible={isConfirmModalVisible} onClose={()=>setIsConfirmModalVisible(false)} onConfirm={handleConfirmModalConfirm}/> diff --git a/services/MultiService.ts b/services/MultiService.ts index f0de634..63f53e7 100644 --- a/services/MultiService.ts +++ b/services/MultiService.ts @@ -5,7 +5,7 @@ import HttpError from "./HttpError"; export const useMultiService = () => { const url = "https://klebert-host.com:33037" - const createParty = async (quizId: string) : Promise<string | HttpError> => { + const createParty = async (quizId: string) : Promise<string | HttpError> => { console.log("Create party with ID :", quizId); console.log(url+"/party"); const requestBody = { @@ -29,8 +29,113 @@ export const useMultiService = () => { } } + const generateRun = async () : Promise<string | HttpError> => { + console.log("generateRun"); + try { + const response = await axios.get(`${url}/party/generateRun`, { + withCredentials: true, + }); + console.log("Generate run done"); + return response.data.runId; + } catch (error: any) { + console.log("Error while generate run:", error); + + if (error.response) { + return new HttpError(error.response.status, error.response.data?.message || "HTTP error"); + } else { + return new HttpError(500, "Unexpected error: " + error.message); + } + } + }; + + const revealAnswer = async () : Promise<boolean | HttpError> => { + console.log("revealAnswer"); + try { + const response = await axios.get(`${url}/party/revealAnswer`, { + withCredentials: true, + }); + console.log("revealAnswer done"); + return true; + } catch (error: any) { + console.log("Error while reveal Answer:", error); + + if (error.response) { + return new HttpError(error.response.status, error.response.data?.message || "HTTP error"); + } else { + return new HttpError(500, "Unexpected error: " + error.message); + } + } + }; + + const answerQuestion = async (questionId: number, answerId: number) : Promise<boolean | HttpError> => { + console.log("answerQuestion"); + const requestBody = { + questionId: questionId, + answerId: answerId, + }; + + try { + const response = await axios.post(`${url}/party/answer`, requestBody,{ + withCredentials: true, + }); + console.log("answerQuestion done"); + return true; + } catch (error: any) { + console.log("Error while reveal Answer:", error); + + if (error.response) { + return new HttpError(error.response.status, error.response.data?.message || "HTTP error"); + } else { + return new HttpError(500, "Unexpected error: " + error.message); + } + } + }; + + const nextQuestion = async () : Promise<boolean | HttpError> => { + console.log("nextQuestion"); + try { + const response = await axios.get(`${url}/party/nextQuestion`, { + withCredentials: true, + }); + console.log("nextQuestion done"); + return true; + } catch (error: any) { + console.log("Error while nextQuestion:", error); + + if (error.response) { + return new HttpError(error.response.status, error.response.data?.message || "HTTP error"); + } else { + return new HttpError(500, "Unexpected error: " + error.message); + } + } + }; + + const startParty = async () : Promise<boolean | HttpError> => { + console.log("startParty"); + try { + const response = await axios.get(`${url}/party/start`, { + withCredentials: true, + }); + console.log("startParty done"); + return true; + } catch (error: any) { + console.log("Error while startParty:", error); + + if (error.response) { + return new HttpError(error.response.status, error.response.data?.message || "HTTP error"); + } else { + return new HttpError(500, "Unexpected error: " + error.message); + } + } + }; + return { createParty: createParty, + generateRun: generateRun, + revealAnswer: revealAnswer, + nextQuestion: nextQuestion, + answerQuestion: answerQuestion, + startParty: startParty } } \ No newline at end of file -- GitLab From 7ad7904d833441f936e2aca2827c0b4eb6303117 Mon Sep 17 00:00:00 2001 From: GOEPP THOMAS <thomas@saturne-digital.fr> Date: Thu, 16 Jan 2025 09:32:15 +0100 Subject: [PATCH 2/6] refactor: playing quiz with SSE --- screens/Multiplayer/Lobby/Lobby.tsx | 7 +++++-- .../Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx index d128e07..6d78f47 100644 --- a/screens/Multiplayer/Lobby/Lobby.tsx +++ b/screens/Multiplayer/Lobby/Lobby.tsx @@ -43,7 +43,7 @@ export default function Lobby({navigation, route}: Props) { const [showModal, setShowModal] = useState<boolean>(false); const [esUseState, setEsUseState] = useState<EventSource<CustomEventType>>(); - const {createParty, generateRun, startParty} = useMultiService(); + const {createParty, generateRun, startParty, nextQuestion} = useMultiService(); const userInvite = { id: 0, username: 'Invite', email: 'invite@email.com'} let goodId = roomId; @@ -135,7 +135,10 @@ export default function Lobby({navigation, route}: Props) { }; const onPlayPressed = async () => { - await startParty(); + console.log("playing es :" + esUseState); + navigation.navigate("PlayingQuizMultiMode", {runId: runId, socket: esUseState, roomId: roomId}); + + startParty(); }; const onCancelPressed = () => { diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx index 671935b..e79a338 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx @@ -55,7 +55,6 @@ export default function PlayingQuizMultiMode({route, navigation}:Props) { setQuizState(QuizState.ANSWERING); }); - } const fetchRuns = async () => { if (runId === undefined) return; -- GitLab From 28c791a0e9f290cce9eca366851b2b71fb99079d Mon Sep 17 00:00:00 2001 From: GOEPP THOMAS <thomas@saturne-digital.fr> Date: Thu, 16 Jan 2025 10:00:29 +0100 Subject: [PATCH 3/6] refactor: playing quiz with SSE --- screens/Multiplayer/Lobby/Lobby.tsx | 8 ++++--- .../PlayingQuizMultiMode.tsx | 22 ++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx index 6d78f47..67a7b18 100644 --- a/screens/Multiplayer/Lobby/Lobby.tsx +++ b/screens/Multiplayer/Lobby/Lobby.tsx @@ -13,6 +13,7 @@ import WhiteButton from "../../../components/buttons/WhiteButton"; import ModalInvitePlayer from "../../../components/Multiplayer/ModalInvitePlayer"; import EventSource from "react-native-sse"; import {CustomEventType} from "../../../models/CustomEventType"; +import {Question} from "../../../models/Question"; interface Props { navigation: NavigationProp<any>; route: RouteProp<RoutePropsType, "Lobby">; @@ -43,7 +44,7 @@ export default function Lobby({navigation, route}: Props) { const [showModal, setShowModal] = useState<boolean>(false); const [esUseState, setEsUseState] = useState<EventSource<CustomEventType>>(); - const {createParty, generateRun, startParty, nextQuestion} = useMultiService(); + const {createParty, generateRun, startParty} = useMultiService(); const userInvite = { id: 0, username: 'Invite', email: 'invite@email.com'} let goodId = roomId; @@ -74,9 +75,10 @@ export default function Lobby({navigation, route}: Props) { setRunId(responseGenerate); }); - es.addEventListener("gameStarted", async () => { + es.addEventListener("gameStarted", () => { console.log("Game started event data:"); - navigation.navigate("PlayingQuizMultiMode", {runId: runId, socket: es, roomId: roomId}); + console.log("ES envoyé : ", es); + navigation.navigate("PlayingQuizMultiMode", {runId: runId, es: es, roomId: roomId, isHost: true}); }); es.addEventListener("userJoined", (event) => { diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx index e79a338..8b8a376 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx @@ -38,6 +38,7 @@ interface Props { export default function PlayingQuizMultiMode({route, navigation}:Props) { const {runId, es, roomId, isHost} = route.params; + const {getQuizInformations, getRunsInfo} = useQuizService(); const [quizState, setQuizState] = useState(QuizState.ANSWERING); const [quizInformations, setQuizInformations] = useState<QuizInformations | undefined>(undefined); @@ -46,15 +47,20 @@ export default function PlayingQuizMultiMode({route, navigation}:Props) { const [score, setScore] = useState(0); const {nextQuestion} = useMultiService(); + useEffect(() => { + console.log("es changed", es); + }, [es]); - const initES = async () => { - es.addEventListener("nextQuestion", async (event) => { - if (!event.data) return; - const question: Question = JSON.parse(event.data); - setActualQuestion(question); - setQuizState(QuizState.ANSWERING); - }); - + const initES = () => { + setTimeout(()=>{ + es.addEventListener("nextQuestion", (event) => { + console.log("nextQuestion event data:"); + if (!event.data) return; + const question: Question = JSON.parse(event.data); + setActualQuestion(question); + setQuizState(QuizState.ANSWERING); + }); + },2000) } const fetchRuns = async () => { if (runId === undefined) return; -- GitLab From e987dec5072103ead10da66cd92dd6d10dba5bb0 Mon Sep 17 00:00:00 2001 From: GOEPP THOMAS <thomas@saturne-digital.fr> Date: Thu, 16 Jan 2025 14:46:53 +0100 Subject: [PATCH 4/6] refactor: playing quiz with SSE --- screens/Multiplayer/Lobby/Lobby.tsx | 19 ++++++------- .../PlayingQuizMultiMode.tsx | 27 +++++++++---------- .../PlayingQuizMultiModeBody.tsx | 13 ++++++--- .../PlayingQuizMultiModeHeader.tsx | 8 +++--- services/MultiService.ts | 23 ++++++++++++++-- 5 files changed, 56 insertions(+), 34 deletions(-) diff --git a/screens/Multiplayer/Lobby/Lobby.tsx b/screens/Multiplayer/Lobby/Lobby.tsx index 67a7b18..0da8017 100644 --- a/screens/Multiplayer/Lobby/Lobby.tsx +++ b/screens/Multiplayer/Lobby/Lobby.tsx @@ -65,20 +65,19 @@ export default function Lobby({navigation, route}: Props) { const es = new EventSource<CustomEventType>(`https://klebert-host.com:33037/party/join/${goodId}`); setEsUseState(es); - es.addEventListener("open", async (event) => { - console.log("open event"); + es.addEventListener("gameStarted", async (event) => { + if(!event.data) return; + console.log("Game started event data:",event.data); const responseGenerate = await generateRun(); if(HttpError.isHttpError(responseGenerate)) { console.log("zzzzzzzzz"); return; } - setRunId(responseGenerate); - }); + console.log("generate run",responseGenerate); - es.addEventListener("gameStarted", () => { - console.log("Game started event data:"); - console.log("ES envoyé : ", es); - navigation.navigate("PlayingQuizMultiMode", {runId: runId, es: es, roomId: roomId, isHost: true}); + setRunId(responseGenerate); + // navigation.navigate("PlayingQuizMultiMode", {runId: responseGenerate, questionCount:event.data.questionCount, es: es, roomId: roomId, isHost: true}); + navigation.navigate("PlayingQuizMultiMode", {runId: responseGenerate, questionCount: 10, es: es, roomId: roomId, isHost: isHost}); }); es.addEventListener("userJoined", (event) => { @@ -136,10 +135,8 @@ export default function Lobby({navigation, route}: Props) { navigation.navigate("TabNavigator"); }; - const onPlayPressed = async () => { + const onPlayPressed = () => { console.log("playing es :" + esUseState); - navigation.navigate("PlayingQuizMultiMode", {runId: runId, socket: esUseState, roomId: roomId}); - startParty(); }; diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx index 8b8a376..ae3aeb7 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx @@ -19,6 +19,7 @@ import {useMultiService} from "../../../../services/MultiService"; type RoutePropsType = { PlayingQuizMultiMode: { runId: string; + questionCount: number; es: EventSource<CustomEventType>; roomId: string; isHost: boolean; @@ -37,7 +38,7 @@ interface Props { } export default function PlayingQuizMultiMode({route, navigation}:Props) { - const {runId, es, roomId, isHost} = route.params; + const {runId, es, roomId,questionCount, isHost} = route.params; const {getQuizInformations, getRunsInfo} = useQuizService(); const [quizState, setQuizState] = useState(QuizState.ANSWERING); @@ -47,22 +48,17 @@ export default function PlayingQuizMultiMode({route, navigation}:Props) { const [score, setScore] = useState(0); const {nextQuestion} = useMultiService(); - useEffect(() => { - console.log("es changed", es); - }, [es]); - const initES = () => { - setTimeout(()=>{ - es.addEventListener("nextQuestion", (event) => { - console.log("nextQuestion event data:"); - if (!event.data) return; - const question: Question = JSON.parse(event.data); - setActualQuestion(question); - setQuizState(QuizState.ANSWERING); - }); - },2000) + es.addEventListener("nextQuestion", (event) => { + console.log("nextQuestion event data:"); + if (!event.data) return; + const question: Question = JSON.parse(event.data); + setActualQuestion(question); + setQuizState(QuizState.ANSWERING); + }); } const fetchRuns = async () => { + console.log("run to get info :", runId); if (runId === undefined) return; const runFetched = await getRunsInfo(runId); if (runFetched instanceof HttpError) { @@ -89,12 +85,13 @@ export default function PlayingQuizMultiMode({route, navigation}:Props) { <TemplateDuo childrenHeader={<PlayingQuizMultiModeHeader quizInformations={quizInformations} runId={runId} actualQuestion={actualQuestion} score={score} - navigation={navigation}></PlayingQuizMultiModeHeader>} + navigation={navigation} questionCount={10}></PlayingQuizMultiModeHeader>} childrenBody={<PlayingQuizMultiModeBody runId={runId} actualQuestion={actualQuestion} es={es} fetchActualQuestion={() => { }} roomId={roomId} isHost={isHost} navigation={navigation} quizState={quizState} + setScore={setScore} setQuizState={setQuizState}> </PlayingQuizMultiModeBody>} /> diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx index 50a55cb..729b62c 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx @@ -28,6 +28,7 @@ interface Props { isHost: boolean; quizState: QuizState; setQuizState: (quizState: QuizState) => void; + setScore: (score: number) => void; navigation: NavigationProp<any>; } @@ -74,14 +75,14 @@ const getStyleOfAnswerButton = (answerId: number, selectedAnswerIndex: number | return styles.answerButton; } -export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchActualQuestion, roomId, es,isHost, quizState,setQuizState, navigation }: Props) { +export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchActualQuestion, roomId, es,isHost, setScore, quizState,setQuizState, navigation }: Props) { const [selectedAnswerId, setSelectedAnswerId] = useState<number | null>(null); const [correctAnswerId, setCorrectAnswerId] = useState<number | null>(null); const [isLastQuestion, setIsLastQuestion] = useState(false); const [quizInformations, setQuizInformations] = useState<QuizInformations>(); const [runInformations, setRunInformations] = useState<RunInformations>(); const {getRunsInfo, getQuizInformations} = useQuizService(); - const {revealAnswer, answerQuestion, nextQuestion} = useMultiService(); + const {revealAnswer, answerQuestion, nextQuestion, getScore} = useMultiService(); const getCorrectAnswer = (answers: Answer[]): Answer => { const correctAnswer = answers.find((answer) => answer.isCorrect); if (!correctAnswer) return answers[0]; @@ -117,7 +118,13 @@ export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchAc if(isHost) { - revealAnswer(); + await revealAnswer(); + const scoreFetched = await getScore(); + if(HttpError.isHttpError(scoreFetched)) + { + return; + } + setScore(scoreFetched); } }; diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx index d07c152..63b2922 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeHeader.tsx @@ -14,10 +14,12 @@ interface Props { runId?: string; actualQuestion?: Question; score: number; + questionCount: number; navigation: NavigationProp<any> + } -export default function PlayingQuizMultiModeHeader({quizInformations, runId, actualQuestion, score, navigation}: Props) { +export default function PlayingQuizMultiModeHeader({quizInformations, runId, actualQuestion, score, questionCount, navigation}: Props) { const [isConfirmModalVisible, setIsConfirmModalVisible] = useState(false); const {t} = useTranslation(); @@ -42,11 +44,11 @@ export default function PlayingQuizMultiModeHeader({quizInformations, runId, act <View style={styles.questionAndScoreContainer}> <View style={styles.InformationsContainer}> <Text style={TextsStyles.titleText}>{t("app.screens.question.question")}</Text> - <Text style={TextsStyles.titleText}>{actualQuestion ? actualQuestion.order + 1 :"?"}/{quizInformations ? quizInformations.questionCount : "?"}</Text> + <Text style={TextsStyles.titleText}>{actualQuestion ? actualQuestion.order + 1 :"?"}/{questionCount}</Text> </View> <View style={styles.InformationsContainer}> <Text style={TextsStyles.titleText}>{t("app.screens.question.score")}</Text> - <Text style={TextsStyles.titleText}>{score}/{quizInformations ? quizInformations.questionCount : "?"}</Text> + <Text style={TextsStyles.titleText}>{score}/{questionCount}</Text> </View> </View> <View style={styles.QuizQuestionContainer}> diff --git a/services/MultiService.ts b/services/MultiService.ts index 63f53e7..7b10a56 100644 --- a/services/MultiService.ts +++ b/services/MultiService.ts @@ -35,7 +35,6 @@ export const useMultiService = () => { const response = await axios.get(`${url}/party/generateRun`, { withCredentials: true, }); - console.log("Generate run done"); return response.data.runId; } catch (error: any) { console.log("Error while generate run:", error); @@ -129,13 +128,33 @@ export const useMultiService = () => { } }; + const getScore = async () : Promise<number | HttpError> => { + console.log("getScore"); + try { + const response = await axios.get(`${url}/party/score`, { + withCredentials: true, + }); + console.log("getScore done"); + return response.data.score; + } catch (error: any) { + console.log("Error while startParty:", error); + + if (error.response) { + return new HttpError(error.response.status, error.response.data?.message || "HTTP error"); + } else { + return new HttpError(500, "Unexpected error: " + error.message); + } + } + }; + return { createParty: createParty, generateRun: generateRun, revealAnswer: revealAnswer, nextQuestion: nextQuestion, answerQuestion: answerQuestion, - startParty: startParty + startParty: startParty, + getScore: getScore } } \ No newline at end of file -- GitLab From 1867bda84d4fe9be8344fa033f66def2dcd4cb15 Mon Sep 17 00:00:00 2001 From: GOEPP THOMAS <thomas@saturne-digital.fr> Date: Thu, 16 Jan 2025 16:14:37 +0100 Subject: [PATCH 5/6] refactor: playing quiz with SSE --- .../PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx | 5 +++-- components/PlayingQuiz/EndQuiz/UserScore.tsx | 3 ++- models/CustomEventType.ts | 2 +- models/UserEndQuiz.ts | 5 +++++ .../PlayingQuizMultiMode/PlayingQuizMultiMode.tsx | 13 ++++++++++++- screens/Multiplayer/MultiplayerChild.tsx | 1 - screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx | 8 ++++---- .../PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx | 13 +++++++------ 8 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 models/UserEndQuiz.ts diff --git a/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx b/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx index 819fabe..57f73da 100644 --- a/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx +++ b/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx @@ -1,14 +1,15 @@ import React from "react"; import { FlatList, View, Text, StyleSheet, Image } from "react-native"; import {User} from "../../../models/User"; +import {UserEndQuiz} from "../../../models/UserEndQuiz"; interface Props { - users: User[]; + users: UserEndQuiz[]; maxScore: number; } export default function EndQuizListPlayer({ users, maxScore }: Props) { - const renderUser = ({ item, index }: { item: User; index: number }) => ( + const renderUser = ({ item, index }: { item: UserEndQuiz; index: number }) => ( <View style={[styles.userContainer, index === 0 && styles.firstPlace]}> <Image source={require("../../../assets/ProfilBaseImage.png")} // Replace with actual profile picture if available diff --git a/components/PlayingQuiz/EndQuiz/UserScore.tsx b/components/PlayingQuiz/EndQuiz/UserScore.tsx index 6583622..b8f2187 100644 --- a/components/PlayingQuiz/EndQuiz/UserScore.tsx +++ b/components/PlayingQuiz/EndQuiz/UserScore.tsx @@ -1,8 +1,9 @@ import { View, Text, StyleSheet, Image } from "react-native"; import {User} from "../../../models/User"; +import {UserEndQuiz} from "../../../models/UserEndQuiz"; interface Props { - user: User; + user: UserEndQuiz; score: number; maxScore: number; isFirst: boolean; diff --git a/models/CustomEventType.ts b/models/CustomEventType.ts index 49be365..feea302 100644 --- a/models/CustomEventType.ts +++ b/models/CustomEventType.ts @@ -1 +1 @@ -export type CustomEventType = "userJoined" | "nextQuestion" | "generateRun" | "gameStarted" | "answerRevealed" +export type CustomEventType = "userJoined" | "nextQuestion" | "generateRun" | "gameStarted" | "answerRevealed" | "gameEnded"; diff --git a/models/UserEndQuiz.ts b/models/UserEndQuiz.ts new file mode 100644 index 0000000..352a19b --- /dev/null +++ b/models/UserEndQuiz.ts @@ -0,0 +1,5 @@ +export interface UserEndQuiz{ + id: number, + username: string, + score: number +} \ No newline at end of file diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx index ae3aeb7..503fc43 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx @@ -14,6 +14,8 @@ import EventSource from "react-native-sse"; import {CustomEventType} from "../../../../models/CustomEventType"; import {AnswerSSEResponse} from "../../../../models/Response/AnswerSSEResponse"; import {useMultiService} from "../../../../services/MultiService"; +import {UserEndQuiz} from "../../../../models/UserEndQuiz"; +import {shuffleAnswersOfQuiz} from "../../../../helper/QuizHelper"; type RoutePropsType = { @@ -53,9 +55,18 @@ export default function PlayingQuizMultiMode({route, navigation}:Props) { console.log("nextQuestion event data:"); if (!event.data) return; const question: Question = JSON.parse(event.data); - setActualQuestion(question); + + setActualQuestion(shuffleAnswersOfQuiz(question)); setQuizState(QuizState.ANSWERING); }); + + es.addEventListener("gameEnded", (event) => { + console.log("gameEnded event data:"); + if (!event.data) return; + const users: UserEndQuiz[] = JSON.parse(event.data); + console.log("users:", users); + navigation.navigate("EndQuizMulti", { users: users }); + }); } const fetchRuns = async () => { console.log("run to get info :", runId); diff --git a/screens/Multiplayer/MultiplayerChild.tsx b/screens/Multiplayer/MultiplayerChild.tsx index c766368..c8fc1a4 100644 --- a/screens/Multiplayer/MultiplayerChild.tsx +++ b/screens/Multiplayer/MultiplayerChild.tsx @@ -63,7 +63,6 @@ export default function MultiplayerChild({navigation}: Props) { <View style={styles.buttonContainer}> <MenuButton text={"COMMUNITY"} handleButtonPressed={handleButtonCommunityPressed}/> <MenuButton text={"PLAY AN ONLINE QUIZ"} handleButtonPressed={handleOnlineQuizPressed}/> - <MenuButton text={"ONGOING QUIZZES"} handleButtonPressed={handleButtonOngoingQuizzesPressed}/> </View> </> )} diff --git a/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx b/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx index 1945637..08ddf19 100644 --- a/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx +++ b/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx @@ -2,12 +2,12 @@ import {NavigationProp, RouteProp} from "@react-navigation/native"; import { View, StyleSheet, Image, Text } from "react-native"; import TemplateMenu from "../../../templates/TemplateMenu"; import {Quiz} from "../../../models/Quiz"; -import EndQuizChild from "../EndQuiz/EndQuizChild"; import EndQuizMultiChild from "./EndQuizMultiChild"; +import {UserEndQuiz} from "../../../models/UserEndQuiz"; type RoutePropsType = { EndQuizChild: { - quiz: Quiz; + users: UserEndQuiz[]; }; }; interface Props { @@ -16,12 +16,12 @@ interface Props { } export default function EndQuizMulti({route,navigation}: Props) { - const { quiz } = route.params; + const { users } = route.params; return ( <View style={styles.containerGlobal}> <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}> <View> - <EndQuizMultiChild navigation={navigation} quiz={quiz}/> + <EndQuizMultiChild navigation={navigation} users={users} /> </View> </TemplateMenu> </View> diff --git a/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx b/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx index b53eb9f..87e35c7 100644 --- a/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx +++ b/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx @@ -6,15 +6,16 @@ import {useQuizService} from "../../../services/QuizService"; import HttpError from "../../../services/HttpError"; import UserScore from "../../../components/PlayingQuiz/EndQuiz/UserScore"; import EndQuizListPlayer from "../../../components/PlayingQuiz/EndQuiz/EndQuizListPlayer"; +import {UserEndQuiz} from "../../../models/UserEndQuiz"; interface Props { navigation: NavigationProp<any>; - quiz: Quiz; + users: UserEndQuiz[] } -export default function EndQuizMultiChild({ navigation, quiz }: Props) { +export default function EndQuizMultiChild({ navigation, users }: Props) { const userTest = {id: 1, email: "user1@email.com", username: "user1", stats: undefined}; @@ -33,11 +34,11 @@ export default function EndQuizMultiChild({ navigation, quiz }: Props) { style={styles.stars} /> <View style={styles.usersContainer}> - <UserScore user={userTest} score={10} maxScore={quiz.questionCount} isFirst={false}/> - <UserScore user={userTest} score={10} maxScore={quiz.questionCount} isFirst={true}/> - <UserScore user={userTest} score={10} maxScore={quiz.questionCount} isFirst={false}/> + { users[1] && (<UserScore user={users[1]} score={10} maxScore={10} isFirst={false}/>)} + <UserScore user={users[0]} score={10} maxScore={10} isFirst={true}/> + { users[2] &&(<UserScore user={users[2]} score={10} maxScore={10} isFirst={false}/>)} </View> - <EndQuizListPlayer users={[userTest, userTest]} maxScore={quiz.questionCount}/> + <EndQuizListPlayer users={users} maxScore={10}/> {/*<DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>*/} <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton> -- GitLab From 2cd4df11a1f9f18cd92f09a7d73b38bbcce4900b Mon Sep 17 00:00:00 2001 From: GOEPP THOMAS <thomas@saturne-digital.fr> Date: Thu, 16 Jan 2025 20:45:08 +0100 Subject: [PATCH 6/6] refactor: end quiz sse --- .../PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx | 2 +- components/PlayingQuiz/EndQuiz/UserScore.tsx | 4 ++-- .../PlayingQuizMultiMode/PlayingQuizMultiMode.tsx | 2 +- .../PlayingQuizMultiModeBody.tsx | 13 +++++++------ screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx | 5 +++-- .../PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx | 11 ++++++----- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx b/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx index 57f73da..a55009b 100644 --- a/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx +++ b/components/PlayingQuiz/EndQuiz/EndQuizListPlayer.tsx @@ -20,7 +20,7 @@ export default function EndQuizListPlayer({ users, maxScore }: Props) { {item.username.toUpperCase()} </Text> <Text style={styles.score}> - {10 + index}/{maxScore} {/* Adjust score logic as needed */} + {item.score}/{maxScore} {/* Adjust score logic as needed */} </Text> </View> </View> diff --git a/components/PlayingQuiz/EndQuiz/UserScore.tsx b/components/PlayingQuiz/EndQuiz/UserScore.tsx index b8f2187..01b80ab 100644 --- a/components/PlayingQuiz/EndQuiz/UserScore.tsx +++ b/components/PlayingQuiz/EndQuiz/UserScore.tsx @@ -9,7 +9,7 @@ interface Props { isFirst: boolean; } -export default function UserScore({ user, score, maxScore, isFirst }: Props) { +export default function UserScore({ user, maxScore, isFirst }: Props) { function shortenString(input: string): string { if (input.length <= 5) { @@ -28,7 +28,7 @@ export default function UserScore({ user, score, maxScore, isFirst }: Props) { </View> <Text style={styles.userName}>{shortenString(user.username.toUpperCase())}</Text> <Text style={styles.userScore}> - {score}/{maxScore} + {user.score}/{maxScore} </Text> </View> ); diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx index 503fc43..e7d8f46 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiMode.tsx @@ -65,7 +65,7 @@ export default function PlayingQuizMultiMode({route, navigation}:Props) { if (!event.data) return; const users: UserEndQuiz[] = JSON.parse(event.data); console.log("users:", users); - navigation.navigate("EndQuizMulti", { users: users }); + navigation.navigate("EndQuizMulti", { users: users, questionCount: questionCount }); }); } const fetchRuns = async () => { diff --git a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx index 729b62c..a2709da 100644 --- a/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx +++ b/screens/Multiplayer/Lobby/PlayingQuizMultiMode/PlayingQuizMultiModeBody.tsx @@ -119,14 +119,15 @@ export default function PlayingQuizMultiModeBody({runId, actualQuestion, fetchAc if(isHost) { await revealAnswer(); - const scoreFetched = await getScore(); - if(HttpError.isHttpError(scoreFetched)) - { - return; - } - setScore(scoreFetched); } + const scoreFetched = await getScore(); + if(HttpError.isHttpError(scoreFetched)) + { + return; + } + setScore(scoreFetched); + }; const onContinue = () => { if(isHost) diff --git a/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx b/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx index 08ddf19..f4ae39d 100644 --- a/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx +++ b/screens/PlayingQuiz/EndQuizMulti/EndQuizMulti.tsx @@ -8,6 +8,7 @@ import {UserEndQuiz} from "../../../models/UserEndQuiz"; type RoutePropsType = { EndQuizChild: { users: UserEndQuiz[]; + questionCount: number; }; }; interface Props { @@ -16,12 +17,12 @@ interface Props { } export default function EndQuizMulti({route,navigation}: Props) { - const { users } = route.params; + const { users, questionCount } = route.params; return ( <View style={styles.containerGlobal}> <TemplateMenu navigation={navigation} headerNavigation={false} buttonGoBack={false}> <View> - <EndQuizMultiChild navigation={navigation} users={users} /> + <EndQuizMultiChild navigation={navigation} users={users} questionCount={questionCount} /> </View> </TemplateMenu> </View> diff --git a/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx b/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx index 87e35c7..866d9bd 100644 --- a/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx +++ b/screens/PlayingQuiz/EndQuizMulti/EndQuizMultiChild.tsx @@ -13,9 +13,10 @@ import {UserEndQuiz} from "../../../models/UserEndQuiz"; interface Props { navigation: NavigationProp<any>; users: UserEndQuiz[] + questionCount: number } -export default function EndQuizMultiChild({ navigation, users }: Props) { +export default function EndQuizMultiChild({ navigation, users, questionCount}: Props) { const userTest = {id: 1, email: "user1@email.com", username: "user1", stats: undefined}; @@ -34,11 +35,11 @@ export default function EndQuizMultiChild({ navigation, users }: Props) { style={styles.stars} /> <View style={styles.usersContainer}> - { users[1] && (<UserScore user={users[1]} score={10} maxScore={10} isFirst={false}/>)} - <UserScore user={users[0]} score={10} maxScore={10} isFirst={true}/> - { users[2] &&(<UserScore user={users[2]} score={10} maxScore={10} isFirst={false}/>)} + { users[1] && (<UserScore user={users[1]} score={10} maxScore={questionCount} isFirst={false}/>)} + <UserScore user={users[0]} score={10} maxScore={questionCount} isFirst={true}/> + { users[2] &&(<UserScore user={users[2]} score={10} maxScore={questionCount} isFirst={false}/>)} </View> - <EndQuizListPlayer users={users} maxScore={10}/> + <EndQuizListPlayer users={users} maxScore={questionCount}/> {/*<DefaultButton text="RESTART" handleButtonPressed={handleRestartPress} buttonStyle={styles.whiteButton} buttonText={styles.whiteButtonText}></DefaultButton>*/} <DefaultButton text="BACK TO MENU" handleButtonPressed={handleBackToMenu} buttonStyle={styles.blueButton} buttonText={styles.blueButtonText}></DefaultButton> -- GitLab