Aurelia inactivity exit

tl; dr, with Aurelia, how can I call a function that is inside the view model from outside the view model?

I need to perform client-side logout for a user who has not performed an action (route change, server request, etc.) for a certain period of time. After reading this GitHub problem, I created an inactive view and view model and included it in my app.html and in my attached () function, I start my timer and register the user when the time is up.

It all works great, but I ran into a problem that makes me feel like it was a huge rabbit hole. How to call the resetInactivityTimer () function from outside the view model, is it possible to make one function in the class public? For example, when a server request is executed, I want to call the resetInactivityTimer () function from my service class

inactivity-logout.ts

import {Aurelia} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {inject} from 'aurelia-dependency-injection';

@inject(Aurelia, Router)
export class InactivityLogout {
    inactivityWarningDuration: number; // how long should the warning be up
    initialInactivityWarningDuration: number; // how long should the warning be up
    inactivityDuration: number; // how long before we warn them
    inactivityIntervalHandle: any;

    constructor(aurelia, router) {
        this.aurelia = aurelia;
        this.router = router;
        this.initialInactivityWarningDuration = 5;
        this.inactivityWarningDuration = this.initialInactivityWarningDuration;
        this.inactivityDuration = 5;
    }

    attached() {
        this.queueInactivityTimer();
    }

    resetInactivityTimer(){
        $("#LogoutWarningPopup").modal("hide"); 

        this.inactivityWarningDuration = this.initialInactivityWarningDuration;
        clearInterval(this.warningInterval);
        this.queueInactivityTimer();
    }

    queueInactivityTimer(){
        clearTimeout(this.inactivityIntervalHandle);

        this.inactivityIntervalHandle = setTimeout(() => {
            this.displayWarning();
        }, 1000 * this.inactivityDuration);
    }

    displayWarning(){
        $("#LogoutWarningPopup").modal({ backdrop: 'static', keyboard: false });
        this.warningInterval = setInterval(()=>{
                this.inactivityWarningDuration--;
                if(this.inactivityWarningDuration <= 0){
                    clearInterval(this.warningInterval);
                    this.logout();
                }
            }, 1000); //start counting down the timer
    }

    logout(){
        $("#LogoutWarningPopup").modal("hide");
        console.log("due to inactivity, you've been logged out.")
        this.aurelia.setRoot('views/login');
    }
}
Run codeHide result

app.html

    <require from='./inactivity-logout.js'></require>
    <inactivity-logout></inactivity-logout>
Run codeHide result

Search-service.ts

    performSearch(searchText: String) {

        /*
         * Stuff here to reset inactivity timer 
         */

        return this.httpClient.put("/api/Search", searchText)
           .then(response => {
               return response;
           });
    }
Run codeHide result
+4
source share
1 answer

A good way for global events is to use the PubSub template with aurelia-event-aggregatorlib.

import {Aurelia} from 'aurelia-framework';
import {Router} from 'aurelia-router';
import {inject} from 'aurelia-dependency-injection';
import {EventAggregator} from 'aurelia-event-aggregator';

@inject(Aurelia, Router, EventAggregator)
export class InactivityLogout {
    inactivityWarningDuration: number; // how long should the warning be up
    initialInactivityWarningDuration: number; // how long should the warning be up
    inactivityDuration: number; // how long before we warn them
    inactivityIntervalHandle: any;

    constructor(aurelia, router, ea) {
        this.aurelia = aurelia;
        this.router = router;
        this.initialInactivityWarningDuration = 5;
        this.inactivityWarningDuration = this.initialInactivityWarningDuration;
        this.inactivityDuration = 5;
        this.ea = ea;
        
        // subscribe
        this.sub = this.ea.subscribe(RefreshInactivity, msg => {
           console.log(msg.value);
        });

        // to unsubscribe somewhere
        // this.sub.dispose()
    }
...

}
Run codeHide result

export class RefreshInactivity {
  
  constructor(value) {
    this.value = value;
  }
  
}
Run codeHide result

send an event somewhere in the application

 this.ea.publish(new RefreshInactivity('some value'));
+5
source

All Articles