From 865db906e3ba697b5e5b6d9324c1dff4d4416746 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Tue, 19 Jan 2016 11:40:08 +0000 Subject: [PATCH] Make getUsers() return users for *EEEEEVERYOOOOONE* regardless of presence events --- lib/models/user.js | 26 ++++++++++++++++++++++++++ lib/store/memory.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/lib/models/user.js b/lib/models/user.js index bb797222d..97bc5732c 100644 --- a/lib/models/user.js +++ b/lib/models/user.js @@ -89,6 +89,32 @@ User.prototype.setPresenceEvent = function(event) { } }; +/** + * Manually set this user's display name. No event is emitted in response to this + * as there is no underlying MatrixEvent to emit with. + * @param {string} name The new display name. + */ +User.prototype.setDisplayName = function(name) { + var oldName = this.displayName; + this.displayName = name; + if (name !== oldName) { + this._updateModifiedTime(); + } +}; + +/** + * Manually set this user's avatar URL. No event is emitted in response to this + * as there is no underlying MatrixEvent to emit with. + * @param {string} url The new avatar URL. + */ +User.prototype.setAvatarUrl = function(url) { + var oldUrl = this.avatarUrl; + this.avatarUrl = url; + if (url !== oldUrl) { + this._updateModifiedTime(); + } +}; + /** * Update the last modified time to the current time. */ diff --git a/lib/store/memory.js b/lib/store/memory.js index b3fd7ff6d..a60d296bb 100644 --- a/lib/store/memory.js +++ b/lib/store/memory.js @@ -19,6 +19,7 @@ limitations under the License. * @module store/memory */ var utils = require("../utils"); + var User = require("../models/user"); /** * Construct a new in-memory data store for the Matrix Client. @@ -55,6 +56,7 @@ module.exports.MatrixInMemoryStore.prototype = { return this.syncToken; }, + /** * Set the token to stream from. * @param {string} token The token to stream from. @@ -69,6 +71,44 @@ module.exports.MatrixInMemoryStore.prototype = { */ storeRoom: function(room) { this.rooms[room.roomId] = room; + // add listeners for room member changes so we can keep the room member + // map up-to-date. + room.currentState.on("RoomState.members", this._onRoomMember.bind(this)); + // add existing members + var self = this; + room.currentState.getMembers().forEach(function(m) { + self._onRoomMember(null, room.currentState, m); + }); + }, + + /** + * Called when a room member in a room being tracked by this store has been + * updated. + * @param {MatrixEvent} event + * @param {RoomState} state + * @param {RoomMember} member + */ + _onRoomMember: function(event, state, member) { + if (member.membership === "invite") { + // We do NOT add invited members because people love to typo user IDs + // which would then show up in these lists (!) + return; + } + // We don't clobber any existing entry in the user map which has presence + // so user entries with presence info are preferred. This does mean we will + // clobber room member entries constantly, which is desirable to keep things + // like display names and avatar URLs up-to-date. + if (this.users[member.userId] && this.users[member.userId].events.presence) { + return; + } + + var user = new User(member.userId); + user.setDisplayName(member.name); + var rawUrl = ( + member.events.member ? member.events.member.getContent().avatar_url : null + ); + user.setAvatarUrl(rawUrl); + this.users[user.userId] = user; }, /** @@ -93,6 +133,9 @@ module.exports.MatrixInMemoryStore.prototype = { * @param {string} roomId */ removeRoom: function(roomId) { + if (this.rooms[roomId]) { + this.rooms[roomId].removeListener("RoomState.members", this._onRoomMember); + } delete this.rooms[roomId]; },