diff --git a/package-lock.json b/package-lock.json index 950ef1f..4ad2174 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "jeopardy", - "version": "1.0.6", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jeopardy", - "version": "1.0.6", + "version": "2.0.0", "dependencies": { "axios": "^1.12.2", "cookie": "^1.0.2" diff --git a/package.json b/package.json index 8d08c11..1dfd41a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jeopardy", "private": true, - "version": "1.0.6", + "version": "2.0.0", "type": "module", "scripts": { "dev": "vite dev", diff --git a/src/lib/DisplayState.svelte.ts b/src/lib/DisplayState.svelte.ts index 7228c8c..eee4ea4 100644 --- a/src/lib/DisplayState.svelte.ts +++ b/src/lib/DisplayState.svelte.ts @@ -1,4 +1,4 @@ -import type { FullGame, FullWall } from "./games/games"; +import type { Game, Wall } from "./Types"; interface Player { name: string; @@ -8,10 +8,9 @@ interface Player { const baseRoute = "/connected/display/running"; let players: Player[] = $state([]); let currentPlayer: string = $state(""); -// eslint-disable-next-line prefer-const -let game: FullGame | undefined = undefined; +let game: Game | undefined = $state(); let gameIndex: number = -1; -let wall: FullWall | undefined = undefined; +let wall: Wall | undefined = $state(); let wallIndex: number = -1; export default { @@ -29,7 +28,7 @@ export default { currentPlayer = str; }, baseRoute, - get game(): FullGame | undefined { + get game(): Game | undefined { return game; }, // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -42,7 +41,7 @@ export default { set gameIndex(i: number) { gameIndex = i; }, - get wall(): FullWall | undefined { + get wall(): Wall | undefined { return wall; }, // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/lib/Types.ts b/src/lib/Types.ts index 492d667..f4df0dd 100644 --- a/src/lib/Types.ts +++ b/src/lib/Types.ts @@ -8,7 +8,7 @@ import type { SimpleQuestion } from "./games/games"; -export type VisitedQuestions = number[][]; +export type VisitedQuestions = QuestionId[]; export type Directory = { name: string; diff --git a/src/lib/Wall.svelte b/src/lib/Wall.svelte index dbb8571..8b7950b 100644 --- a/src/lib/Wall.svelte +++ b/src/lib/Wall.svelte @@ -24,10 +24,6 @@ isEditor?: boolean; } - function isVisited(catIndex: number, queIndex: number): boolean { - return visited[catIndex] && visited[catIndex].includes(queIndex); - } - let { wall, onclick, onclickIds, visited, isEditor = false }: Props = $props(); let categories: Category[] = $state([]); @@ -107,10 +103,10 @@ > {/if} - {#each category.questions as question, queIndex} + {#each category.questions as question}
-
{category.name}
-
- {#each category.questions as question, queIndex} - -
{ - if (onclick) onclick(catIndex, queIndex); - }} - > -
- {question.points >= 0 ? question.points : "???"} -
-
- {/each} - {/each} + Legacy Not Supported {/if} {:else} diff --git a/src/routes/connected/display/running/[game]/+layout.svelte b/src/routes/connected/display/running/[game]/+layout.svelte index 8e35c41..ef51e10 100644 --- a/src/routes/connected/display/running/[game]/+layout.svelte +++ b/src/routes/connected/display/running/[game]/+layout.svelte @@ -2,29 +2,17 @@ let { children } = $props(); import { error } from "@sveltejs/kit"; - import games from "$lib/games/games"; + // import games from "$lib/games/games"; import { page } from "$app/state"; import DisplayStateSvelte from "$lib/DisplayState.svelte"; + import { onMount } from "svelte"; + import { fetchGame } from "../../../../editor/fetchers"; - console.log("game:", page.params.game); - - let paramGame = page.params.game; - if (paramGame === undefined) { - error(404); - } - const gameIndex = parseInt(paramGame); - if (isNaN(gameIndex)) { - error(404); - } - if (DisplayStateSvelte.gameIndex !== gameIndex) { - const game = games[gameIndex]; - if (game) { + onMount(() => { + fetchGame(`${page.params.game}`).then((game) => { DisplayStateSvelte.game = game; - DisplayStateSvelte.gameIndex = gameIndex; - } else { - error(404); - } - } + }); + });
diff --git a/src/routes/connected/display/running/[game]/[wall]/+page.svelte b/src/routes/connected/display/running/[game]/[wall]/+page.svelte index 21a72aa..acfd8b0 100644 --- a/src/routes/connected/display/running/[game]/[wall]/+page.svelte +++ b/src/routes/connected/display/running/[game]/[wall]/+page.svelte @@ -6,27 +6,11 @@ import ws from "$lib/websocket.svelte"; import { MessageType } from "$lib/MessageType"; import type { VisitedQuestions } from "$lib/Types"; + import { onMount } from "svelte"; + import { fetchWall } from "../../../../../editor/fetchers"; console.log("wall:", page.params.wall); - let paramWall = page.params.wall; - if (paramWall === undefined) { - error(404); - } - const wallIndex = parseInt(paramWall); - if (isNaN(wallIndex)) { - error(404); - } - if (DisplayStateSvelte.wallIndex !== wallIndex) { - const wall = DisplayStateSvelte.game?.walls[wallIndex]; - if (wall) { - DisplayStateSvelte.wall = wall; - DisplayStateSvelte.gameIndex = wallIndex; - } else { - error(404); - } - } - let visited: VisitedQuestions = $state([]); $effect(() => { @@ -40,6 +24,12 @@ } } catch (e) {} }); + + onMount(() => { + fetchWall(`${page.params.wall}`).then((wall) => { + DisplayStateSvelte.wall = wall; + }); + }); diff --git a/src/routes/connected/display/running/[game]/[wall]/[category]/[question]/+page.svelte b/src/routes/connected/display/running/[game]/[wall]/[category]/[question]/+page.svelte index c3e5dbf..d735080 100644 --- a/src/routes/connected/display/running/[game]/[wall]/[category]/[question]/+page.svelte +++ b/src/routes/connected/display/running/[game]/[wall]/[category]/[question]/+page.svelte @@ -9,65 +9,22 @@ isImageMultipleChoiceQuestion, isImageQuestion, isMultipleChoiceQuestion, - isSimpleQuestion + isSimpleQuestion, + type Question } from "$lib/games/games"; import ws from "$lib/websocket.svelte"; import { MessageType } from "$lib/MessageType"; - import { untrack } from "svelte"; + import { onMount, untrack } from "svelte"; import MultipleChoiceQuestionComponent from "$lib/MultipleChoiceQuestionComponent.svelte"; import ImageQuestionComponent from "$lib/ImageQuestionComponent.svelte"; import AudioQuestionComponent from "$lib/AudioQuestionComponent.svelte"; import AudioMultipleChoiceQuestionComponent from "$lib/AudioMultipleChoiceQuestionComponent.svelte"; import ImageMultipleChoiceQuestionComponent from "$lib/ImageMultipleChoiceQuestionComponent.svelte"; + import { fetchCategory, fetchQuestion } from "../../../../../../../editor/fetchers"; + import type { Category, GeneralQuestion } from "$lib/Types"; - console.log("wall:", page.params.wall); - - let paramWall = page.params.wall; - if (paramWall === undefined) { - error(404); - } - const wallIndex = parseInt(paramWall); - if (isNaN(wallIndex)) { - error(404); - } - if (DisplayStateSvelte.wallIndex !== wallIndex) { - const wall = DisplayStateSvelte.game?.walls[wallIndex]; - if (wall) { - DisplayStateSvelte.wall = wall; - DisplayStateSvelte.gameIndex = wallIndex; - } else { - error(404); - } - } - if (page.params.category === undefined) { - error(404); - } - const categoryIndex = parseInt(page.params.category); - if (isNaN(categoryIndex)) { - error(404); - } - - const category = DisplayStateSvelte.wall?.categories[categoryIndex]; - - if (category === undefined) { - error(404); - } - - if (page.params.question === undefined) { - error(404); - } - const questionIndex = parseInt(page.params.question); - if (isNaN(questionIndex)) { - error(404); - } - - const question = category.questions[questionIndex]; - - console.log(question); - - if (question === undefined) { - error(404); - } + let category: Category | undefined = $state(); + let question: GeneralQuestion | undefined = $state(); let showAnswer = $state(false); let showQuestion = $state(false); @@ -118,42 +75,71 @@ } } catch (e) {} }); + + onMount(() => { + fetchCategory(`${page.params.category}`) + .then((cat) => { + category = cat; + return fetchQuestion(`${page.params.question}`); + }) + .then((que) => { + question = que; + }); + }); -
-
-
{category.name}
-
- {question.points} Punkte +{#if category && question} +
+
+
{category.name}
+
+ {question.points} Punkte +
+
+
+ {#if question === undefined} +

Question is undefined

+ {:else if isSimpleQuestion(question)} + + {:else if isMultipleChoiceQuestion(question)} + + {:else if isImageQuestion(question)} + + {:else if isImageMultipleChoiceQuestion(question)} + + {:else if isAudioQuestion(question)} + + {:else if isAudioMultipleChoiceQuestion(question)} + + {:else} +

Type of question unknown

+ {/if}
-
- {#if question === undefined} -

Question is undefined

- {:else if isSimpleQuestion(question)} - - {:else if isMultipleChoiceQuestion(question)} - - {:else if isImageQuestion(question)} - - {:else if isImageMultipleChoiceQuestion(question)} - - {:else if isAudioQuestion(question)} - - {:else if isAudioMultipleChoiceQuestion(question)} - - {:else} -

Type of question unknown

- {/if} -
-
+{:else} + Loading... +{/if} diff --git a/src/routes/connected/games/+page.server.ts b/src/routes/connected/games/+page.server.ts deleted file mode 100644 index f1264e9..0000000 --- a/src/routes/connected/games/+page.server.ts +++ /dev/null @@ -1,7 +0,0 @@ -import games from '$lib/games/games'; - -export function load() { - return { - games - }; -} diff --git a/src/routes/connected/games/+page.svelte b/src/routes/connected/games/+page.svelte index c9acd01..cc2c38e 100644 --- a/src/routes/connected/games/+page.svelte +++ b/src/routes/connected/games/+page.svelte @@ -1,14 +1,39 @@

Games

- {#each data.games as game, i} + {#each games as game} {game.name}{game.name} {/each}
diff --git a/src/routes/connected/games/[game]/+page.server.ts b/src/routes/connected/games/[game]/+page.server.ts deleted file mode 100644 index 583a1b1..0000000 --- a/src/routes/connected/games/[game]/+page.server.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { error } from '@sveltejs/kit'; -import games from '$lib/games/games'; - -export function load({ params }) { - const index = parseInt(params.game); - if (isNaN(index)) { - error(404); - } - const game = games[index]; - if (game === undefined) error(404); - else return game; -} diff --git a/src/routes/connected/games/[game]/+page.svelte b/src/routes/connected/games/[game]/+page.svelte index 2b9bd9a..7440efa 100644 --- a/src/routes/connected/games/[game]/+page.svelte +++ b/src/routes/connected/games/[game]/+page.svelte @@ -9,7 +9,8 @@ isAudioQuestion, isAudioMultipleChoiceQuestion, isImageMultipleChoiceQuestion, - type FullGame + type FullGame, + type Question } from "$lib/games/games"; import ws from "$lib/websocket.svelte"; import { page } from "$app/state"; @@ -18,12 +19,14 @@ import Scoreboard from "$lib/Scoreboard.svelte"; import SimpleQuestionComponent from "$lib/SimpleQuestionComponent.svelte"; import PlusMinusButton from "$lib/PlusMinusButton.svelte"; - import type { VisitedQuestions } from "$lib/Types.js"; + import type { _id, Category, Game, VisitedQuestions, Wall as WallType } from "$lib/Types.js"; import MultipleChoiceQuestionComponent from "$lib/MultipleChoiceQuestionComponent.svelte"; import ImageQuestionComponent from "$lib/ImageQuestionComponent.svelte"; import AudioQuestionComponent from "$lib/AudioQuestionComponent.svelte"; import AudioMultipleChoiceQuestionComponent from "$lib/AudioMultipleChoiceQuestionComponent.svelte"; import ImageMultipleChoiceQuestionComponent from "$lib/ImageMultipleChoiceQuestionComponent.svelte"; + import { fetchCategory, fetchGame, fetchQuestion, fetchWall } from "../../../editor/fetchers"; + import { onMount } from "svelte"; interface SaveData { players: Player[]; @@ -57,7 +60,7 @@ class GameManager { public state: GameState = $state(GameState.INIT); - public game: FullGame; + public game: Game | undefined = $state(); public players: Player[] = $state([ { name: "Player 1", @@ -74,37 +77,42 @@ ]); public currentPlayer = $state(0); - public currentWall = $state(0); + public currentWallIndex = $state(0); + public currentWall: WallType | undefined = $state(); public visitedQuestions: VisitedQuestions = $state([]); - public currentCategory = $state(0); - public currentQuestion = $state(0); + public currentCategoryId = $state(""); + public currentCategory: Category | undefined = $state(); + public currentQuestionId = $state(""); + public currentQuestion: Question | undefined = $state(); public answerIsShowing = $state(false); public questionIsShowing = $state(false); public isBuzzed = $state(false); - constructor(game: FullGame) { + setGame(game: Game) { this.game = game; } save(): void { + if (!this.game) return; const saveData = { players: this.players, currentPlayer: this.currentPlayer, - currentWall: this.currentWall, + currentWall: this.currentWallIndex, visitedQuestions: this.visitedQuestions }; - localStorage.setItem(`saveGame-${this.game.name}`, JSON.stringify(saveData)); + localStorage.setItem(`saveGame-${this.game._id}`, JSON.stringify(saveData)); } load(): void { - const saveDataString = localStorage.getItem(`saveGame-${this.game.name}`); + if (!this.game) return; + const saveDataString = localStorage.getItem(`saveGame-${this.game._id}`); if (saveDataString === null) return; try { const saveData: SaveData = JSON.parse(saveDataString); this.players = saveData.players; this.currentPlayer = saveData.currentPlayer; - this.currentWall = saveData.currentWall; + this.currentWallIndex = saveData.currentWall; this.visitedQuestions = saveData.visitedQuestions; console.log(saveData); } catch (e) { @@ -113,10 +121,14 @@ } startGame(): void { + if (!this.game) return; this.currentPlayer = Math.floor(Math.random() * this.players.length); this.state = GameState.CHOOSING_QUESTION; - this.sendStart(); - this.sendCurrentState(); + fetchWall(this.game.walls[this.currentWallIndex]).then((wall) => { + this.currentWall = wall; + this.sendStart(); + this.sendCurrentState(); + }); } sendStart(): void { @@ -136,7 +148,7 @@ sendWall(): void { ws.sendMessage({ type: MessageType.GOTO, - route: `/${page.params.game}/${this.currentWall}` + route: `/${page.params.game}/${this.currentWall?._id}` }); this.sendVisited(); } @@ -154,30 +166,39 @@ } sendCurrentQuestion(): void { + if (!this.game) return; ws.sendMessage({ type: MessageType.GOTO, - route: `/${page.params.game}/${this.currentWall}/${this.currentCategory}/${this.currentQuestion}` + route: `/${this.game._id}/${this.currentWall?._id}/${this.currentCategoryId}/${this.currentQuestionId}` }); } sendEnd(): void { ws.sendMessage({ type: MessageType.GOTO, - route: `/${page.params.game}/${this.currentWall}/end` + route: `/${page.params.game}/${this.currentWall?._id}/end` }); } - tileClicked(categoryIndex: number, questionIndex: number) { - console.log("Cat", categoryIndex, "Que", questionIndex); - console.log(gameManager.wall.categories[categoryIndex]?.questions[questionIndex]); + tileClicked(catId: _id, queId: _id) { + console.log("Cat", catId, "Que", queId); - this.currentCategory = categoryIndex; - this.currentQuestion = questionIndex; + this.currentCategoryId = catId; + this.currentQuestionId = queId; this.answerIsShowing = false; - this.sendCurrentQuestion(); + fetchCategory(this.currentCategoryId) + .then((category) => { + this.currentCategory = category; - this.state = GameState.SHOW_QUESTION; + return fetchQuestion(this.currentQuestionId); + }) + .then((question) => { + this.currentQuestion = question; + + this.sendCurrentQuestion(); + this.state = GameState.SHOW_QUESTION; + }); } addPlayer() { @@ -236,20 +257,21 @@ } plus(player: Player) { - if (!this.answerIsShowing) return; + if (!this.answerIsShowing || !this.currentQuestion) return; if (player.name === this.currentPlayerToName()) { - player.points += this.question.points * 2; + player.points += this.currentQuestion.points * 2; } else { - player.points += this.question.points; + player.points += this.currentQuestion.points; } this.sendPlayers(); } minus(player: Player) { + if (!this.currentQuestion) return; if (player.name === this.currentPlayerToName()) { - player.points -= this.question.points * 2; + player.points -= this.currentQuestion.points * 2; } else { - player.points -= this.question.points; + player.points -= this.currentQuestion.points; } this.sendPlayers(); } @@ -267,12 +289,8 @@ } finishQuestion(): void { - if (this.visitedQuestions[this.currentCategory] == undefined) { - this.visitedQuestions[this.currentCategory] = [this.currentQuestion]; - } else if ( - !this.visitedQuestions[this.currentCategory].includes(this.currentQuestion) - ) { - this.visitedQuestions[this.currentCategory].push(this.currentQuestion); + if (!this.visitedQuestions.includes(this.currentQuestionId)) { + this.visitedQuestions.push(this.currentQuestionId); } this.setupGoingBack(); this.nextPlayer(); @@ -286,28 +304,21 @@ } wallIsDone(): boolean { - let visitedNum = 0; - for (const questions of this.visitedQuestions) { - if (questions != undefined) { - visitedNum += questions.length; - } - } - let totalNum = 0; - for (const category of this.wall.categories) { - totalNum += category.questions.length; - } - console.log(`${visitedNum} >= ${totalNum}`); - return visitedNum >= totalNum; + return this.visitedQuestions.length >= 25; } goToNextWall(): void { - if (this.currentWall + 1 >= this.game.walls.length) { + if (!this.game) return; + if (this.currentWallIndex + 1 >= this.game.walls.length) { this.goToEndScreen(); } else { - this.currentWall += 1; + this.currentWallIndex += 1; this.visitedQuestions = []; - this.sendWall(); - this.state = GameState.CHOOSING_QUESTION; + fetchWall(this.game.walls[this.currentWallIndex]).then((wall) => { + this.currentWall = wall; + this.sendWall(); + this.state = GameState.CHOOSING_QUESTION; + }); } } @@ -324,169 +335,175 @@ currentPlayerToName(): string { return this.players[this.currentPlayer].name; } - - get wall() { - return this.game.walls[this.currentWall]; - } - - get category() { - return this.wall.categories[this.currentCategory]; - } - - get question() { - return this.category.questions[this.currentQuestion]; - } } - let { data } = $props(); + let gameManager = new GameManager(); - let gameManager = new GameManager(data); + onMount(() => { + fetchGame(`${page.params.game}`).then((game) => { + gameManager.game = game; + }); + }); -
-

{gameManager.game.name}

- {#if gameManager.state === GameState.INIT} -
-
-

Spieler

- - +

{gameManager.game.name}

+ {#if gameManager.state === GameState.INIT} +
+
+

Spieler

+ + +
+
+ {#each gameManager.players as player, i} +
+ + +
+ {/each} +
+
-
- {#each gameManager.players as player, i} -
- - -
- {/each} -
- -
- {:else} -
- gameManager.sendPlayers()} - /> - {#if gameManager.state === GameState.SHOW_QUESTION} -
-
-
{gameManager.category.name}
-
- {gameManager.question.points} Punkte + {:else} +
+ gameManager.sendPlayers()} + /> + {#if gameManager.state === GameState.SHOW_QUESTION} +
+
+
{gameManager.currentCategory?.name}
+
+ {gameManager.currentQuestion?.points} Punkte +
+
+
+ {#if gameManager.currentQuestion === undefined} +

Question is undefined

+ {:else if isSimpleQuestion(gameManager.currentQuestion)} + + {:else if isMultipleChoiceQuestion(gameManager.currentQuestion)} + + {:else if isImageQuestion(gameManager.currentQuestion)} + + {:else if isImageMultipleChoiceQuestion(gameManager.currentQuestion)} + + {:else if isAudioQuestion(gameManager.currentQuestion)} + + {:else if isAudioMultipleChoiceQuestion(gameManager.currentQuestion)} + + {:else} +

Type of question unknown

+ {/if} +
+
+ + {#if gameManager.questionIsShowing} + + {:else} + + {/if} + {#if gameManager.answerIsShowing} + + {:else} + + {/if} + {#if gameManager.isBuzzed} + + {:else} + + {/if} + {#each gameManager.players as player} + gameManager.plus(player)} + minus={() => gameManager.minus(player)} + showPlus={gameManager.answerIsShowing} + /> + {/each} +
+ {#if gameManager.answerIsShowing} + + {/if}
-
- {#if gameManager.question === undefined} -

Question is undefined

- {:else if isSimpleQuestion(gameManager.question)} - - {:else if isMultipleChoiceQuestion(gameManager.question)} - - {:else if isImageQuestion(gameManager.question)} - - {:else if isImageMultipleChoiceQuestion(gameManager.question)} - - {:else if isAudioQuestion(gameManager.question)} - - {:else if isAudioMultipleChoiceQuestion(gameManager.question)} - - {:else} -

Type of question unknown

- {/if} + {:else if gameManager.state === GameState.END} +
+
ENDE
-
- - {#if gameManager.questionIsShowing} - - {:else} - - {/if} - {#if gameManager.answerIsShowing} - - {:else} - - {/if} - {#if gameManager.isBuzzed} - - {:else} - - {/if} - {#each gameManager.players as player} - gameManager.plus(player)} - minus={() => gameManager.minus(player)} - showPlus={gameManager.answerIsShowing} - /> - {/each} -
- {#if gameManager.answerIsShowing} - - {/if} + {:else} +
+ gameManager.tileClicked(cat, que)} + visited={gameManager.visitedQuestions} + />
-
- {:else if gameManager.state === GameState.END} -
ENDE
- {:else} -
- gameManager.tileClicked(cat, que)} - visited={gameManager.visitedQuestions} - /> -
- {/if} -
- {/if} -
+ {/if} +
+ {/if} +
+{:else} + Loading Game... +{/if} diff --git a/src/routes/editor/[gameid]/[wallid]/[categoryid]/[questionid]/+page.svelte b/src/routes/editor/[gameid]/[wallid]/[categoryid]/[questionid]/+page.svelte index bbb59e5..d520ae3 100644 --- a/src/routes/editor/[gameid]/[wallid]/[categoryid]/[questionid]/+page.svelte +++ b/src/routes/editor/[gameid]/[wallid]/[categoryid]/[questionid]/+page.svelte @@ -218,8 +218,15 @@
- +
+ + +
{#if isSimpleQuestion(question)}