v0.9.1 web ui fixes and improvements
This commit is contained in:
@ -5,7 +5,8 @@ let gameState = {
|
|||||||
turn: 'w',
|
turn: 'w',
|
||||||
isPlayerWhite: true,
|
isPlayerWhite: true,
|
||||||
isLocked: false,
|
isLocked: false,
|
||||||
pollInterval: null,
|
polling: false,
|
||||||
|
pollController: null,
|
||||||
apiUrl: '',
|
apiUrl: '',
|
||||||
selectedSquare: null,
|
selectedSquare: null,
|
||||||
healthCheckInterval: null,
|
healthCheckInterval: null,
|
||||||
@ -672,41 +673,64 @@ async function triggerComputerMove() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startPolling() {
|
function startPolling() {
|
||||||
gameState.pollInterval = setInterval(async () => {
|
gameState.polling = true;
|
||||||
try {
|
pollOnce();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopPolling() {
|
function stopPolling() {
|
||||||
clearInterval(gameState.pollInterval);
|
gameState.polling = false;
|
||||||
gameState.pollInterval = null;
|
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() {
|
function lockBoard() {
|
||||||
|
|||||||
Reference in New Issue
Block a user