Files
JoshHeaps.Net/JoshHeaps.Net/wwwroot/js/ChessScripts/ChessSignalR.js
T
Josh-HeapsandClaude Opus 4.8 c92c46e6d4 Render the board from pushed state
Clients now render from the state delivered with each move/update and
drop stale or echoed updates via a ply-version guard, instead of issuing
a full game-state fetch per event. Adds captured-piece trays, a material
advantage badge, a move list, a status line, and the mobile menu toggle.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-10 16:58:22 -06:00

71 lines
2.3 KiB
JavaScript

const ChessSignalR = {
connection: null,
async setupConnection() {
this.connection = new signalR.HubConnectionBuilder()
.withUrl("/chessHub")
.configureLogging(signalR.LogLevel.Information)
.build();
this.connection.onclose(err => {
console.error("❌ SignalR connection closed:", err?.message);
});
this.connection.on("ReceiveMoveUpdate", async (gameId, moveDto, moveResultDto, state) => {
await this.handleMoveUpdate(gameId, moveDto, moveResultDto, state);
});
this.connection.on("ReceiveGameOver", async (gameId, winner, reason) => {
await this.handleGameOver(gameId, winner, reason);
});
try {
await this.connection.start();
console.log("✅ SignalR connected");
await this.connection.invoke("JoinWebsocketGroup", GameState.currentGameId);
} catch (err) {
console.error("❌ SignalR failed to start or join:", err);
}
},
async handleMoveUpdate(gameId, moveDto, moveResultDto, state) {
if (gameId !== GameState.currentGameId) return;
// Drop the echo of our own move and any out-of-order delivery.
if (!GameState.shouldApply(state?.version)) return;
GameState.setPreviousMove([moveDto.sourceRow, moveDto.sourceCol], [moveDto.targetRow, moveDto.targetCol]);
ChessBoard.renderState(state);
ChessAPI.alertGameStatusChange(moveResultDto);
},
async handleGameOver(gameId, winner, reason) {
if (gameId !== GameState.currentGameId) return;
const youWon = (winner === "White") === GameState.currentPlayerIsWhite;
if (reason === "forfeit")
alert(youWon ? "🏳️ Your opponent forfeited — you win!" : "🏳️ You forfeited this game.");
showCopyPgn(gameId);
await this.leaveGame();
},
async leaveGame() {
if (this.connection) {
await this.connection.invoke("LeaveWebsocketGroup", GameState.currentGameId);
await this.connection.stop();
this.connection = null;
}
},
async stopConnection() {
if (this.connection) {
await this.connection.stop();
this.connection = null;
}
}
};
console.log("ChessSignalR.js loaded");