v0.9.1 web ui fixes and improvements
This commit is contained in:
@ -5,7 +5,8 @@ let gameState = {
|
||||
turn: 'w',
|
||||
isPlayerWhite: true,
|
||||
isLocked: false,
|
||||
pollInterval: null,
|
||||
polling: false,
|
||||
pollController: null,
|
||||
apiUrl: '',
|
||||
selectedSquare: null,
|
||||
healthCheckInterval: null,
|
||||
@ -672,41 +673,64 @@ async function triggerComputerMove() {
|
||||
}
|
||||
|
||||
function startPolling() {
|
||||
gameState.pollInterval = setInterval(async () => {
|
||||
try {
|
||||
const response = await fetch(`${gameState.apiUrl}/api/v1/games/${gameState.gameId}`);
|
||||
if (!response.ok) {
|
||||
const errorInfo = handleApiError('poll game state', null, response);
|
||||
if (response.status === 404) {
|
||||
stopPolling();
|
||||
unlockBoard();
|
||||
flashErrorMessage('Game no longer exists');
|
||||
gameState.gameId = null;
|
||||
return;
|
||||
}
|
||||
// Non-404: already displayed by handleApiError above, keep polling
|
||||
return;
|
||||
}
|
||||
|
||||
const game = await response.json();
|
||||
if (game.state !== 'pending') {
|
||||
stopPolling();
|
||||
updateGameDisplay(game);
|
||||
unlockBoard();
|
||||
}
|
||||
gameState.networkError = false;
|
||||
updateServerIndicator('healthy');
|
||||
} catch (error) {
|
||||
handleApiError('poll game state', error);
|
||||
stopPolling();
|
||||
unlockBoard();
|
||||
}
|
||||
}, 1500);
|
||||
gameState.polling = true;
|
||||
pollOnce();
|
||||
}
|
||||
|
||||
function stopPolling() {
|
||||
clearInterval(gameState.pollInterval);
|
||||
gameState.pollInterval = null;
|
||||
gameState.polling = false;
|
||||
if (gameState.pollController) {
|
||||
gameState.pollController.abort();
|
||||
gameState.pollController = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function pollOnce() {
|
||||
if (!gameState.polling || !gameState.gameId) return;
|
||||
|
||||
const moveCount = (gameState.moveList || []).length;
|
||||
gameState.pollController = new AbortController();
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`${gameState.apiUrl}/api/v1/games/${gameState.gameId}?wait=true&moveCount=${moveCount}`,
|
||||
{ signal: gameState.pollController.signal }
|
||||
);
|
||||
|
||||
if (!gameState.polling) return;
|
||||
|
||||
if (!response.ok) {
|
||||
const errorInfo = handleApiError('poll game state', null, response);
|
||||
if (response.status === 404) {
|
||||
stopPolling();
|
||||
unlockBoard();
|
||||
flashErrorMessage('Game no longer exists');
|
||||
gameState.gameId = null;
|
||||
return;
|
||||
}
|
||||
// Retry after delay for transient errors
|
||||
setTimeout(pollOnce, 2000);
|
||||
return;
|
||||
}
|
||||
|
||||
const game = await response.json();
|
||||
gameState.networkError = false;
|
||||
updateServerIndicator('healthy');
|
||||
|
||||
if (game.state !== 'pending') {
|
||||
stopPolling();
|
||||
updateGameDisplay(game);
|
||||
unlockBoard();
|
||||
} else {
|
||||
// Still pending, long-poll again
|
||||
pollOnce();
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.name === 'AbortError') return;
|
||||
handleApiError('poll game state', error);
|
||||
stopPolling();
|
||||
unlockBoard();
|
||||
}
|
||||
}
|
||||
|
||||
function lockBoard() {
|
||||
|
||||
Reference in New Issue
Block a user