186 lines
4.9 KiB
TypeScript
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';
|
|
}
|
|
}
|