I want to alert user if he is idle for 20 min. So, created a service.
It is working fine with desktop but in mobile phone its not showing up and sometimes if screen left in the background for couple of hours, then logout dialog screen started the countdown once i got on the page again.
I mean it should logout and I should see login page but here it shows logout alert countdown page after couple of hours else it doesn't show up in mobile browser.
Here is my code please let me know which logic I am missing.
Here is Service.ts file. check() will be called for every 5 sec and will logout alert will show in 20 sec...
const MINUTES_UNITL_AUTO_LOGOUT = 0.2; // 1 mins- 20
const CHECK_INTERVAL = 5000; // checks every 5 secs- 5000
@Injectable({
providedIn: "root",
})
export class AutoLogoutService {
logOutInterval: any;
constructor(
private localStorage: LocalStoreManager,
private authService: AuthService,
public dialog: MatDialog
) {
this.localStorage.savePermanentData(
Date.now().toString().toString(),
DBkeys.AUTO_LOGOUT
);
this.initListener();
}
initListener() {
document.body.addEventListener("click", () => this.reset());
document.body.addEventListener("mouseover", () => this.reset());
document.body.addEventListener("mouseout", () => this.reset());
document.body.addEventListener("keydown", () => this.reset());
document.body.addEventListener("keyup", () => this.reset());
document.body.addEventListener("keypress", () => this.reset());
}
reset() {
this.setLastAction(Date.now());
}
initInterval() {
this.logOutInterval = setInterval(() => {
this.check();
}, CHECK_INTERVAL);
}
clearInterval() {
clearInterval(this.logOutInterval);
}
check() {
const now = Date.now();
const timeleft = this.getLastAction() + MINUTES_UNITL_AUTO_LOGOUT * 60 * 1000;
const diff = timeleft - now;
const isTimeout = diff < 0;
console.log(diff);
if (isTimeout && !this.authService.isLogoutDialogOpenned) {
this.authService.isLogoutDialogOpenned = true;
this.dialog
.open(LogoutDialog, {
maxWidth: "100vw",
})
.afterClosed()
.subscribe((result) => {
this.authService.isLogoutDialogOpenned = false;
});
}
}
public getLastAction() {
return parseInt(this.localStorage.getData(DBkeys.AUTO_LOGOUT));
}
public setLastAction(lastAction: number) {
this.localStorage.savePermanentData(
lastAction.toString(),
DBkeys.AUTO_LOGOUT
);
}
}
I believe in mobile, when user minimized browser your logic stops executing as mobile phones kill background application automatically for ram management and when he relaunches browser your script starts again. You should also logout on destroy or on window.beforeunload event.
Thanks for the suggestions, but the below solution worked for me
Used ngZone where it runs in the background
initInterval() {
this.ngZone.runOutsideAngular(() => {
this.logOutInterval = setInterval(() => {
this.check();
}, CHECK_INTERVAL);
})
}
clearInterval() {
clearInterval(this.logOutInterval);
}
check() {
const now = Date.now();
const timeleft =
this.getLastAction() + MINUTES_UNITL_AUTO_LOGOUT * 60 * 1000;
const diff = timeleft - now;
const isTimeout = diff < 0;
const isBackgroundLogoutEnabled = diff < -ONE_MINUTE;
this.ngZone.run(() => {
if (isTimeout && !this.authService.isLogoutDialogOpenned) {
this.authService.isLogoutDialogOpenned = true;
this.dialog
.open(LogoutDialog, {
maxWidth: "100vw",
})
.afterClosed()
.subscribe((result) => {
this.authService.isLogoutDialogOpenned = false;
});
}
if(isBackgroundLogoutEnabled){
this.clearInterval();
this.authService.isLogoutDialogOpenned = false;
this.authService.logout();
this.authService.redirectLogoutUser();
this.dialog.closeAll();
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With