fix: show finished games on watch page instead of hanging spinner (#16)
Summary
▎
▎ - Opening a finished game caused an infinite spinner because the NDJSON stream never delivers events for finished games — it just hangs waiting for events that will never come
▎ - Fix: fetch the full game state via REST on load (GET .../game/{gameId}), apply it to the board immediately, and only open the stream subscription if the game is still ongoing or pending
▎
▎ Changes
▎
▎ - tournament-watch.component.ts — REST fetch now drives the initial state; stream is only started conditionally; extracted applySnapshot(), isFinished(), subscribeToStream()
▎
▎ Test plan
▎
▎ - [ ] Finished game: board shows final position, correct status label, no spinner
▎ - [ ] Live game: board shows current position, stream updates continue to work
▎ - [ ] Pending game: stream starts and updates once the game begins
---------
Co-authored-by: LQ63 <lkhermann@web.de>
Reviewed-on: #16
This commit was merged in pull request #16.
This commit is contained in:
@@ -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.';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user