Subscribe outside the Angular zone.
Emit the timeout inside the Angular zone (optional, some components maybe does not use OnPush)
Throttling the DOM events every second
const expired$: Subject<boolean> = new Subject<boolean>();
const _resetTimerSubj = new BehaviorSubject(1);
const _stopWatching = new Subject<void>();
constructor(private zone: NgZone) {
}
public startWatching(timeOutSeconds): Observable<any> {
const timeOutMilliSeconds = timeOutSeconds * 1000;
const idleAndTimeout$ = merge(
this._resetTimerSubj, // for reset timer
fromEvent(document, 'mousemove'),
fromEvent(document, 'click'),
fromEvent(document, 'mousedown'),
fromEvent(document, 'keypress'),
fromEvent(document, 'DOMMouseScroll'),
fromEvent(document, 'mousewheel'),
fromEvent(document, 'touchmove'),
fromEvent(document, 'MSPointerMove'),
fromEvent(window, 'mousemove'),
fromEvent(window, 'resize')
).pipe(
throttleTime(1000),
switchMap((x) => timer(timeOutMilliSeconds, timeOutMilliSeconds)),
takeUntil(this._stopWatching)
);
this.zone.runOutsideAngular(() => {
idleAndTimeout$.subscribe({
next: (x) => { this.zone.run(() =>this.expired$.next(true) ) },
error: (err: any) => { this.zone.run(() => this.expired$.error(err)) },
complete: () => { this.zone.run(() => this.expired$.complete() )},
});
});
return this.expired$.asObservable();
}
public resetTimer() {
this._resetTimerSubj.next(1)
}
// stopTimer
public stopWatching() {
this._stopWatching.next();
}
Hi,
This is a very helpful service.
I think the following changes will make it even better in terms of the performance of the app and using more Rxjs operators
Subscribe outside the Angular zone.
Emit the timeout inside the Angular zone (optional, some components maybe does not use OnPush)
Throttling the DOM events every second
stopTimer could be called it stopWatching?
`
`