Michael Hoeller
Michael Hoeller

Reputation: 24338

How to track a focus change in Meteor.js

I have in my app a page which is a kind of collaborative workspace. On this page I like to show the list of logged-in users and if they currently have a focus on this collaborative workspace or not.

In short: I want to track the focus on a certain page.

Has someone done this before? Or is there a package around? I have found BenjaminRH/meteor-event-hooks but this seem have stopped to be supported for 2 years. I have tried it and run in quite bit of problems.

Upvotes: 0

Views: 98

Answers (2)

Michael Hoeller
Michael Hoeller

Reputation: 24338

Here is a complete working solution

I added the package, and set up an extra field on the client

UserPresence.data = function() {
    return {
         focus: Iron.Location.get().path
    };
 }

I read from Meteor.users the users which are relevant and pass them to the view

Template.userstatus.helpers({
    'users':function(){
        var project    = Projects.findOne({_id:Session.get('active_project')});
        var userList   = Meteor.users.find( { $or: [ {_id:{$in:project.invited}},
        {_id:project.userId} ] } );
        return userList;
    }
});

<template name="userstatus">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h3 class="panel-title">Teilnehmer Status</h3>
    </div>
    <div class="panel-body">
          {{#each users}}
              {{ >useronline }}
          {{/each}}
    </div>
  </div>
</template>


<template name="useronline">
        <span style="margin-right: 2px;" class="label {{labelClass}}">{{profile.name }} </span>
 </template>

The second template is needed since I need the "this" context in the helper to "implicit join" the data.

The actual display of the users in the states online/offline/idle/focussed) is done in the useronline helper (the classes are plain bootstrap):

Template.useronline.helpers({
     labelClass: function() {
        var UP = UserPresences.findOne( {userId:this._id});

        if (UP === undefined)
            return "label-default";

        if (UP.data.focus === Iron.Location.get().path)
             return "label-warning";

        if (UP.state === 'idle')
            return "label-primary";
        else if (UP.state === 'online')
            return "label-success";
        else
            return "label-default";
    }
});

Upvotes: 0

Gaelan
Gaelan

Reputation: 1149

You can use dpid:user-presence to do this. Adding it you your app should add a collection named UserPresences containing information about every browser window currently open to your site.

Upvotes: 1

Related Questions