diff --git a/index.html b/index.html
index 81b2f59..c3096ad 100644
--- a/index.html
+++ b/index.html
@@ -18,7 +18,7 @@
diff --git a/public/icons/disconnected.svg b/public/icons/disconnected.svg
new file mode 100755
index 0000000..d78a8f7
--- /dev/null
+++ b/public/icons/disconnected.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/public/style.css b/public/style.css
index c39e1c0..95d497b 100644
--- a/public/style.css
+++ b/public/style.css
@@ -1,6 +1,6 @@
:root {
--color-background-light-pink: #ffe0f0;
- --color-text-dark: #333;
+ --color-text: #333;
--color-game-container-bg: white;
--color-game-container-shadow: rgba(0, 0, 0, 0.1);
--color-board-bg: #ffefff;
@@ -23,7 +23,7 @@ body {
min-height: 100vh;
margin: 0;
background-color: var(--color-background-light-pink);
- color: var(--color-text-dark);
+ color: var(--color-text);
}
#game-container {
@@ -122,13 +122,12 @@ body {
#messages {
margin-top: 10px;
font-size: 0.9em;
- color: var(--color-text-dark);
+ color: var(--color-text);
}
-#player-info {
- margin-top: 10px;
+#title-box {
font-weight: bold;
- color: var(--color-text-dark);
+ color: var(--color-text);
}
#game-link-container {
@@ -140,25 +139,20 @@ body {
margin-top: 20px;
}
-#copy-link-button,
-#copy-success-message {
+#copy-link-button {
position: absolute;
- left: 50%;
- transform: translateX(-50%);
display: flex;
justify-content: center;
align-items: center;
- top: 0; bottom: 0;
transition: opacity 0.3s ease;
padding: 8px 15px;
border-radius: 5px;
white-space: nowrap;
- box-sizing: border-box;
}
#copy-link-button {
background-color: var(--color-board-border);
- color: var(--color-text-dark);
+ color: var(--color-text);
border: none;
cursor: pointer;
gap: 8px;
@@ -173,7 +167,8 @@ body {
background-color: var(--color-success-purple);
}
-#copy-link-button img.icon {
- width: 20px;
- height: 20px;
+img.icon {
+ width: 1em;
+ height: 1em;
+ vertical-align: middle;
}
diff --git a/src/view/board-renderer.ts b/src/view/board-renderer.ts
index c3468ae..92b0abe 100644
--- a/src/view/board-renderer.ts
+++ b/src/view/board-renderer.ts
@@ -52,6 +52,6 @@ export function renderGameBoardHtml(
return boardHtml;
}
-export function renderPlayerInfoHtml(gameId: string, playerId: string): string {
- return `You are: ${playerId}
Game ID: ${gameId}
`;
+export function renderTitleBoxHtml(gameId: string, playerId: string): string {
+ return `You are: ${playerId}
Game ID: ${gameId}
`;
}
diff --git a/src/web-socket-handler.ts b/src/web-socket-handler.ts
index 82083f2..0cd58c0 100644
--- a/src/web-socket-handler.ts
+++ b/src/web-socket-handler.ts
@@ -2,7 +2,6 @@ import { ElysiaWS } from 'elysia/dist/ws';
import { GameInstance } from './game/game-instance';
import {
renderGameBoardHtml,
- renderPlayerInfoHtml,
} from './view/board-renderer';
interface MakeMoveMessage {
@@ -109,7 +108,7 @@ export class WebSocketHandler {
}
this.connections.set(
gameId,
- connectionsInGame.filter((conn) => conn !== ws),
+ connectionsInGame.filter((conn) => conn.data.query.playerId !== ws.data.query.playerId),
);
if (this.connections.get(gameId)?.length === 0) {
this.connections.delete(gameId);
@@ -119,6 +118,9 @@ export class WebSocketHandler {
// Notify remaining players about disconnect
this.sendMessageToGame(gameId, `${playerId} disconnected.`);
}
+
+ this.sendTitleBoxesForGame(gameId);
+
console.log(`${playerId} disconnected from game ${gameId}`);
}
@@ -138,8 +140,6 @@ export class WebSocketHandler {
const updatedBoardHtml = renderGameBoardHtml(game, playerId);
ws.send(updatedBoardHtml);
- const updatedPlayerInfoHtml = renderPlayerInfoHtml(game.id, playerId);
- ws.send(updatedPlayerInfoHtml);
if (game.status === 'finished') {
if (game.winner === 'draw') {
@@ -166,13 +166,15 @@ export class WebSocketHandler {
} else {
console.log(`No connections to update for game ${gameId}.`);
}
+
+ this.sendTitleBoxesForGame(gameId);
}
public sendMessageToGame(gameId: string, message: string): void {
const connections = this.connections.get(gameId);
if (connections) {
connections.forEach((ws) => {
- ws.send('' + message + '
');
+ this.sendMessage(ws, message);
});
}
}
@@ -181,6 +183,64 @@ export class WebSocketHandler {
targetWs.send('' + message + '
');
}
+ private sendTitleBox(targetWs: WS, message: string): void {
+ targetWs.send('' + message + '
');
+ }
+
+ private sendTitleBoxesForGame(gameId: string): void {
+ const game = this.games.get(gameId);
+ if (!game) {
+ console.error(`Tried to send title boxes for game ${gameId}, but it doesn't exist!`)
+ return;
+ }
+ const connections = this.connections.get(gameId);
+ if (!connections) {
+ console.log(`Attempted to send title boxes for game ${gameId}, but no players are connected.`)
+ return;
+ }
+
+ var message = "";
+ switch (game.status) {
+ case 'waiting': {
+ message = "Waiting for players...";
+ }
+ case 'playing': {
+ const blackTag = game.players.black ? this.playerTag(gameId, game.players.black) : 'Unknown';
+ const whiteTag = game.players.white ? this.playerTag(gameId, game.players.white) : 'Unknown';
+ message = `${blackTag} vs ${whiteTag}`;
+ }
+ case 'finished': {
+ switch (game.winner) {
+ case 'draw': {
+ message = "Game ended in draw.";
+ }
+ case 'black': {
+ message = `${game.players.black} wins!`;
+ }
+ case 'white': {
+ message = `${game.players.white} wins!`;
+ }
+ }
+ }
+ }
+
+ connections.forEach((connection) => {this.sendTitleBox(connection, message)});
+ }
+
+ private playerTag(gameId: string, playerId: string) {
+ var connectionIcon = `
`
+ const connections = this.connections.get(gameId);
+ if (connections) {
+ connections.forEach((ws) => {
+ if (ws.data.query.playerId === playerId) {
+ console.log(`Connection exists for player ${playerId}`);
+ connectionIcon = '';
+ }
+ });
+ }
+ return `${playerId}${connectionIcon}`
+ }
+
public getGame(gameId: string): GameInstance | undefined {
return this.games.get(gameId);
}