66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import { Component, ElementRef, EventEmitter, Input, OnChanges, Output, ViewChild } from '@angular/core';
|
|
|
|
export type MoveNavDirection = 'first' | 'prev' | 'next' | 'last';
|
|
|
|
interface MovePair {
|
|
white: string;
|
|
black: string | null;
|
|
}
|
|
|
|
@Component({
|
|
selector: 'app-move-history',
|
|
standalone: true,
|
|
imports: [],
|
|
templateUrl: './move-history.component.html',
|
|
styleUrl: './move-history.component.css'
|
|
})
|
|
export class MoveHistoryComponent implements OnChanges {
|
|
@Input({ required: true }) moves: string[] = [];
|
|
@Input() viewingPly: number | null = null;
|
|
@Output() navigate = new EventEmitter<MoveNavDirection>();
|
|
@Output() navigateToPly = new EventEmitter<number>();
|
|
|
|
@ViewChild('movesEl') movesEl?: ElementRef<HTMLElement>;
|
|
|
|
movePairs: MovePair[] = [];
|
|
|
|
get plyCount(): number {
|
|
return this.moves.length;
|
|
}
|
|
|
|
get isLive(): boolean {
|
|
return this.viewingPly === null || this.viewingPly >= this.moves.length - 1;
|
|
}
|
|
|
|
ngOnChanges(): void {
|
|
this.movePairs = this.buildPairs(this.moves);
|
|
}
|
|
|
|
isWhiteViewing(pairIndex: number): boolean {
|
|
const ply = this.viewingPly ?? this.moves.length - 1;
|
|
return ply === pairIndex * 2;
|
|
}
|
|
|
|
isBlackViewing(pairIndex: number): boolean {
|
|
const ply = this.viewingPly ?? this.moves.length - 1;
|
|
return ply === pairIndex * 2 + 1;
|
|
}
|
|
|
|
clickWhite(pairIndex: number): void {
|
|
this.navigateToPly.emit(pairIndex * 2);
|
|
}
|
|
|
|
clickBlack(pairIndex: number, black: string | null): void {
|
|
if (!black) return;
|
|
this.navigateToPly.emit(pairIndex * 2 + 1);
|
|
}
|
|
|
|
private buildPairs(moves: string[]): MovePair[] {
|
|
const pairs: MovePair[] = [];
|
|
for (let i = 0; i < moves.length; i += 2) {
|
|
pairs.push({ white: moves[i], black: moves[i + 1] ?? null });
|
|
}
|
|
return pairs;
|
|
}
|
|
}
|