Files
NowChess-Frontend/src/app/pages/welcome/welcome.component.ts
T
2026-04-22 13:05:09 +02:00

186 lines
4.9 KiB
TypeScript

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { finalize } from 'rxjs';
import { getErrorMessage } from '../../core/http/error-message.util';
import { GameApiService } from '../../services/game-api.service';
@Component({
selector: 'app-welcome',
standalone: true,
imports: [CommonModule, FormsModule],
templateUrl: './welcome.component.html',
styleUrl: './welcome.component.css'
})
export class WelcomeComponent {
creating = false;
errorMessage = '';
showDifficultySelector = false;
showJoinGameForm = false;
showImportGameForm = false;
gameIdInput = '';
joiningGame = false;
importing = false;
importMode: 'fen' | 'pgn' = 'fen';
importText = '';
constructor(
private readonly router: Router,
private readonly gameApi: GameApiService
) {
this.initTheme();
}
private initTheme(): void {
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
}
}
startOneVsOne(): void {
if (this.creating) {
return;
}
this.errorMessage = '';
this.creating = true;
this.gameApi
.createGame()
.pipe(finalize(() => (this.creating = false)))
.subscribe({
next: (game) => {
void this.router.navigate(['/game', game.gameId]);
},
error: (error) => {
this.errorMessage = getErrorMessage(error, 'Unable to create a game.');
}
});
}
startVsBot(difficulty: 'easy' | 'medium' | 'hard'): void {
if (this.creating) {
return;
}
this.errorMessage = '';
this.creating = true;
this.showDifficultySelector = false;
this.gameApi
.createGameVsBot(difficulty)
.pipe(finalize(() => (this.creating = false)))
.subscribe({
next: (game) => {
void this.router.navigate(['/game', game.gameId]);
},
error: (error) => {
this.errorMessage = getErrorMessage(error, 'Unable to create a game against bot.');
}
});
}
toggleDifficultySelector(): void {
this.showDifficultySelector = !this.showDifficultySelector;
this.showJoinGameForm = false;
this.showImportGameForm = false;
this.errorMessage = '';
}
toggleJoinGameForm(): void {
this.showJoinGameForm = !this.showJoinGameForm;
this.showDifficultySelector = false;
this.showImportGameForm = false;
this.errorMessage = '';
this.gameIdInput = '';
}
toggleImportGameForm(): void {
this.showImportGameForm = !this.showImportGameForm;
this.showDifficultySelector = false;
this.showJoinGameForm = false;
this.errorMessage = '';
if (!this.showImportGameForm) {
this.importText = '';
this.importMode = 'fen';
}
}
setImportMode(mode: 'fen' | 'pgn'): void {
this.importMode = mode;
this.errorMessage = '';
}
submitImportedGame(): void {
const trimmedImport = this.importText.trim();
if (this.importing || !trimmedImport) {
return;
}
this.errorMessage = '';
this.importing = true;
const importRequest =
this.importMode === 'fen' ? this.gameApi.importFen(trimmedImport) : this.gameApi.importPgn(trimmedImport);
importRequest.pipe(finalize(() => (this.importing = false))).subscribe({
next: (game) => {
this.importText = '';
this.showImportGameForm = false;
void this.router.navigate(['/game', game.gameId]);
},
error: (error) => {
const defaultMessage = this.importMode === 'fen' ? 'Unable to import FEN.' : 'Unable to import PGN.';
this.errorMessage = getErrorMessage(error, defaultMessage);
}
});
}
joinGame(): void {
if (this.joiningGame || !this.gameIdInput.trim()) {
return;
}
this.errorMessage = '';
this.joiningGame = true;
this.gameApi
.getGame(this.gameIdInput.trim())
.pipe(finalize(() => (this.joiningGame = false)))
.subscribe({
next: (game) => {
void this.router.navigate(['/game', game.gameId]);
},
error: (error) => {
this.errorMessage = getErrorMessage(error, 'Unable to find or join the game.');
}
});
}
clearJoinGameForm(): void {
this.showJoinGameForm = false;
this.gameIdInput = '';
this.errorMessage = '';
}
toggleDarkMode(): void {
const htmlElement = document.documentElement;
const isDarkMode = htmlElement.getAttribute('data-theme') === 'dark';
if (isDarkMode) {
htmlElement.removeAttribute('data-theme');
localStorage.removeItem('theme');
} else {
htmlElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
}
}
isDarkMode(): boolean {
return document.documentElement.getAttribute('data-theme') === 'dark';
}
}