LT-107: Add countdown dialog
- Remove ui from meteor-stale-session package
This commit is contained in:
parent
d18a66d513
commit
5ec3cace94
@ -71,8 +71,6 @@ meteor-base@1.0.1
|
|||||||
meteor-platform@1.2.3
|
meteor-platform@1.2.3
|
||||||
minifiers@1.1.7
|
minifiers@1.1.7
|
||||||
minimongo@1.0.10
|
minimongo@1.0.10
|
||||||
mizzao:build-fetcher@0.2.0
|
|
||||||
mizzao:jquery-ui@1.11.4
|
|
||||||
mobile-experience@1.0.1
|
mobile-experience@1.0.1
|
||||||
mobile-status-bar@1.0.6
|
mobile-status-bar@1.0.6
|
||||||
momentjs:moment@2.11.2
|
momentjs:moment@2.11.2
|
||||||
|
|||||||
@ -18,5 +18,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
{{> timeoutCountdownDialog}}
|
||||||
{{> yield}}
|
{{> yield}}
|
||||||
</template>
|
</template>
|
||||||
@ -11,3 +11,31 @@ Template.layoutLesionTracker.helpers({
|
|||||||
return Meteor.user().profile.fullName;
|
return Meteor.user().profile.fullName;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.layoutLesionTracker.onCreated(function() {
|
||||||
|
// Show countdown dialog
|
||||||
|
var handle;
|
||||||
|
$(document).on('TriggerOpenTimeoutCountdownDialog', function (e, leftTime) {
|
||||||
|
// TODO: Show modal dialog
|
||||||
|
handle = setInterval(function() {
|
||||||
|
leftTime --;
|
||||||
|
// Set countdownDialogLeftTime session
|
||||||
|
Session.set("countdownDialogLeftTime", leftTime);
|
||||||
|
// Show dialog
|
||||||
|
if ($("#timeoutCountdownDialog").css("display") == "none") {
|
||||||
|
$("#timeoutCountdownDialog").css("display", "block");
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('TriggerCloseTimeoutCountdownDialog', function (e) {
|
||||||
|
$("#timeoutCountdownDialog").css("display", "none");
|
||||||
|
if (handle) {
|
||||||
|
clearInterval(handle);
|
||||||
|
// Close the dialog
|
||||||
|
$("#timeoutCountdownDialog").css("display", "none");
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
<template name="timeoutCountdownDialog">
|
||||||
|
<div id="timeoutCountdownDialog">
|
||||||
|
<div class="dialogHeader">
|
||||||
|
<h5>Session is about to expire!</h5>
|
||||||
|
</div>
|
||||||
|
<div class="dialogContent">
|
||||||
|
<p>You will be log out in {{leftTime}} {{secondsText}}.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
Template.timeoutCountdownDialog.helpers({
|
||||||
|
leftTime: function(e) {
|
||||||
|
return Session.get("countdownDialogLeftTime");
|
||||||
|
},
|
||||||
|
secondsText: function() {
|
||||||
|
return Session.get("countdownDialogLeftTime") > 1? "seconds": "second";
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
#timeoutCountdownDialog
|
||||||
|
display: none
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
bottom: 0
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
margin: auto
|
||||||
|
width: 20%
|
||||||
|
height: 15%
|
||||||
|
z-index: 100
|
||||||
|
border-radius: 5px
|
||||||
|
padding: 10px 20px 10px 20px
|
||||||
|
background-color: rgba(255,255,255,1)
|
||||||
|
outline: none
|
||||||
@ -79,6 +79,10 @@ Package.onUse(function(api) {
|
|||||||
api.addFiles('client/components/nonTargetResponseDialog/nonTargetResponseDialog.styl', 'client');
|
api.addFiles('client/components/nonTargetResponseDialog/nonTargetResponseDialog.styl', 'client');
|
||||||
api.addFiles('client/components/nonTargetResponseDialog/nonTargetResponseDialog.js', 'client');
|
api.addFiles('client/components/nonTargetResponseDialog/nonTargetResponseDialog.js', 'client');
|
||||||
|
|
||||||
|
api.addFiles('client/components/timeoutCountdownDialog/timeoutCountdownDialog.html', 'client');
|
||||||
|
api.addFiles('client/components/timeoutCountdownDialog/timeoutCountdownDialog.styl', 'client');
|
||||||
|
api.addFiles('client/components/timeoutCountdownDialog/timeoutCountdownDialog.js', 'client');
|
||||||
|
|
||||||
api.addFiles('client/components/timepointTextDialog/timepointTextDialog.html', 'client');
|
api.addFiles('client/components/timepointTextDialog/timepointTextDialog.html', 'client');
|
||||||
api.addFiles('client/components/timepointTextDialog/timepointTextDialog.styl', 'client');
|
api.addFiles('client/components/timepointTextDialog/timepointTextDialog.styl', 'client');
|
||||||
|
|
||||||
|
|||||||
@ -9,74 +9,84 @@
|
|||||||
var heartbeatInterval = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionHeartbeatInterval || (3*60*1000); // 3mins
|
var heartbeatInterval = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionHeartbeatInterval || (3*60*1000); // 3mins
|
||||||
var activityEvents = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionActivityEvents || 'mousemove click keydown';
|
var activityEvents = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionActivityEvents || 'mousemove click keydown';
|
||||||
var inactivityTimeout = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionInactivityTimeout || (30*60*1000); // 30mins
|
var inactivityTimeout = Meteor.settings && Meteor.settings.public && Meteor.settings.public.staleSessionInactivityTimeout || (30*60*1000); // 30mins
|
||||||
var countdownDialogTime = Meteor.settings && Meteor.settings.public && Meteor.settings.public.countdownDialogTime || (15*1000); // 30second
|
|
||||||
var showCountdownDialog = Meteor.settings && Meteor.settings.public && Meteor.settings.public.showCountdownDialog || true;
|
var dialogTimeout = Meteor.settings && Meteor.settings.public && Meteor.settings.public.dialogTimeout || (30*1000); // 30secs
|
||||||
|
var showCountdownDialog = Meteor.settings && Meteor.settings.public && Meteor.settings.public.showCountdownDialog || false;
|
||||||
|
var countdownHeartbeatInterval = (heartbeatInterval < dialogTimeout)? heartbeatInterval : dialogTimeout;
|
||||||
|
|
||||||
var activityDetected = false;
|
var activityDetected = false;
|
||||||
var activityDetectedTime = new Date();
|
var lastActivityDetectedTime = new Date();
|
||||||
|
var dialogIsOpen = false;
|
||||||
|
|
||||||
Meteor.startup(function() {
|
Meteor.startup(function() {
|
||||||
// Add countdown dialog to body
|
|
||||||
$("body").append('<div id="staleSessionCountdownModal" title="Session will expire!"></div>');
|
|
||||||
|
|
||||||
//Initialize the dialog
|
|
||||||
$("#staleSessionCountdownModal").dialog({
|
|
||||||
autoOpen: false,
|
|
||||||
open: function(){
|
|
||||||
$('.ui-widget-overlay').bind('click',function(){
|
|
||||||
$('#staleSessionCountdownModal').dialog('close');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// periodically send a heartbeat if activity has been detected within the interval
|
// periodically send a heartbeat if activity has been detected within the interval
|
||||||
//
|
//
|
||||||
Meteor.setInterval(function() {
|
|
||||||
if (Meteor.userId() && activityDetected) {
|
|
||||||
Meteor.call('heartbeat');
|
|
||||||
activityDetected = false;
|
|
||||||
}
|
|
||||||
}, heartbeatInterval);
|
|
||||||
|
|
||||||
// Detect the time when countdown dialog will be shown
|
|
||||||
if (showCountdownDialog) {
|
if (showCountdownDialog) {
|
||||||
Meteor.setInterval(function() {
|
Meteor.setInterval(function() {
|
||||||
if (!activityDetected) {
|
if (Meteor.userId()) {
|
||||||
var lastHeartbeatTime = activityDetectedTime.getTime();
|
if (activityDetected) {
|
||||||
var now = new Date().getTime();
|
Meteor.call('heartbeat', function(error, heartbeatTime) {
|
||||||
var overdueTimestamp = now - lastHeartbeatTime;
|
lastActivityDetectedTime = heartbeatTime;
|
||||||
var dialogTime = inactivityTimeout - countdownDialogTime;
|
activityDetected = false;
|
||||||
if(dialogTime <= overdueTimestamp && inactivityTimeout >= overdueTimestamp) {
|
// Event to close dialog
|
||||||
var sec = Math.round((inactivityTimeout - overdueTimestamp) / 1000);
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
||||||
console.log(sec);
|
dialogIsOpen = false;
|
||||||
var dialogStr = "You will be log out in "+sec+" seconds.";
|
});
|
||||||
if (sec === 0) {
|
|
||||||
$("#staleSessionCountdownModal").dialog('close');
|
|
||||||
} else {
|
|
||||||
if(sec === 1) {
|
|
||||||
dialogStr = "You will be log out in "+sec+" second.";
|
|
||||||
}
|
|
||||||
$('#staleSessionCountdownModal').html(dialogStr);
|
|
||||||
$("#staleSessionCountdownModal").dialog('open');
|
|
||||||
|
|
||||||
// Remove border of close button
|
|
||||||
$(".ui-button:focus").css("outline", "none");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$("#staleSessionCountdownModal").dialog('close');
|
var overdueTimestamp = new Date().getTime() - lastActivityDetectedTime;
|
||||||
|
// Ignore min differences
|
||||||
|
overdueTimestamp = overdueTimestamp - (overdueTimestamp % 1000);
|
||||||
|
console.log(overdueTimestamp);
|
||||||
|
var startTime = inactivityTimeout - dialogTimeout;
|
||||||
|
if (overdueTimestamp <= inactivityTimeout) {
|
||||||
|
var nextIntervalTime = overdueTimestamp + countdownHeartbeatInterval;
|
||||||
|
if (nextIntervalTime <= inactivityTimeout && nextIntervalTime >= startTime) {
|
||||||
|
if (Math.abs(startTime - overdueTimestamp) <= Math.abs(nextIntervalTime - startTime) && !dialogIsOpen) {
|
||||||
|
// Open dialog
|
||||||
|
var leftTime = Math.round((inactivityTimeout - overdueTimestamp) / 1000);
|
||||||
|
$.event.trigger('TriggerOpenTimeoutCountdownDialog', leftTime);
|
||||||
|
dialogIsOpen = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Event to close dialog
|
||||||
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
||||||
|
dialogIsOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Event to close dialog
|
||||||
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
||||||
|
dialogIsOpen = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Event to close dialog
|
||||||
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
||||||
|
dialogIsOpen = false;
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, countdownHeartbeatInterval);
|
||||||
|
|
||||||
|
} else{
|
||||||
|
|
||||||
|
Meteor.setInterval(function() {
|
||||||
|
if (Meteor.userId() && activityDetected) {
|
||||||
|
Meteor.call('heartbeat');
|
||||||
|
activityDetected = false;
|
||||||
|
}
|
||||||
|
}, heartbeatInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// detect activity and mark it as detected on any of the following events
|
// detect activity and mark it as detected on any of the following events
|
||||||
//
|
//
|
||||||
$(document).on(activityEvents, function(event) {
|
$(document).on(activityEvents, function() {
|
||||||
activityDetected = true;
|
activityDetected = true;
|
||||||
activityDetectedTime = new Date();
|
// Event to close dialog
|
||||||
$("#staleSessionCountdownModal").dialog('close');
|
$.event.trigger('TriggerCloseTimeoutCountdownDialog');
|
||||||
|
dialogIsOpen = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
Package.describe({
|
Package.describe({
|
||||||
name: 'zuuk:stale-session',
|
name: 'zuuk:stale-session',
|
||||||
summary: 'Stale session and session timeout handling for meteorjs',
|
summary: 'Stale session and session timeout handling for meteorjs',
|
||||||
git: "https://github.com/lindleycb/meteor-stale-session.git",
|
git: "https://github.com/lindleycb/meteor-stale-session.git",
|
||||||
version: "1.0.8"
|
version: "1.0.8"
|
||||||
});
|
});
|
||||||
|
|
||||||
Package.onUse(function(api) {
|
Package.onUse(function(api) {
|
||||||
api.use('accounts-base@1.0.0', ['client','server']);
|
api.use('accounts-base@1.0.0', ['client','server']);
|
||||||
api.use('jquery@1.0.0', 'client');
|
api.use('jquery@1.0.0', 'client');
|
||||||
api.use('mizzao:jquery-ui', 'client');
|
|
||||||
api.addFiles('client.js', 'client');
|
api.addFiles('client.js', 'client');
|
||||||
api.addFiles('server.js', 'server');
|
api.addFiles('server.js', 'server');
|
||||||
});
|
});
|
||||||
@ -17,7 +17,9 @@ Meteor.methods({
|
|||||||
if (!this.userId) { return; }
|
if (!this.userId) { return; }
|
||||||
var user = Meteor.users.findOne(this.userId);
|
var user = Meteor.users.findOne(this.userId);
|
||||||
if (user) {
|
if (user) {
|
||||||
Meteor.users.update(user._id, {$set: {heartbeat: new Date()}});
|
var heartbeatTime = new Date();
|
||||||
|
Meteor.users.update(user._id, {$set: {heartbeat: heartbeatTime}});
|
||||||
|
return heartbeatTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -19,9 +19,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"staleSessionInactivityTimeout": 1800000,
|
"staleSessionInactivityTimeout": 300000,
|
||||||
"staleSessionHeartbeatInterval": 180000,
|
"staleSessionHeartbeatInterval": 30000,
|
||||||
"staleSessionPurgeInterval": 60000,
|
"staleSessionPurgeInterval": 15000,
|
||||||
"staleSessionActivityEvents": "mousemove click keydown"
|
"staleSessionActivityEvents": "mousemove click keydown",
|
||||||
|
"showCountdownDialog": true,
|
||||||
|
"dialogTimeout": 30000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,9 +17,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"staleSessionInactivityTimeout": 1800000,
|
"staleSessionInactivityTimeout": 300000,
|
||||||
"staleSessionHeartbeatInterval": 180000,
|
"staleSessionHeartbeatInterval": 30000,
|
||||||
"staleSessionPurgeInterval": 60000,
|
"staleSessionPurgeInterval": 15000,
|
||||||
"staleSessionActivityEvents": "mousemove click keydown"
|
"staleSessionActivityEvents": "mousemove click keydown",
|
||||||
|
"showCountdownDialog": true,
|
||||||
|
"dialogTimeout": 30000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,9 +18,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"staleSessionInactivityTimeout": 1800000,
|
"staleSessionInactivityTimeout": 300000,
|
||||||
"staleSessionHeartbeatInterval": 180000,
|
"staleSessionHeartbeatInterval": 30000,
|
||||||
"staleSessionPurgeInterval": 60000,
|
"staleSessionPurgeInterval": 15000,
|
||||||
"staleSessionActivityEvents": "mousemove click keydown"
|
"staleSessionActivityEvents": "mousemove click keydown",
|
||||||
|
"showCountdownDialog": true,
|
||||||
|
"dialogTimeout": 30000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -17,9 +17,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"public": {
|
"public": {
|
||||||
"staleSessionInactivityTimeout": 30000,
|
"staleSessionInactivityTimeout": 300000,
|
||||||
"staleSessionHeartbeatInterval": 3000,
|
"staleSessionHeartbeatInterval": 30000,
|
||||||
"staleSessionPurgeInterval": 1000,
|
"staleSessionPurgeInterval": 15000,
|
||||||
"staleSessionActivityEvents": "mousemove click keydown"
|
"staleSessionActivityEvents": "mousemove click keydown",
|
||||||
|
"showCountdownDialog": true,
|
||||||
|
"dialogTimeout": 30000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user