fix: show finished games on watch page instead of hanging spinner

Previously, navigating to a finished game caused the watch page to spin
forever because the stream never delivers events for finished games.

Fix by fetching the full game state via REST on load (GET .../game/{gameId}),
applying it immediately to the board, and only starting the stream subscription
if the game is still ongoing or pending.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
LQ63
2026-06-28 19:52:05 +02:00
parent 8603222ab4
commit 076ff17281
2 changed files with 52 additions and 7 deletions
@@ -59,19 +59,43 @@ export class TournamentWatchComponent implements OnInit {
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe({
next: game => {
this.whiteName = game.white?.name ?? null;
this.blackName = game.black?.name ?? null;
this.applySnapshot(game);
this.connecting = false;
if (!this.isFinished(game.status)) {
this.subscribeToStream();
}
},
error: err => {
this.connecting = false;
this.error = (err as Error).message ?? 'Failed to load game.';
},
});
}
private applySnapshot(game: GameStateSnapshot): void {
this.whiteName = game.white?.name ?? null;
this.blackName = game.black?.name ?? null;
this.snapshot = game;
this.fen = game.fen;
this.turn = game.turn;
this.status = game.status;
this.winner = game.winner;
this.clock = game.clock ?? null;
this.moves = game.moves ? game.moves.split(/\s+/).filter(Boolean) : [];
}
private isFinished(status: GameStatus): boolean {
return status !== 'pending' && status !== 'ongoing';
}
private subscribeToStream(): void {
this.stream.streamGame(this.serverUrl, this.tournamentId, this.gameId)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe({
next: ev => this.apply(ev),
error: err => {
this.connecting = false;
this.error = (err as Error).message ?? 'Stream failed.';
}
},
});
}