Resetting a countdown timer whenever the user interacts with the SPA - html

I have an ember Single Page Application. The application has an auto-logout feature: whenever the timer expires, it will automatically logout. I would like to reset the timer every time that the user interacts with the page:
whenever keyboard input is entered
whenever any component of the page is clicked, including for example dropdown-opening, which is not triggering any ember action
Is it possible to add any code to catch any mouse / keyboard event before it is sent to ember? After resetting the timer, the event should be passed to ember or the CSS pipeline for further processing.
I would like to consider a special case: whenever the user clicks in a non-active area (background, for example), I am not sure of whether it is better to reset the timer or not, so I would like to be able to catch that, in order to decide later what to do. I am not sure how to define non-active area: from the point of view of the user, is clicking anywhere where no CSS effects or any other kind of effect is triggered.

Here's what we're using, I most definitely stole it from someone else and worked it into Ember, but I'm not going to find out where. It really just tells you if they've interacted with the page in any way, not necessarily if any component etc has been clicked.
App.idleTime = 0;
$(document).ready(function () {
//Increment the idle time counter every minute.
var idleInterval = setInterval(function() {
App.idleTime = App.idleTime + 1;
}, 60000); // 1 minute
//Zero the idle timer on mouse movement.
$(this).mousemove(function (e) {
App.idleTime = 0;
});
$(this).keypress(function (e) {
App.idleTime = 0;
});
});
And then I have a schedule task in my application route that watches the idle time and goes haywire with it when appropriate. The code below is made up, but should give you an idea.
App.ApplicationRoute = Em.Route.extend({
idleMax: 10,
setupBatman: function(){
this.watchJoker();
}.on('init'),
watchJoker: function(){
Ember.run.later(this, this.watchJoker, 1000);
if (App.idleTime >= this.get('idleMax')) {
console.log("You are looking idle, I'm gonna kick you.");
// kick
}
}
});
Update: I felt guilt, it came from here: Detecting idle time in JavaScript elegantly

Related

How to make sure a focus on single textboxt after every possible user action?

I have a function to make cursor focus to a textbox.
function getfocus(){
var focusbox;
focusbox = document.getElementById("i_focushere");
setTimeout(function() {
focusbox.focus();
}, 1);
}
I call this function on some event like change and click. Something like this.
//FORCE FOCUS SELECT
$(document).on('change','select', function(e){
getfocus();
});
//FORCE FOCUS BUTTON
$(document).on('click','button', function(e){
getfocus();
});
Is that enough to make sure focus after every possible user action. Users action is limited to a page only though. Any suggestions are really appreciated.

How to get loop animation progress in scripts (Spark AR)

I need to get loop animation progress (and looped) information (if it will be in patch editor, it 's the outputs). But I can't find this information on documentation. How can I get needed information?
For "looped" you can use onAfterIteration event on the TimeDriver:
https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/animationmodule.timedriver
For progress, unfortunately there isn't a progress available on the TimeDriver, but you can use a multiTrigger event listener on the animation signal. Depending on what exactly you are trying to achieve, there are a few different ways of doing it:
https://sparkar.facebook.com/ar-studio/learn/documentation/reference/classes/reactivemodule.scalarsignal
For example:
//setup your animation
const Animation = require('Animation');
let driver = Animation.timeDriver({durationMilliseconds:1000, loopCount:Infinity});
let sampler = Animation.samplers.linear(0,1);
let animation = Animation.animate(driver, sampler);
//add listener for "looped" to the driver
driver.onAfterIteration().subscribe(function(e){
//do stuff on here...
});
//add listener for progress to the animation signal
//this will trigger when the animation signal goes above .5
animation.multiTrigger(.5).subscribe(function(e){
//do stuff here...
})

How to know that fitToView() has finished completely

I want to know that fitToView() finished completely.
Some program procedures do not work after fitToView() without setTimeout().
For example, the following code not work.
const dbid = [1141]
this.viewer.select(dbid)
this.viewer.fitToView(dbid, viewer.model)
zoom() //This will not work
//code from:
function zoom (){
var nav = viewer.navigation
var pos = nav.getPosition()
var target = nav.getTarget()
var viewdir = new THREE.Vector3()
viewdir.subVectors (pos, target).normalize()
// zooms out by 100 along the view direction
viewdir.multiplyScalar (1000)
pos.add(viewdir)
nav.setPosition(pos)
}
The following code work well.
this.viewer.fitToView(dbid, viewer.model)
setTimeout(function(){
zoom() //This will work fine
}, 2000)
However, I don't want to use the setTimeout as much as possible.
Is there a way to know that fitToView () is finished completely?
If you use version 3.2.1 of the viewer a new event Autodesk.Viewing.CAMERA_TRANSITION_COMPLETED, it will be fired while following transitions are finished:
Go Home transition
Focus / Fit to View transition
Restore State transition
Named Views transition
Any other camera transitions
// Hook the event
viewer.addEventListener(Autodesk.Viewing.CAMERA_TRANSITION_COMPLETED, function(){
console.log('camera is no longer moving');
});
// Trigger an action that will move the camera and fire the event
viewer.fitToView();
You can see more about the Viewer Version changes here.
https://developer.autodesk.com/en/docs/viewer/v2/overview/changelog/3.2.1/

User vs. System events in Google Maps API v3

I've been reading the Google Maps API docs to see if it's possible to tell the difference between a system event vs. a user one?
For example, the zoom_changed event gets triggered when you use methods like setZoom, fitBounds, etc, which in my implementation is unsavoury, as I just want to know when the user actually changes the zoom level.
Unfortunately, the click event is only fired on the map itself, not the controls, so you can't rely on that method to help detect the users input.
Ideas?
Although I haven't been able to solve this using the Google Maps API, I have created a workaround which involves me calling this method before I change the map zoom or positioning without user interaction:
MapGraph.prototype.systemMove = function() {
var _this = this;
this.isMoving = true;
return setTimeout(function() {
return _this.isMoving = false;
}, 500);
};
And my event bindings look like this:
google.maps.event.addListener(this.map, 'dragend', function(event) {
if (!_this.isMoving) return _this.mapChanged();
});
Not perfect, but it does work.
Would love to see any other implementations though.
You may also consider an alternate solution I proposed in this Stack Overflow answer, which does not rely on mouse events to recognize user-initiated changes.
Instead of trying to recognize user events, add a flag to the map whenever a programmatic change is initiated with setZoom or fitBounds.
map.systemChange = true
map.setZoom()
Then check for (and reset) the flag in the event listener.
map.addListener('zoom_changed', function () {
if (map.systemChange) {
map.systemChange = false // Reset the flag for a system-initiated event
} else {
// Handle the user-initiated event
}
});

Can I specify a delay before the browser raises "rollover" event?

I am working on an ASP.NET web application that is required to bring up a popup on a roolover. I am using the "OnMouseOver" event and it works as expected. The problem is that the event is on a "hair trigger"; even a casual passage of the mouse over the control brings up the popup (which then must be manually dismissed). I want to add a delay so that a rapid pass over the control in question does not trigger the event. Is there a way to set such a delay or is there a different event that I could use to get the same "trigger event on a slow rollover"?
One solution that comes to mind, there may be better ways though:
Make the onmouseover call the function via a setTimeout delay
Inside the function, check the mouse is actually over that element.
You could also use an onmouseout to clear the setTimeout, but then you'd have to store a reference to the timer in a global variable to get at it again.
What I ended up doing is as follows (oRow is a table row but it could be any control):
function ItemMouseOver(oRow, "parameters for the popup")
{
oRow.showTimer = window.setTimeout(function()
{
alert('popup');
}, 1000);
}
function ItemMouseOut(oRow)
{
if (oRow.showTimer)
window.clearTimeout(oRow.showTimer);
In the ASP.NET grid view RowDataBound event: I added the following code:
protected void ReportGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && (
e.Row.RowState == DataControlRowState.Normal
|| e.Row.RowState == DataControlRowState.Alternate))
{
// get the input values for the popup for the row (stuff deleted)
e.Row.Attributes["onmouseover"] = "javascript:ItemMouseOver(this,
"parameters for the popup");";
e.Row.Attributes["onmouseout"] = "javascript:ItemMouseOut(this);";
}
}
It works just fine. Thanks.