Add name editing. Add icons for all buttons.

This commit is contained in:
sepia 2025-07-23 16:50:35 -05:00
parent 02d777c364
commit bc45f3a604
13 changed files with 253 additions and 12 deletions

View file

@ -7,7 +7,12 @@ export interface Message {
| 'takeback'
| 'draw'
| 'rematch'
| 'redirect_to_game';
| 'redirect_to_game'
| 'update_display_name';
}
export interface UpdateDisplayNameMessage extends Message {
displayName: string;
}
export interface MakeMoveMessage extends Message {

View file

@ -10,6 +10,7 @@ import {
DrawMessage,
RematchMessage,
RedirectToGameMessage,
UpdateDisplayNameMessage,
} from './messages';
import { v4 as uuidv4 } from 'uuid';
@ -27,6 +28,7 @@ class PlayerConnection {
}
public sendMessage(severity: 'info' | 'error', message: string) {
console.log(`Sending message ${message} to player ${this.id}`);
// TODO
}
}
@ -146,17 +148,26 @@ class GameServer {
if (this.takebackRequesterId === conn.id) {
buttons.push(
<button id="cancel-takeback-request-button" ws-send="click">
<svg class="icon" alt="Cancel">
<use href="/icons/decline.svg"></use>
</svg>
Cancel Takeback Request
</button>,
);
} else {
buttons.push(
<button id="accept-takeback-button" ws-send="click">
<svg class="icon" alt="Accept">
<use href="/icons/accept.svg"></use>
</svg>
Accept Takeback
</button>,
);
buttons.push(
<button id="decline-takeback-button" ws-send="click">
<svg class="icon" alt="Decline">
<use href="/icons/decline.svg"></use>
</svg>
Decline Takeback
</button>,
);
@ -165,17 +176,26 @@ class GameServer {
if (this.drawRequesterId === conn.id) {
buttons.push(
<button id="cancel-draw-request-button" ws-send="click">
<svg class="icon" alt="Cancel">
<use href="/icons/decline.svg"></use>
</svg>
Cancel Draw Request
</button>,
);
} else {
buttons.push(
<button id="accept-draw-button" ws-send="click">
<svg class="icon" alt="Accept">
<use href="/icons/accept.svg"></use>
</svg>
Accept Draw
</button>,
);
buttons.push(
<button id="decline-draw-button" ws-send="click">
<svg class="icon" alt="Decline">
<use href="/icons/decline.svg"></use>
</svg>
Decline Draw
</button>,
);
@ -183,16 +203,25 @@ class GameServer {
} else {
buttons.push(
<button id="resign-button" ws-send="click">
<svg class="icon" alt="Resign">
<use href="/icons/resign.svg"></use>
</svg>
Resign
</button>,
);
buttons.push(
<button id="takeback-button" ws-send="click">
<svg class="icon" alt="Takeback">
<use href="/icons/undo.svg"></use>
</svg>
Takeback
</button>,
);
buttons.push(
<button id="draw-button" ws-send="click">
<svg class="icon" alt="Draw">
<use href="/icons/draw.svg"></use>
</svg>
Draw
</button>,
);
@ -202,17 +231,26 @@ class GameServer {
if (this.rematchRequesterId === conn.id) {
buttons.push(
<button id="cancel-rematch-request-button" ws-send="click">
<svg class="icon" alt="Cancel">
<use href="/icons/decline.svg"></use>
</svg>
Cancel Rematch Request
</button>,
);
} else {
buttons.push(
<button id="accept-rematch-button" ws-send="click">
<svg class="icon" alt="Accept">
<use href="/icons/accept.svg"></use>
</svg>
Accept Rematch
</button>,
);
buttons.push(
<button id="decline-rematch-button" ws-send="click">
<svg class="icon" alt="Decline">
<use href="/icons/decline.svg"></use>
</svg>
Decline Rematch
</button>,
);
@ -220,6 +258,9 @@ class GameServer {
} else {
buttons.push(
<button id="rematch-button" ws-send="click">
<svg class="icon" alt="Rematch">
<use href="/icons/rotate-right.svg"></use>
</svg>
Rematch
</button>,
);
@ -248,7 +289,7 @@ class GameServer {
const classes = `player-name ${'player-' + color} ${turnClass}`.trim();
return (
<span class={classes}>
{playerId}
{this.connections.get(playerId)?.name}
{connectionIcon}
</span>
);
@ -287,6 +328,10 @@ class GameServer {
this.handleRematchMessage(conn, message as RematchMessage);
break;
}
case 'update_display_name': {
this.handleUpdateDisplayName(conn, message as UpdateDisplayNameMessage);
break;
}
}
}
@ -588,6 +633,37 @@ class GameServer {
this.rematchRequesterId = null;
this.broadcastButtons();
}
private handleUpdateDisplayName(
conn: PlayerConnection,
message: UpdateDisplayNameMessage,
): void {
const newDisplayName = message.displayName.trim();
if (!newDisplayName) {
conn.sendMessage('error', 'Display name cannot be empty.');
return;
}
if (newDisplayName.length > 20) {
conn.sendMessage(
'error',
'Display name cannot be longer than 20 characters.',
);
return;
}
if (newDisplayName === conn.name) {
return; // No change, do nothing
}
conn.name = newDisplayName;
this.broadcastTitle();
conn.sendMessage(
'info',
`Your display name has been updated to "${newDisplayName}".`,
);
}
}
export class WebSocketHandler {