5

I have implemented a session timeout module in my angular app which monitors idle time and opens the session time out dialog and shows the countdown value on the dialog. The problem is count down value is stopping when ever i moved my mouse on that screen or atleast on touching that screen but i want to stop the countdown value on the dialog only when i click anything on the dialog not the screen . I thought this can be do this if we give the custom interrupts as shown in the below link here

For ex if i configure for only mouse click it can stop the countdown on the dialog, but that is not happening. May be that issue might be because of i am opening the session timeout dilaog from the another component.

But i am not able to stop the count down , Here is my sample code

this.idle.onIdleStart.subscribe(() => {
  console.log('on idle start');
  let dialogRef;

  if (this.dialogRef === undefined || this.dialogRef === null) {

    dialogRef = this.dialog['open'](SessionTimeoutDialogComponent, {
      width: '30%',
      data: {idleTime: 10, timeoutTime: 10},
      panelClass: 'session-timeout-dialog'
    });
    this.dialogRef = dialogRef;
  }

  this.dialogRef.afterClosed().subscribe(result => {
    this.timeoutTime = result;
  });
  this.dialogRef = dialogRef;
});


 this.idle.onTimeoutWarning.subscribe((countdown) => {
  this.timeoutTime = countdown;
  this.dataService.changeVersionSelectionData(countdown);

});

Can anyone guide how can we do this ?

Roster
  • 1,764
  • 6
  • 17
  • 36
  • `data: {idleTime: 10, timeoutTime: 10},` I think from this line you are passing timeout value, then you will be able pause the timer in `SessionTimeoutDialogComponent` itself..? – Ganesh Sep 09 '19 at 06:20
  • @ganesh045 Sorry that line is removed now , i have used observable to update that countdown value on dialog – Roster Sep 10 '19 at 07:21
  • is it working now... ? – Ganesh Sep 10 '19 at 09:22
  • @Ganesh045 I tried to clear and set interval again , Please check most relavant question i have posted for the same issue . https://stackoverflow.com/questions/57866420/ngidle-how-to-clear-and-reset-interrupts-in-angular – Roster Sep 10 '19 at 09:50

1 Answers1

8

SOLUTION: The trick is, clear the interrupts just when you do idleStart by calling this.idle.clearInterrupts(), which removes the event listeners, but the actual countdown is still going on, which can either reset or end based on user action in the dialogue,

Here is what I did:


    this.idle.onIdleStart.subscribe(() => {
      console.log('on idle start');

      this.idle.clearInterrupts();

      const dialogConfig = new MatDialogConfig();
      dialogConfig.disableClose = true;
      dialogConfig.data = { title, body };

      const dialogRef = this.dialog.open(DialogComponent, dialogConfig);

      dialogRef.afterClosed().subscribe(result => {
        console.log('The dialog is closed. Result='+result);
        if (result)
          this.idle.setInterrupts(DEFAULT_INTERRUPTSOURCES);
          this.idle.watch();
        });
        this.dialogRef = dialogRef;
        return dialogRef.afterClosed();
      }
    });

    this.idle.onTimeoutWarning.subscribe((countdown) => {
      this.dialogRef.componentInstance.body='You will be logged out in '+countdown+'seconds!';
    });

    this.idle.onTimeout.subscribe(() => {
      console.log('timeout..');
      this.dialogRef.close();
      this.logout();
      this.router.navigate(['/']);
    });

The idea is to clearInterrupts() just after idle starts so no events are caught.

Then, you open the dialog and for the period idle.setTimeout(period) you see the countdown in it. Now, say you have a dialog.component.html:


    <h1 mat-dialog-title>{{ title }}</h1>
    <div mat-dialog-content>
        <p>{{ body }}</p>
    </div>
    <div mat-dialog-actions style="text-align: center;">
        <button mat-button (click)="close()">STAY LOGGED</button>
    </div>

and a dialog.component.ts:


    @Component({
        selector: 'app-dialog',
        templateUrl: './dialog.component.html',
    })
    export class DialogComponent implements OnInit {
        title: string;
        body: string;

        constructor(
            public dialogRef: MatDialogRef,
            @Inject(MAT_DIALOG_DATA) public data: {title, body}) {

            this.title = data.title;
            this.body = data.body;
        }

        close() {
            this.dialogRef.close(true);
        }
    }

In this setup, if you click the button: 'STAY LOGGED', you exit the dialog with result=true. You reset the timers and start watching the idle all over again.

If you don't click the button, you'll be eventually logged out.

This is what I came with after long hours of experimenting with MatDialog and updating it's contents in realtime (for the countdown).

It looks to me that the job is done!

Ujju
  • 2,723
  • 3
  • 25
  • 35
Agoun
  • 334
  • 3
  • 11