Files
NowChess-Frontend/src/app/pages/games/games.component.ts
T
shosho996 95eff42dfe fix: NCWF-4 Token Issues (#8)
Co-authored-by: Lala, Shahd <Shahd.Lala@sybit.de>
Co-authored-by: shahdlala66 <shahd.lala66@gmail.com>
Reviewed-on: #8
2026-06-02 21:55:55 +02:00

108 lines
3.3 KiB
TypeScript

import { Component, DestroyRef, OnInit, inject } from '@angular/core';
import { Router, RouterLink } from '@angular/router';
import { forkJoin, of } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { AuthService } from '../../services/auth.service';
import { GameApiService } from '../../services/game-api.service';
import { GameHistoryService } from '../../services/game-history.service';
import { GameFull, GameStatus } from '../../models/game.models';
type GamesTab = 'active' | 'history';
const FINISHED_STATUSES: GameStatus[] = [
'checkmate', 'stalemate', 'resign', 'draw', 'insufficientMaterial'
];
@Component({
selector: 'app-games',
standalone: true,
imports: [RouterLink],
templateUrl: './games.component.html',
styleUrl: './games.component.css'
})
export class GamesComponent implements OnInit {
private readonly destroyRef = inject(DestroyRef);
private readonly router = inject(Router);
private readonly authService = inject(AuthService);
private readonly gameApi = inject(GameApiService);
private readonly gameHistory = inject(GameHistoryService);
tab: GamesTab = 'active';
loading = true;
activeGames: GameFull[] = [];
finishedGames: GameFull[] = [];
ngOnInit(): void {
this.authService.currentUser$
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((user) => {
if (!user) void this.router.navigate(['/']);
});
this.loadGames();
}
setTab(tab: GamesTab): void {
this.tab = tab;
}
resumeGame(gameId: string): void {
void this.router.navigate(['/game', gameId]);
}
removeGame(gameId: string): void {
this.gameHistory.removeGame(gameId);
this.activeGames = this.activeGames.filter((g) => g.gameId !== gameId);
this.finishedGames = this.finishedGames.filter((g) => g.gameId !== gameId);
}
statusLabel(status: GameStatus): string {
const labels: Record<GameStatus, string> = {
started: 'In Progress',
check: 'Check',
checkmate: 'Checkmate',
stalemate: 'Stalemate',
resign: 'Resigned',
draw: 'Draw',
drawOffered: 'Draw Offered',
fiftyMoveAvailable: 'In Progress',
promotionPending: 'In Progress',
insufficientMaterial: 'Draw'
};
return labels[status] ?? status;
}
isFinished(status: GameStatus): boolean {
return FINISHED_STATUSES.includes(status);
}
private loadGames(): void {
const ids = this.gameHistory.getGameIds();
if (ids.length === 0) {
this.loading = false;
return;
}
const requests = ids.map((id) =>
this.gameApi.getGame(id).pipe(
catchError((err: unknown) => {
if (typeof err === 'object' && err !== null && (err as { status: number }).status === 404) {
this.gameHistory.removeGame(id);
}
return of(null);
})
)
);
forkJoin(requests)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((results) => {
const valid = results.filter((g): g is GameFull => g !== null);
this.activeGames = valid.filter((g) => !FINISHED_STATUSES.includes(g.state.status));
this.finishedGames = valid.filter((g) => FINISHED_STATUSES.includes(g.state.status));
this.loading = false;
});
}
}