From 985f6d9bf9fcc313e378d2f0b0e374c6611e7fab Mon Sep 17 00:00:00 2001 From: Jonas Kappa Date: Sat, 6 Sep 2025 01:50:13 +0200 Subject: [PATCH] Almost done --- src/app.css | 4 + src/lib/DisplayState.svelte.ts | 58 ++++ src/lib/GameState.svelte.ts | 10 + src/lib/GameState.ts | 6 + src/lib/MessageType.ts | 8 + .../connected/games/[game] => lib}/Player.ts | 0 src/lib/PlusMinusButton.svelte | 37 ++ src/lib/Scoreboard.svelte | 42 +++ src/lib/SimpleQuestionComponent.svelte | 22 ++ src/lib/Types.ts | 1 + src/lib/Wall.svelte | 49 +++ src/lib/games/games.ts | 11 +- src/lib/websocket.svelte.ts | 12 +- src/routes/connected/+layout.svelte | 1 + src/routes/connected/display/+layout.svelte | 30 ++ src/routes/connected/display/+page.svelte | 12 - .../connected/display/running/+layout.svelte | 32 ++ .../connected/display/running/+page.svelte | 0 .../display/running/[game]/+layout.svelte | 39 +++ .../running/[game]/[wall]/+page.svelte | 45 +++ .../[wall]/[category]/[question]/+page.svelte | 99 ++++++ .../running/[game]/[wall]/end/+page.svelte | 40 +++ src/routes/connected/games/+layout.svelte | 19 + .../connected/games/[game]/+page.svelte | 326 +++++++++++++++--- .../connected/games/[game]/GameState.ts | 4 - src/routes/connected/games/[game]/Wall.svelte | 23 -- 26 files changed, 832 insertions(+), 98 deletions(-) create mode 100644 src/lib/DisplayState.svelte.ts create mode 100644 src/lib/GameState.svelte.ts create mode 100644 src/lib/GameState.ts create mode 100644 src/lib/MessageType.ts rename src/{routes/connected/games/[game] => lib}/Player.ts (100%) create mode 100644 src/lib/PlusMinusButton.svelte create mode 100644 src/lib/Scoreboard.svelte create mode 100644 src/lib/SimpleQuestionComponent.svelte create mode 100644 src/lib/Types.ts create mode 100644 src/lib/Wall.svelte create mode 100644 src/routes/connected/display/+layout.svelte create mode 100644 src/routes/connected/display/running/+layout.svelte create mode 100644 src/routes/connected/display/running/+page.svelte create mode 100644 src/routes/connected/display/running/[game]/+layout.svelte create mode 100644 src/routes/connected/display/running/[game]/[wall]/+page.svelte create mode 100644 src/routes/connected/display/running/[game]/[wall]/[category]/[question]/+page.svelte create mode 100644 src/routes/connected/display/running/[game]/[wall]/end/+page.svelte create mode 100644 src/routes/connected/games/+layout.svelte delete mode 100644 src/routes/connected/games/[game]/GameState.ts delete mode 100644 src/routes/connected/games/[game]/Wall.svelte diff --git a/src/app.css b/src/app.css index 230536e..c5f29de 100644 --- a/src/app.css +++ b/src/app.css @@ -1,6 +1,10 @@ @import "tailwindcss"; @layer components { + html { + background-color: rgb(230, 230, 230); + } + .btn { border: 1px solid black; border-radius: 5px; diff --git a/src/lib/DisplayState.svelte.ts b/src/lib/DisplayState.svelte.ts new file mode 100644 index 0000000..452230e --- /dev/null +++ b/src/lib/DisplayState.svelte.ts @@ -0,0 +1,58 @@ +import type { Game, Wall } from "./games/games"; + +interface Player { + name: string; + points: number; +} + +const baseRoute = "/connected/display/running"; +let players: Player[] = $state([]); +let currentPlayer: string = $state(""); +// eslint-disable-next-line prefer-const +let game: Game | undefined = undefined; +let gameIndex: number = -1; +let wall: Wall | undefined = undefined; +let wallIndex: number = -1; + +export default { + get players(): Player[] { + return players; + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + set players(newPlayers: any) { + players = newPlayers; + }, + get currentPlayer(): string { + return currentPlayer; + }, + set currentPlayer(str: string) { + currentPlayer = str; + }, + baseRoute, + get game(): Game | undefined { + return game; + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + set game(newGame: any) { + game = newGame; + }, + get gameIndex() { + return gameIndex; + }, + set gameIndex(i: number) { + gameIndex = i; + }, + get wall(): Wall | undefined { + return wall; + }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + set wall(newWall: any) { + wall = newWall; + }, + get wallIndex() { + return wallIndex; + }, + set wallIndex(i: number) { + wallIndex = i; + } +}; diff --git a/src/lib/GameState.svelte.ts b/src/lib/GameState.svelte.ts new file mode 100644 index 0000000..44ab3c6 --- /dev/null +++ b/src/lib/GameState.svelte.ts @@ -0,0 +1,10 @@ +let displayConnected = $state(false); + +export default { + get displayConnected() { + return displayConnected; + }, + set displayConnected(c: boolean) { + displayConnected = c; + } +}; diff --git a/src/lib/GameState.ts b/src/lib/GameState.ts new file mode 100644 index 0000000..1c6a553 --- /dev/null +++ b/src/lib/GameState.ts @@ -0,0 +1,6 @@ +export enum GameState { + INIT, + CHOOSING_QUESTION, + SHOW_QUESTION, + END +} diff --git a/src/lib/MessageType.ts b/src/lib/MessageType.ts new file mode 100644 index 0000000..c2addef --- /dev/null +++ b/src/lib/MessageType.ts @@ -0,0 +1,8 @@ +export enum MessageType { + START = "START", + PLAYERS = "PLAYERS", + GOTO = "GOTO", + SHOW_ANSWER = "SHOW_ANSWER", + HIDE_ANSWER = "HIDE_ANSWER", + VISITED_QUESTIONS = "VISITED_QUESTIONS" +} diff --git a/src/routes/connected/games/[game]/Player.ts b/src/lib/Player.ts similarity index 100% rename from src/routes/connected/games/[game]/Player.ts rename to src/lib/Player.ts diff --git a/src/lib/PlusMinusButton.svelte b/src/lib/PlusMinusButton.svelte new file mode 100644 index 0000000..bb42211 --- /dev/null +++ b/src/lib/PlusMinusButton.svelte @@ -0,0 +1,37 @@ + + +
+ +
+ {label} +
+ +
+ + diff --git a/src/lib/Scoreboard.svelte b/src/lib/Scoreboard.svelte new file mode 100644 index 0000000..be26c7c --- /dev/null +++ b/src/lib/Scoreboard.svelte @@ -0,0 +1,42 @@ + + +
+
+

Scoreboard

+
+
+ + + {#each _players() as player} + + + + + {/each} + +
{player.points}{player.name}
+
+
+ + diff --git a/src/lib/SimpleQuestionComponent.svelte b/src/lib/SimpleQuestionComponent.svelte new file mode 100644 index 0000000..5d1207c --- /dev/null +++ b/src/lib/SimpleQuestionComponent.svelte @@ -0,0 +1,22 @@ + + +
+
+
{question.data.question}
+
+ {#if showAnswer} +
+ {question.data.answer} +
+ {/if} +
diff --git a/src/lib/Types.ts b/src/lib/Types.ts new file mode 100644 index 0000000..b2149b0 --- /dev/null +++ b/src/lib/Types.ts @@ -0,0 +1 @@ +export type VisitedQuestions = number[][]; diff --git a/src/lib/Wall.svelte b/src/lib/Wall.svelte new file mode 100644 index 0000000..29573ea --- /dev/null +++ b/src/lib/Wall.svelte @@ -0,0 +1,49 @@ + + +{#if wall != undefined} +
+ {#each wall.categories as category, catIndex} +
+
{category.name}
+
+ {#each category.questions as question, queIndex} + +
{ + if (onclick) onclick(catIndex, queIndex); + }} + > +
{question.points}
+
+ {/each} + {/each} +
+{:else} +

Wall is undefined

+{/if} + + diff --git a/src/lib/games/games.ts b/src/lib/games/games.ts index 6e9574b..fa24c9f 100644 --- a/src/lib/games/games.ts +++ b/src/lib/games/games.ts @@ -931,9 +931,11 @@ const games: Games = [ } ]; +export type QuestionType = "SIMPLE" | "MULTIPLE_CHOICE"; + export type Question = { points: number; - type: "SIMPLE" | "MULTIPLE_CHOICE"; + type: QuestionType; }; export type SimpleQuestion = Question & { @@ -953,6 +955,13 @@ export type MultipleChoiceQuestion = Question & { }; }; +export function isSimpleQuestion(question: Question): question is SimpleQuestion { + return (question as SimpleQuestion).type === "SIMPLE"; +} +export function isMultipleChoiceQuestion(question: Question): question is MultipleChoiceQuestion { + return (question as MultipleChoiceQuestion).type === "MULTIPLE_CHOICE"; +} + export type Category = { name: string; questions: (SimpleQuestion | MultipleChoiceQuestion)[]; diff --git a/src/lib/websocket.svelte.ts b/src/lib/websocket.svelte.ts index 6b16087..d520043 100644 --- a/src/lib/websocket.svelte.ts +++ b/src/lib/websocket.svelte.ts @@ -1,7 +1,7 @@ export enum SocketConnectionType { - NONE, - HOST, - DISPLAY + NONE = "NONE", + HOST = "HOST", + DISPLAY = "DISPLAY" } const messages: string[] = $state([]); @@ -41,7 +41,7 @@ function onOpen(type: SocketConnectionType) { console.log("Connection established"); console.log(event); if (socket === undefined) return; - socket.send(type == SocketConnectionType.HOST ? "HOST" : "DISPLAY"); + socket.send(type.toString()); }; } @@ -49,11 +49,11 @@ function onOpen(type: SocketConnectionType) { function onFirstMessage(event: MessageEvent) { if (socket === undefined) return; console.log(event.data); - if (event.data === "HOST") { + if (event.data === SocketConnectionType.HOST) { connectionType = SocketConnectionType.HOST; socket.removeEventListener("message", onFirstMessage); socket.addEventListener("message", onMessage); - } else if (event.data === "DISPLAY") { + } else if (event.data === SocketConnectionType.DISPLAY) { connectionType = SocketConnectionType.DISPLAY; socket.removeEventListener("message", onFirstMessage); socket.addEventListener("message", onMessage); diff --git a/src/routes/connected/+layout.svelte b/src/routes/connected/+layout.svelte index 57794d1..59821f3 100644 --- a/src/routes/connected/+layout.svelte +++ b/src/routes/connected/+layout.svelte @@ -5,6 +5,7 @@ let { children } = $props(); $effect(() => { + console.log("ConnectionType:", ws.connectionType); if (ws.connectionType === SocketConnectionType.NONE) { goto("/"); } diff --git a/src/routes/connected/display/+layout.svelte b/src/routes/connected/display/+layout.svelte new file mode 100644 index 0000000..2fc2ae5 --- /dev/null +++ b/src/routes/connected/display/+layout.svelte @@ -0,0 +1,30 @@ + + +{@render children?.()} diff --git a/src/routes/connected/display/+page.svelte b/src/routes/connected/display/+page.svelte index 7b18919..381f398 100644 --- a/src/routes/connected/display/+page.svelte +++ b/src/routes/connected/display/+page.svelte @@ -1,15 +1,3 @@ - -

Waiting for game to start

diff --git a/src/routes/connected/display/running/+layout.svelte b/src/routes/connected/display/running/+layout.svelte new file mode 100644 index 0000000..b476147 --- /dev/null +++ b/src/routes/connected/display/running/+layout.svelte @@ -0,0 +1,32 @@ + + +
+ +
+ {@render children?.()} +
+
diff --git a/src/routes/connected/display/running/+page.svelte b/src/routes/connected/display/running/+page.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/routes/connected/display/running/[game]/+layout.svelte b/src/routes/connected/display/running/[game]/+layout.svelte new file mode 100644 index 0000000..8e35c41 --- /dev/null +++ b/src/routes/connected/display/running/[game]/+layout.svelte @@ -0,0 +1,39 @@ + + +
+
+

+ {DisplayStateSvelte.game?.name} +

+
+
+ {@render children?.()} +
+
diff --git a/src/routes/connected/display/running/[game]/[wall]/+page.svelte b/src/routes/connected/display/running/[game]/[wall]/+page.svelte new file mode 100644 index 0000000..21a72aa --- /dev/null +++ b/src/routes/connected/display/running/[game]/[wall]/+page.svelte @@ -0,0 +1,45 @@ + + + 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 new file mode 100644 index 0000000..b0d9caf --- /dev/null +++ b/src/routes/connected/display/running/[game]/[wall]/[category]/[question]/+page.svelte @@ -0,0 +1,99 @@ + + +
+
+
{category.name}
+
+ {question.points} Punkte +
+
+
+ {#if question === undefined} +

Question is undefined

+ {:else if isSimpleQuestion(question)} + + {:else} +

Type of question unknown: {question.type}

+ {/if} +
+
diff --git a/src/routes/connected/display/running/[game]/[wall]/end/+page.svelte b/src/routes/connected/display/running/[game]/[wall]/end/+page.svelte new file mode 100644 index 0000000..daadde5 --- /dev/null +++ b/src/routes/connected/display/running/[game]/[wall]/end/+page.svelte @@ -0,0 +1,40 @@ + + +
+
Herzlichen Glückwunsch
+ {#each winners() as player} +
+ {player.name} +
+ {/each} +
+ {#if winners().length > 1} + haben + {:else} + hat + {/if} + gewonnen! +
+
+ + diff --git a/src/routes/connected/games/+layout.svelte b/src/routes/connected/games/+layout.svelte new file mode 100644 index 0000000..e431b74 --- /dev/null +++ b/src/routes/connected/games/+layout.svelte @@ -0,0 +1,19 @@ + + +{@render children?.()} diff --git a/src/routes/connected/games/[game]/+page.svelte b/src/routes/connected/games/[game]/+page.svelte index fb9f894..686b933 100644 --- a/src/routes/connected/games/[game]/+page.svelte +++ b/src/routes/connected/games/[game]/+page.svelte @@ -1,40 +1,72 @@
@@ -93,21 +258,78 @@

Spieler

- gameManager.startGame()}>Start
{#each gameManager.players as player, i}
- +
{/each}
- +
{:else} - +
+ + {#if gameManager.state === GameState.SHOW_QUESTION} +
+
+ {#if gameManager.question === undefined} +

Question is undefined

+ {:else if isSimpleQuestion(gameManager.question)} + + {:else} +

Type of question unknown: {gameManager.question.type}

+ {/if} +
+
+ + {#if gameManager.answerIsShowing} + + {:else} + + {/if} + {#each gameManager.players as player} + gameManager.plus(player)} + minus={() => gameManager.minus(player)} + /> + {/each} + +
+
+ {:else if gameManager.state === GameState.END} +
ENDE
+ {:else} +
+ gameManager.tileClicked(cat, que)} + visited={gameManager.visitedQuestions} + /> +
+ {/if} +
{/if}
diff --git a/src/routes/connected/games/[game]/GameState.ts b/src/routes/connected/games/[game]/GameState.ts deleted file mode 100644 index 5096ed4..0000000 --- a/src/routes/connected/games/[game]/GameState.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum GameState { - INIT, - CHOOSING_QUESTION -} diff --git a/src/routes/connected/games/[game]/Wall.svelte b/src/routes/connected/games/[game]/Wall.svelte deleted file mode 100644 index 5605b10..0000000 --- a/src/routes/connected/games/[game]/Wall.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - -
- {#each wall.categories as category} -
-
{category.name}
-
- {#each category.questions as question} -
-
{question.points}
-
- {/each} - {/each} -