Add cancellation buttons for draw, rematch, takeback requests

This commit is contained in:
sepia 2025-07-22 20:47:05 -05:00
parent 2f46d86947
commit 904a9f973f
3 changed files with 115 additions and 7 deletions

View File

@ -51,5 +51,17 @@ document.addEventListener('htmx:wsConfigSend', function (e) {
e.detail.parameters = { e.detail.parameters = {
type: 'decline_rematch', type: 'decline_rematch',
}; };
} else if (e.target.id == 'cancel-takeback-request-button') {
e.detail.parameters = {
type: 'cancel_takeback_request',
};
} else if (e.target.id == 'cancel-draw-request-button') {
e.detail.parameters = {
type: 'cancel_draw_request',
};
} else if (e.target.id == 'cancel-rematch-request-button') {
e.detail.parameters = {
type: 'cancel_rematch_request',
};
} }
}); });

View File

@ -11,7 +11,10 @@ export interface Message {
| 'request_rematch' | 'request_rematch'
| 'accept_rematch' | 'accept_rematch'
| 'decline_rematch' | 'decline_rematch'
| 'redirect_to_game'; | 'redirect_to_game'
| 'cancel_takeback_request'
| 'cancel_draw_request'
| 'cancel_rematch_request';
} }
export interface MakeMoveMessage extends Message { export interface MakeMoveMessage extends Message {
@ -42,3 +45,9 @@ export interface DeclineRematchMessage extends Message {}
export interface RedirectToGameMessage extends Message { export interface RedirectToGameMessage extends Message {
gameId: string; gameId: string;
} }
export interface CancelTakebackRequestMessage extends Message {}
export interface CancelDrawRequestMessage extends Message {}
export interface CancelRematchRequestMessage extends Message {}

View File

@ -16,6 +16,9 @@ import {
AcceptRematchMessage, AcceptRematchMessage,
DeclineRematchMessage, DeclineRematchMessage,
RedirectToGameMessage, RedirectToGameMessage,
CancelTakebackRequestMessage,
CancelDrawRequestMessage,
CancelRematchRequestMessage,
} from './messages'; } from './messages';
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
@ -150,8 +153,8 @@ class GameServer {
if (this.takebackRequesterId) { if (this.takebackRequesterId) {
if (this.takebackRequesterId === conn.id) { if (this.takebackRequesterId === conn.id) {
buttonsHtml = ( buttonsHtml = (
<button id="takeback-button" disabled> <button id="cancel-takeback-request-button" ws-send="click">
Takeback Requested Cancel Takeback Request
</button> </button>
); );
} else { } else {
@ -169,8 +172,8 @@ class GameServer {
} else if (this.drawRequesterId) { } else if (this.drawRequesterId) {
if (this.drawRequesterId === conn.id) { if (this.drawRequesterId === conn.id) {
buttonsHtml = ( buttonsHtml = (
<button id="draw-button" disabled> <button id="cancel-draw-request-button" ws-send="click">
Draw Requested Cancel Draw Request
</button> </button>
); );
} else { } else {
@ -204,8 +207,8 @@ class GameServer {
if (this.rematchRequesterId) { if (this.rematchRequesterId) {
if (this.rematchRequesterId === conn.id) { if (this.rematchRequesterId === conn.id) {
buttonsHtml = ( buttonsHtml = (
<button id="rematch-button" disabled> <button id="cancel-rematch-request-button" ws-send="click">
Rematch Requested Cancel Rematch Request
</button> </button>
); );
} else { } else {
@ -304,6 +307,24 @@ class GameServer {
this.handleDeclineRematch(conn, message as DeclineRematchMessage); this.handleDeclineRematch(conn, message as DeclineRematchMessage);
break; break;
} }
case 'cancel_takeback_request': {
this.handleCancelTakebackRequest(
conn,
message as CancelTakebackRequestMessage,
);
break;
}
case 'cancel_draw_request': {
this.handleCancelDrawRequest(conn, message as CancelDrawRequestMessage);
break;
}
case 'cancel_rematch_request': {
this.handleCancelRematchRequest(
conn,
message as CancelRematchRequestMessage,
);
break;
}
} }
} }
@ -592,6 +613,72 @@ class GameServer {
this.rematchRequesterId = null; this.rematchRequesterId = null;
this.broadcastButtons(); this.broadcastButtons();
} }
private handleCancelTakebackRequest(
conn: PlayerConnection,
message: CancelTakebackRequestMessage,
): void {
if (this.gomoku.status !== 'playing') {
conn.sendMessage(
'error',
'You can only cancel a takeback request in an active game.',
);
return;
}
if (this.takebackRequesterId !== conn.id) {
conn.sendMessage(
'error',
'You are not the one who requested a takeback.',
);
return;
}
this.takebackRequesterId = null;
this.broadcastButtons();
}
private handleCancelDrawRequest(
conn: PlayerConnection,
message: CancelDrawRequestMessage,
): void {
if (this.gomoku.status !== 'playing') {
conn.sendMessage(
'error',
'You can only cancel a draw request in an active game.',
);
return;
}
if (this.drawRequesterId !== conn.id) {
conn.sendMessage('error', 'You are not the one who requested a draw.');
return;
}
this.drawRequesterId = null;
this.broadcastButtons();
}
private handleCancelRematchRequest(
conn: PlayerConnection,
message: CancelRematchRequestMessage,
): void {
if (this.gomoku.status !== 'finished') {
conn.sendMessage(
'error',
'You can only cancel a rematch request in a finished game.',
);
return;
}
if (this.rematchRequesterId !== conn.id) {
conn.sendMessage('error', 'You are not the one who requested a rematch.');
return;
}
this.rematchRequesterId = null;
this.broadcastButtons();
}
} }
export class WebSocketHandler { export class WebSocketHandler {