98 lines
3.3 KiB
TypeScript
Raw Normal View History

import { Injectable, OnDestroy } from '@angular/core';
import { SettingsService } from './settings.service';
import { SelfUpdaterService } from './self-updater.service';
import { Subject, timer, Subscription } from 'rxjs';
import { ActivationStart, Router } from '@angular/router';
import { SlideShowService } from '../../display/slide-show.service';
import { filter, switchMap } from 'rxjs/operators';
2018-09-11 16:10:47 +02:00
import * as isWithinRange from 'date-fns/is_within_range';
import * as min from 'date-fns/min';
import * as max from 'date-fns/max';
const TIMER_UPDATE_POLL_INTERVAL = 30000;
2018-09-11 16:10:47 +02:00
const TIME_SEPARATOR = ':';
@Injectable()
export class TimerService implements OnDestroy {
public paused = false;
public autoSwitch = false;
private slideShowTimer: Subscription;
private selfUpdateCheckerTimer: Subscription;
private slideTimerSubject: Subject<number> = new Subject<number>();
private slideIntervalSubscription: Subscription;
constructor(private settings: SettingsService,
private selfUpdaterService: SelfUpdaterService,
private router: Router,
private slideShowService: SlideShowService) {
const timerSUC = timer(TIMER_UPDATE_POLL_INTERVAL, TIMER_UPDATE_POLL_INTERVAL);
this.selfUpdateCheckerTimer = timerSUC.subscribe(() => {
this.selfUpdaterService.checkAndReloadIfNecessary();
});
this.slideShowTimer = this.slideTimerSubject
.pipe(switchMap((period: number) => timer(period)))
.subscribe(() => this.changeSlide());
this.setSlideTimer(this.settings.slideInterval);
this.autoSwitch = false;
this.router.events
.pipe(filter(event => event instanceof ActivationStart))
.subscribe((event: ActivationStart) => this.autoSwitch = !!event.snapshot.data.autoSwitchable);
this.slideIntervalSubscription = this.settings.slideIntervalChanged.subscribe(
interval => this.setSlideTimer(interval)
);
}
public ngOnDestroy() {
this.slideShowTimer.unsubscribe();
this.selfUpdateCheckerTimer.unsubscribe();
this.slideIntervalSubscription.unsubscribe();
}
private changeSlide() {
if (!this.paused) {
if (this.autoSwitch && this.isDuringDailyStandup()) {
this.router.navigate(['/kanban']);
}
if (this.autoSwitch && !this.isDuringDailyStandup()) {
this.slideShowService.nextSlide();
}
this.setSlideTimer(this.settings.slideInterval);
2018-09-11 16:10:47 +02:00
}
}
public setSlideTimer(delay: number) {
this.slideTimerSubject.next(delay);
}
2018-09-11 16:10:47 +02:00
public togglePause() {
this.paused = !this.paused;
if (!this.paused) {
this.setSlideTimer(this.settings.slideInterval);
}
}
public pause() {
this.paused = true;
}
2018-09-11 16:10:47 +02:00
private isDuringDailyStandup(): boolean {
if (this.settings.team.dailyLockEnabled) {
const now = new Date();
const startsParts = this.settings.team.dailyStartTime.split(TIME_SEPARATOR).map(part => +part);
const endsParts = this.settings.team.dailyEndTime.split(TIME_SEPARATOR).map(part => +part);
const times = [
new Date(now.getFullYear(), now.getMonth(), now.getDate(), startsParts[0], startsParts[1]),
new Date(now.getFullYear(), now.getMonth(), now.getDate(), endsParts[0], endsParts[1])
2018-09-11 16:10:47 +02:00
];
const startsAt = min(...times);
const endsAt = max(...times);
return isWithinRange(now, startsAt, endsAt);
}
return false;
}
}