diff --git a/src/Entities.js b/src/Entities.js index 47103bfb65..5a666b1493 100644 --- a/src/Entities.js +++ b/src/Entities.js @@ -17,6 +17,31 @@ limitations under the License. var React = require('react'); var sdk = require('./index'); +function isMatch(query, name, uid) { + query = query.toLowerCase(); + name = name.toLowerCase(); + uid = uid.toLowerCase(); + + // direct prefix matches + if (name.indexOf(query) === 0 || uid.indexOf(query) === 0) { + return true; + } + + // strip @ on uid and try matching again + if (uid.length > 1 && uid[0] === "@" && uid.substring(1).indexOf(query) === 0) { + return true; + } + + // split spaces in name and try matching constituent parts + var parts = name.split(" "); + for (var i = 0; i < parts.length; i++) { + if (parts[i].indexOf(query) === 0) { + return true; + } + } + return false; +} + /* * Converts various data models to Entity objects. * @@ -49,7 +74,7 @@ class MemberEntity extends Entity { } matches(queryString) { - return this.model.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0; + return isMatch(queryString, this.model.name, this.model.userId); } } @@ -77,7 +102,7 @@ class UserEntity extends Entity { matches(queryString) { var name = this.model.displayName || this.model.userId; - return name.toLowerCase().indexOf(queryString.toLowerCase()) === 0; + return isMatch(queryString, name, this.model.userId); } } diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 3af4cdc44f..9172d43a24 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -51,6 +51,7 @@ module.exports = React.createClass({ var cli = MatrixClientPeg.get(); cli.on("RoomState.members", this.onRoomStateMember); cli.on("RoomMember.name", this.onRoomMemberName); + cli.on("RoomState.events", this.onRoomStateEvent); cli.on("Room", this.onRoom); // invites }, @@ -60,6 +61,7 @@ module.exports = React.createClass({ MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); MatrixClientPeg.get().removeListener("RoomMember.name", this.onRoomMemberName); MatrixClientPeg.get().removeListener("User.presence", this.userPresenceFn); + MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvent); } }, @@ -69,11 +71,13 @@ module.exports = React.createClass({ // Lazy-load in more than the first N members setTimeout(function() { if (!self.isMounted()) return; + // lazy load to prevent it blocking the first render + self._loadUserList(); + self.setState({ members: self.roomMembers() }); - // lazy load to prevent it blocking the first render - self._loadUserList(); + }, 50); // Attach a SINGLE listener for global presence changes then locate the @@ -133,6 +137,12 @@ module.exports = React.createClass({ this._updateList(); }, + onRoomStateEvent: function(event, state) { + if (event.getType() === "m.room.third_party_invite") { + this._updateList(); + } + }, + _updateList: function() { this.memberDict = this.getMemberDict();