From 11010f85f2dc85f9de850958140d9bf379a7f143 Mon Sep 17 00:00:00 2001 From: Derek Wang Date: Fri, 1 Nov 2024 14:42:50 +0800 Subject: [PATCH] refactor: fix idle detection timeout dialog still countdown during user actions (#80) --- .../idle-detection.component.ts | 2 +- .../idle-detection-demo.component.html | 2 + .../idle-detection-demo.component.ts | 44 +++++++++++++------ .../src/lib/operators/poll.operator.spec.ts | 8 ++-- .../idle-detection/idle-detection.service.ts | 7 ++- 5 files changed, 43 insertions(+), 20 deletions(-) diff --git a/projects/clr-lift/src/lib/components/idle-detection/idle-detection.component.ts b/projects/clr-lift/src/lib/components/idle-detection/idle-detection.component.ts index 73e7be3..8821603 100644 --- a/projects/clr-lift/src/lib/components/idle-detection/idle-detection.component.ts +++ b/projects/clr-lift/src/lib/components/idle-detection/idle-detection.component.ts @@ -72,6 +72,6 @@ export class IdleDetectionComponent implements OnInit { keepMeSignedIn() { this.closeSubject.next(); - this.idleDetectionService.resetTimer(); + this.idleDetectionService.resetTimer(true); } } diff --git a/projects/demo-application/src/app/ngx-lib/pages/utilities/idle-detection-demo/idle-detection-demo.component.html b/projects/demo-application/src/app/ngx-lib/pages/utilities/idle-detection-demo/idle-detection-demo.component.html index a9a55a0..1247a7f 100644 --- a/projects/demo-application/src/app/ngx-lib/pages/utilities/idle-detection-demo/idle-detection-demo.component.html +++ b/projects/demo-application/src/app/ngx-lib/pages/utilities/idle-detection-demo/idle-detection-demo.component.html @@ -85,3 +85,5 @@

3. (Optional) Use IdleDetectionComponent

Idle Detection Dialog + + diff --git a/projects/demo-application/src/app/ngx-lib/pages/utilities/idle-detection-demo/idle-detection-demo.component.ts b/projects/demo-application/src/app/ngx-lib/pages/utilities/idle-detection-demo/idle-detection-demo.component.ts index aa6b176..a7ff3af 100644 --- a/projects/demo-application/src/app/ngx-lib/pages/utilities/idle-detection-demo/idle-detection-demo.component.ts +++ b/projects/demo-application/src/app/ngx-lib/pages/utilities/idle-detection-demo/idle-detection-demo.component.ts @@ -1,4 +1,6 @@ -import {ChangeDetectionStrategy, Component, OnDestroy, OnInit} from '@angular/core'; +import {ChangeDetectionStrategy, Component, DestroyRef, inject, OnDestroy, OnInit} from '@angular/core'; +import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; +import {Router} from '@angular/router'; import {CalloutComponent, IdleDetectionComponent, PageContainerComponent} from 'clr-lift'; import {IdleDetectionService} from 'ngx-lift'; @@ -13,6 +15,9 @@ import {highlight} from '../../../../shared/utils/highlight.util'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class IdleDetectionDemoComponent implements OnInit, OnDestroy { + private router = inject(Router); + private destroyRef = inject(DestroyRef); + configCode = highlight(` export class IdleDetectionConfig { idleDurationInSeconds?: number; @@ -109,6 +114,10 @@ export class AppComponent { } `); + // onTimeout() { + // this.router.navigate(['/login']); + // } + constructor(private idleDetectionService: IdleDetectionService) {} ngOnInit() { @@ -118,20 +127,29 @@ export class AppComponent { }); this.idleDetectionService.startWatching(); - this.idleDetectionService.onIdleEnd().subscribe(() => { - // Handle idle end event, e.g., show a warning dialog - console.log('idle for a long time, enter timeout phase'); - }); + this.idleDetectionService + .onIdleEnd() + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe(() => { + // Handle idle end event, e.g., show a warning dialog + console.log('idle for a long time, enter timeout phase'); + }); - this.idleDetectionService.onTimeoutEnd().subscribe(() => { - // Handle timeout end event, e.g., log out the user - console.log('timeout, should logout'); - }); + this.idleDetectionService + .onTimeoutEnd() + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe(() => { + // Handle timeout end event, e.g., log out the user + console.log('timeout, should logout'); + }); - this.idleDetectionService.onCountDown().subscribe((countdown) => { - // Update the UI with the remaining time - console.log(countdown); - }); + this.idleDetectionService + .onCountDown() + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((countdown) => { + // Update the UI with the remaining time + console.log(countdown); + }); } ngOnDestroy() { diff --git a/projects/ngx-lift/src/lib/operators/poll.operator.spec.ts b/projects/ngx-lift/src/lib/operators/poll.operator.spec.ts index 171dd46..acbbad2 100644 --- a/projects/ngx-lift/src/lib/operators/poll.operator.spec.ts +++ b/projects/ngx-lift/src/lib/operators/poll.operator.spec.ts @@ -15,9 +15,9 @@ describe('poll', () => { it('should call pollingFn with correct params and return data', (done) => { const interval = 1000; - const trigger = of(null); // Mocking a trigger observable emitting once + const forceRefresh = of(null); // Mocking a trigger observable emitting once - poll({interval, pollingFn: mockPollingFn, paramsBuilder: mockParamsBuilder, trigger}) + poll({interval, pollingFn: mockPollingFn, paramsBuilder: mockParamsBuilder, forceRefresh}) .pipe(take(1)) .subscribe((state) => { expect(state).toEqual({loading: true, error: null, data: null}); // Initial loading state @@ -31,9 +31,9 @@ describe('poll', () => { it('should handle initial trigger emissions', (done) => { const interval = 1000; - const trigger = of('trigger'); + const forceRefresh = of('trigger'); - poll({interval, pollingFn: mockPollingFn, paramsBuilder: mockParamsBuilder, trigger}) + poll({interval, pollingFn: mockPollingFn, paramsBuilder: mockParamsBuilder, forceRefresh}) .pipe(take(1)) .subscribe((state: AsyncState) => { expect(state).toEqual({loading: true, error: null, data: null}); // Initial loading state diff --git a/projects/ngx-lift/src/lib/utils/idle-detection/idle-detection.service.ts b/projects/ngx-lift/src/lib/utils/idle-detection/idle-detection.service.ts index 5ee7335..e455030 100644 --- a/projects/ngx-lift/src/lib/utils/idle-detection/idle-detection.service.ts +++ b/projects/ngx-lift/src/lib/utils/idle-detection/idle-detection.service.ts @@ -92,11 +92,14 @@ export class IdleDetectionService { /** * Resets the idle timer when user activity is detected. + * @param withCountdownReset - Flag to indicate if countdown should be reset. + * By default, it only reset the idle-detection timer. If you enter the countdown phase, it won't stop the countdown. + * Pass true when you want to reset the countdown as well. This is useful when you click "Keep Me Signed In" button in cll-idle-detection component */ - resetTimer() { + resetTimer(withCountdownReset = false) { this.startIdleTimer(); - if (this.isCountingDown) { + if (withCountdownReset && this.isCountingDown) { this.stopCountdown(); } }