Add surrender and rematch UI - Part 1

- Add surrender button to game controls
- Add game-over modal with stats and rematch option
- Add surrender confirmation modal
- Add all CSS styling for new modals and buttons
- Add surrender-rematch.js with global helper functions
- Update multiplayer.js constructor to track opponent for rematch
This commit is contained in:
2025-12-22 17:39:43 +11:00
parent 6c4aedec1d
commit 622a7e4094
5 changed files with 554 additions and 70 deletions

View File

@@ -0,0 +1,71 @@
// Surrender game
surrenderGame() {
if (!this.isMultiplayer || !this.currentGameId) {
this.showMessage('No active game to surrender', 'error');
return;
}
this.socket.emit('surrender', { gameId: this.currentGameId });
}
// Handle rematch request from opponent
handleRematchRequest(data) {
const notification = document.createElement('div');
notification.className = 'challenge-notification';
notification.innerHTML = `
<div class="challenge-content">
<h3>Rematch Request!</h3>
<p><strong>${data.from}</strong> wants a rematch</p>
<p>Board size: ${data.boardSize}×${data.boardSize}</p>
<div class="challenge-actions">
<button class="accept-btn" onclick="multiplayerClient.acceptRematch('${data.rematchId}')">
Accept
</button>
<button class="decline-btn" onclick="multiplayerClient.declineRematch('${data.rematchId}')">
Decline
</button>
</div>
</div>
`;
document.body.appendChild(notification);
setTimeout(() => notification.classList.add('active'), 10);
}
// Send rematch request
sendRematchRequest() {
if (!this.opponentId) {
this.showMessage('No opponent to challenge', 'error');
return;
}
this.socket.emit('send_rematch', {
opponentId: this.opponentId,
boardSize: this.selectedBoardSize
});
this.showMessage(`Rematch request sent to ${this.opponent}`, 'info');
document.getElementById('gameOverModal').classList.remove('active');
}
// Accept rematch
acceptRematch(rematchId) {
this.socket.emit('accept_rematch', { rematchId });
// Hide game over modal
document.getElementById('gameOverModal').classList.remove('active');
// Remove notification
const notifications = document.querySelectorAll('.challenge-notification');
notifications.forEach(n => n.remove());
}
// Decline rematch
declineRematch(rematchId) {
this.socket.emit('decline_rematch', { rematchId });
// Remove notification
const notifications = document.querySelectorAll('.challenge-notification');
notifications.forEach(n => n.remove());
}