Skip to content

Commit

Permalink
Factor out members (presence) functionality into encapsulated obj tha…
Browse files Browse the repository at this point in the history
…t operates based on channel events.

* Made private the members methods that should have been private: add, remove, clear.
* Members obj runs by listening to channel events.  PresenceChannel can be ignorant of its existence.
  • Loading branch information
maryrosecook committed Mar 28, 2012
1 parent ed71fda commit bdd09da
Showing 1 changed file with 57 additions and 59 deletions.
116 changes: 57 additions & 59 deletions src/pusher_channels.js
Expand Up @@ -84,73 +84,71 @@

Pusher.Channel.PresenceChannel = {
init: function(){
this.bind('pusher_internal:member_added', function(data){
var member = this.members.add(data.user_id, data.user_info);
this.emit('pusher:member_added', member);
}.scopedTo(this))

this.bind('pusher_internal:member_removed', function(data){
var member = this.members.remove(data.user_id);
if (member) {
this.emit('pusher:member_removed', member);
}
}.scopedTo(this))
},

disconnect: function(){
this.members.clear();
this.members = new Members(this); // leeches off channel events
},

onSubscriptionSucceeded: function(data) {
this.members._members_map = data.presence.hash;
this.members.count = data.presence.count;
this.subscribed = true;
// We override this because we want the Members obj to be responsible for
// emitting the pusher:subscription_succeeded. It will do this after it has done its work.
}
};

this.emit('pusher:subscription_succeeded', this.members);
},
var Members = function(channel) {
var self = this;

members: {
_members_map: {},
count: 0,
var reset = function() {
this._members_map = {};
this.count = 0;
};
reset.call(this);

each: function(callback) {
for(var i in this._members_map) {
callback({
id: i,
info: this._members_map[i]
});
}
},

add: function(id, info) {
this._members_map[id] = info;
this.count++;
return this.get(id);
},

remove: function(user_id) {
var member = this.get(user_id);
if (member) {
delete this._members_map[user_id];
this.count--;
}
return member;
},

get: function(user_id) {
if (this._members_map.hasOwnProperty(user_id)) { // have heard of this user user_id
return {
id: user_id,
info: this._members_map[user_id]
}
} else { // have never heard of this user
return null;
}
},
channel.bind('pusher_internal:authorized', function(authorizedData) {
channel.bind("pusher_internal:subscription_succeeded", function(subscriptionData) {
self._members_map = subscriptionData.presence.hash;
self.count = subscriptionData.presence.count;
channel.emit('pusher:subscription_succeeded', self);
});
});

clear: function() {
this._members_map = {};
this.count = 0;
channel.bind('pusher_internal:member_added', function(data) {
if(self.get(data.user_id) === null) { // only incr if user_id does not already exist
self.count++;
}

self._members_map[data.user_id] = data.user_info;
channel.emit('pusher:member_added', self.get(data.user_id));
});

channel.bind('pusher_internal:member_removed', function(data) {
var member = self.get(data.user_id);
if(member) {
delete self._members_map[data.user_id];
self.count--;
channel.emit('pusher:member_removed', member);
}
});

channel.bind('pusher_internal:disconnected', function() {
reset.call(self);
});
};

Members.prototype = {
each: function(callback) {
for(var i in this._members_map) {
callback(this.get(i));
}
},

get: function(user_id) {
if (this._members_map.hasOwnProperty(user_id)) { // have heard of this user user_id
return {
id: user_id,
info: this._members_map[user_id]
}
} else { // have never heard of this user
return null;
}
}
};
Expand Down

0 comments on commit bdd09da

Please sign in to comment.