The full solution to this is probably reasonably complicated and it also depends on the runtime - I'm going to assume web web client.
Ultimately you need a way of doing two things:
- to detect a user as being "idle"
- to signal all other users about that user being idel
To detect a user is idle
- window.onblur so you know your app window is no longer focused
- mousemove tracking to see if the user is actually doing anything within your application.
In order to achieve this you probably just want a timeout and only if that timeout triggers do you send an event to indicate the user is idle:
var timeout = null;
function sendUserIdle() {
// see part 2
}
function resetIdleTracking() {
if( timeout !== null ) {
// reset
clearTimeout( timeout );
}
timeout = setTimeout( sendUserIdle, 3*60*1000 ); // 3 minutes
}
window.addEventListener( 'mousemove', resetIdleTracking );
Signal other users about idle users
A missing feature of Pusher presence channels IMO is the ability to update presence information. So, you need another way of achieving this. I think you have two solutions:
- Enable client events on the presence channel and trigger an event from the idle user when your code detects the user becoming idle.
- Send a message to the server from the idle client. The server then triggers a message telling the users that the user is idle.
See: accessing channel members.
1. Using client events
function sendUserIdle() {
var channel = pusher.channel( 'presence-<your-channel>' );
// client events have to have a 'client-' prefix
channel.trigger( 'client-user-idle', channel.members.me );
}
2. Sending to the server
function sendUserIdle() {
makeAjaxRequest( '/idle-notification-endpoint', channel.members.me );
}
Note: you can serialise channel.members.me
using JSON.stringify( channel.members.me )
On the server (in pseudo code):
userInfo = getUserInfoFromRequest();
pusher.trigger( 'presence-<your-channel>', 'user-idle', userInfo );
Showing a client is idle
Upon receipt of the event you would update the list of users UI accordingly (mark that user as idle).
channel.bind( 'user-idle', function( user ) {
var uniqueUserId = user.id;
// update UI
}