Question

Typical chat app. Using the presence channel to tell who is online, but looking for an elegant way to mark a User in the presence channel with an idle flag.

Was it helpful?

Solution

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:

  1. to detect a user as being "idle"
  2. 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:

  1. Enable client events on the presence channel and trigger an event from the idle user when your code detects the user becoming idle.
  2. 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
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top