import { ChangeDetectionStrategy, Component, effect, input, output } from '@angular/core'; import { toSignal } from '@angular/core/rxjs-interop'; import { Subject, timer } from 'rxjs'; import { map, startWith, switchMap, takeWhile, tap } from 'rxjs/operators'; @Component({ standalone: true, selector: 'app-game-timer', template: `
{{ timer() }}
`, changeDetection: ChangeDetectionStrategy.OnPush, }) export class GameTimerComponent { initialSeconds = input(0); resetKey = input(0); timerExpired = output(); private resetSubject = new Subject(); private hasEmittedExpiration = false; constructor() { effect(() => { this.resetKey(); this.hasEmittedExpiration = false; this.resetSubject.next(); }); } timer$ = this.resetSubject.pipe( startWith(null), switchMap(() => timer(0, 1000).pipe( map((tick) => this.initialSeconds() - tick), takeWhile((seconds) => seconds >= 0) ) ), tap((seconds) => { if (seconds === 0 && !this.hasEmittedExpiration) { this.hasEmittedExpiration = true; this.timerExpired.emit(); } }) ); timer = toSignal(this.timer$, { initialValue: 0 }); }