From a11e1cc2f9e37e1261eade4d9c3c141dc7ae43fb Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Wed, 27 Jun 2018 17:39:20 +0100 Subject: [PATCH 01/19] [WIP] Send lazy_load_memberers filter when syncing --- src/MatrixClientPeg.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 9d86a62de45..01a411663c4 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -34,6 +34,14 @@ interface MatrixClientCreds { guest: boolean, } +const FILTER_CONTENT = { + room: { + state: { + lazy_load_members: true, + }, + }, +}; + /** * Wrapper object for handling the js-sdk Matrix Client object in the react-sdk * Handles the creation/initialisation of client objects. @@ -99,6 +107,8 @@ class MatrixClientPeg { // the react sdk doesn't work without this, so don't allow opts.pendingEventOrdering = "detached"; + opts.filter = await this.matrixClient.createFilter(FILTER_CONTENT); + try { const promise = this.matrixClient.store.startup(); console.log(`MatrixClientPeg: waiting for MatrixClient store to initialise`); From 8c985bd049a639e46db9698ed3a8ca96235ffb99 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Tue, 10 Jul 2018 17:20:52 +0200 Subject: [PATCH 02/19] ask client to lazy load room members when viewing a room --- src/stores/RoomViewStore.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index fed0d7b4a1e..05ad16912c5 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -133,6 +133,7 @@ class RoomViewStore extends Store { _viewRoom(payload) { if (payload.room_id) { + MatrixClientPeg.get().loadRoomMembersIfNeeded(payload.room_id); const newState = { roomId: payload.room_id, roomAlias: payload.room_alias, From de3e143a8fd68bf1b9d6e1f01fd2808958375fae Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 12 Jul 2018 19:38:08 +0200 Subject: [PATCH 03/19] only lazy load the members when viewing a joined room --- src/components/structures/RoomView.js | 3 +++ src/stores/RoomViewStore.js | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 0325b3d9a66..2c322b269d2 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -312,6 +312,9 @@ module.exports = React.createClass({ // Stop peeking because we have joined this room previously MatrixClientPeg.get().stopPeeking(); this.setState({isPeeking: false}); + + //viewing a previously joined room, try to lazy load members + MatrixClientPeg.get().loadRoomMembersIfNeeded(room.roomId); } } }, diff --git a/src/stores/RoomViewStore.js b/src/stores/RoomViewStore.js index 05ad16912c5..fed0d7b4a1e 100644 --- a/src/stores/RoomViewStore.js +++ b/src/stores/RoomViewStore.js @@ -133,7 +133,6 @@ class RoomViewStore extends Store { _viewRoom(payload) { if (payload.room_id) { - MatrixClientPeg.get().loadRoomMembersIfNeeded(payload.room_id); const newState = { roomId: payload.room_id, roomAlias: payload.room_alias, From 19387805ac3a95a8f0eaa84406c50767be0f0492 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 12 Jul 2018 19:39:52 +0200 Subject: [PATCH 04/19] Don't assume RoomMember has a state event in direct chat detection Instead call the method on the member that takes lazy loading into account --- src/components/structures/RoomView.js | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 2c322b269d2..3a9b3ae7480 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -749,21 +749,15 @@ module.exports = React.createClass({ }, _updateDMState() { - const me = this.state.room.getMember(MatrixClientPeg.get().credentials.userId); + const me = this.state.room.getMember(MatrixClientPeg.get().getUserId()); if (!me || me.membership !== "join") { return; } + const roomId = this.state.room.roomId; + const dmInviter = me.getDirectChatInviter(); - // The user may have accepted an invite with is_direct set - if (me.events.member.getPrevContent().membership === "invite" && - me.events.member.getPrevContent().is_direct - ) { - // This is a DM with the sender of the invite event (which we assume - // preceded the join event) - Rooms.setDMRoom( - this.state.room.roomId, - me.events.member.getUnsigned().prev_sender, - ); + if (dmInviter) { + Rooms.setDMRoom(roomId, dmInviter); return; } @@ -777,11 +771,8 @@ module.exports = React.createClass({ // The user may have sent an invite with is_direct sent const other = invitedMembers[0]; - if (other && - other.membership === "invite" && - other.events.member.getContent().is_direct - ) { - Rooms.setDMRoom(this.state.room.roomId, other.userId); + if (other && !!other.getDirectChatInviter()) { + Rooms.setDMRoom(roomId, other.userId); return; } }, From 6ff92ede8f26b403cc05f5e18b0c0f445bfdff13 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 13 Jul 2018 12:51:32 +0200 Subject: [PATCH 05/19] this code actually never fires, so remove it and that's ok because createRoom will already mark a DM as such on the inviter's side. So here we just handle the invitees side. --- src/components/structures/RoomView.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 3a9b3ae7480..a545eaab545 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -758,22 +758,6 @@ module.exports = React.createClass({ if (dmInviter) { Rooms.setDMRoom(roomId, dmInviter); - return; - } - - const invitedMembers = this.state.room.getMembersWithMembership("invite"); - const joinedMembers = this.state.room.getMembersWithMembership("join"); - - // There must be one invited member and one joined member - if (invitedMembers.length !== 1 || joinedMembers.length !== 1) { - return; - } - - // The user may have sent an invite with is_direct sent - const other = invitedMembers[0]; - if (other && !!other.getDirectChatInviter()) { - Rooms.setDMRoom(roomId, other.userId); - return; } }, From 54904c9282a14a31d9f01388b5341721f0f7a100 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 13 Jul 2018 14:21:15 +0200 Subject: [PATCH 06/19] use member helper method instead of digging inside member --- src/utils/DMRoomMap.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index d6242719ba4..186dc31c3a9 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -97,14 +97,8 @@ export default class DMRoomMap { // no entry? if the room is an invite, look for the is_direct hint. const room = this.matrixClient.getRoom(roomId); if (room) { - const me = room.getMember(this.matrixClient.credentials.userId); - if (me.membership == 'invite') { - // The 'direct' hihnt is there, so declare that this is a DM room for - // whoever invited us. - if (me.events.member.getContent().is_direct) { - return me.events.member.getSender(); - } - } + const me = room.getMember(this.matrixClient.getUserId()); + return me.getDirectChatInviter(); } } return this.roomToUser[roomId]; From e237a02fa5005e5ce23c0bef799e735eb7182abc Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 13 Jul 2018 14:23:24 +0200 Subject: [PATCH 07/19] use more consistent naming --- src/components/structures/RoomView.js | 2 +- src/utils/DMRoomMap.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index a545eaab545..8d4a15642f3 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -754,7 +754,7 @@ module.exports = React.createClass({ return; } const roomId = this.state.room.roomId; - const dmInviter = me.getDirectChatInviter(); + const dmInviter = me.getDMInviter(); if (dmInviter) { Rooms.setDMRoom(roomId, dmInviter); diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index 186dc31c3a9..d47282f370a 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -98,7 +98,7 @@ export default class DMRoomMap { const room = this.matrixClient.getRoom(roomId); if (room) { const me = room.getMember(this.matrixClient.getUserId()); - return me.getDirectChatInviter(); + return me.getDMInviter(); } } return this.roomToUser[roomId]; From 8529bc55e3a7a7aa5176ad261740a3e6bedb8c17 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 13 Jul 2018 14:25:12 +0200 Subject: [PATCH 08/19] use helper method for knowing whether a user was kicked mainly for readability, but also to discourage grabbing into the member because of lazy loading changes --- src/Rooms.js | 3 +-- src/stores/RoomListStore.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Rooms.js b/src/Rooms.js index ffa39141ff1..607bd60b985 100644 --- a/src/Rooms.js +++ b/src/Rooms.js @@ -81,8 +81,7 @@ export function isConfCallRoom(room, me, conferenceHandler) { } export function looksLikeDirectMessageRoom(room, me) { - if (me.membership == "join" || me.membership === "ban" || - (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) { + if (me.membership == "join" || me.membership === "ban" || me.isKicked()) { // Used to split rooms via tags const tagNames = Object.keys(room.tags); // Used for 1:1 direct chats diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index b6d0949dd3f..8dbfca88757 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -178,8 +178,7 @@ class RoomListStore extends Store { if (me.membership == "invite") { lists["im.vector.fake.invite"].push(room); - } else if (me.membership == "join" || me.membership === "ban" || - (me.membership === "leave" && me.events.member.getSender() !== me.events.member.getStateKey())) { + } else if (me.membership == "join" || me.membership === "ban" || me.isKicked()) { // Used to split rooms via tags let tagNames = Object.keys(room.tags); From af77f0206af4f71895f9aea0f6ba3054f229adec Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 13 Jul 2018 15:46:46 +0200 Subject: [PATCH 09/19] don't assume a member has events associated --- src/Rooms.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Rooms.js b/src/Rooms.js index 607bd60b985..aa025d7dc5d 100644 --- a/src/Rooms.js +++ b/src/Rooms.js @@ -166,7 +166,7 @@ export function guessDMRoomTarget(room, me) { for (const user of room.getJoinedMembers()) { if (user.userId == me.userId) continue; - if (oldestTs === undefined || user.events.member.getTs() < oldestTs) { + if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) { oldestUser = user; oldestTs = user.events.member.getTs(); } @@ -177,7 +177,7 @@ export function guessDMRoomTarget(room, me) { for (const user of room.currentState.getMembers()) { if (user.userId == me.userId) continue; - if (oldestTs === undefined || user.events.member.getTs() < oldestTs) { + if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) { oldestUser = user; oldestTs = user.events.member.getTs(); } From 8c9ceca14f5057cf09a20291255bae679b75c16a Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 13 Jul 2018 15:57:12 +0200 Subject: [PATCH 10/19] take into account lazy loading when enlarging avatar --- src/components/views/rooms/MemberInfo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 67189ac90fc..8b465cef9d3 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -598,7 +598,7 @@ module.exports = withMatrixClient(React.createClass({ onMemberAvatarClick: function() { const member = this.props.member; - const avatarUrl = member.user ? member.user.avatarUrl : member.events.member.getContent().avatar_url; + const avatarUrl = member.getMxcAvatarUrl(); if (!avatarUrl) return; const httpUrl = this.props.matrixClient.mxcUrlToHttp(avatarUrl); From 866b4bb067576c30927344ef4e98df6dd22ccad3 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 13 Jul 2018 16:01:29 +0200 Subject: [PATCH 11/19] use isKicked method in preview bar --- src/components/views/rooms/RoomPreviewBar.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/views/rooms/RoomPreviewBar.js b/src/components/views/rooms/RoomPreviewBar.js index 536093807ae..64c9b376dfc 100644 --- a/src/components/views/rooms/RoomPreviewBar.js +++ b/src/components/views/rooms/RoomPreviewBar.js @@ -101,11 +101,7 @@ module.exports = React.createClass({ const myMember = this.props.room ? this.props.room.currentState.members[ MatrixClientPeg.get().credentials.userId ] : null; - const kicked = ( - myMember && - myMember.membership == 'leave' && - myMember.events.member.getSender() != MatrixClientPeg.get().credentials.userId - ); + const kicked = myMember.isKicked(); const banned = myMember && myMember.membership == 'ban'; if (this.props.inviterName) { From af07d734325d6664af6a7e393a18b035591c1fc6 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 16 Jul 2018 15:07:53 +0200 Subject: [PATCH 12/19] hide lazy loading behind feature flag --- src/MatrixClientPeg.js | 4 +++- src/components/structures/RoomView.js | 6 +++++- src/settings/Settings.js | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 01a411663c4..82d18d307dd 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -107,7 +107,9 @@ class MatrixClientPeg { // the react sdk doesn't work without this, so don't allow opts.pendingEventOrdering = "detached"; - opts.filter = await this.matrixClient.createFilter(FILTER_CONTENT); + if (SettingsStore.isFeatureEnabled('feature_lazyloading')) { + opts.filter = await this.matrixClient.createFilter(FILTER_CONTENT); + } try { const promise = this.matrixClient.store.startup(); diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 8d4a15642f3..2eaf0180a93 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -314,7 +314,11 @@ module.exports = React.createClass({ this.setState({isPeeking: false}); //viewing a previously joined room, try to lazy load members - MatrixClientPeg.get().loadRoomMembersIfNeeded(room.roomId); + + // lazy load members if enabled + if (SettingsStore.isFeatureEnabled('feature_lazyloading')) { + MatrixClientPeg.get().loadRoomMembersIfNeeded(room.roomId); + } } } }, diff --git a/src/settings/Settings.js b/src/settings/Settings.js index e3f5855f0d7..d76c1fd8e8d 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -83,6 +83,11 @@ export const SETTINGS = { supportedLevels: LEVELS_FEATURE, default: false, }, + "feature_lazyloading": { + isFeature: true, + displayName: _td("Increase performance by loading room members on first view"), + supportedLevels: LEVELS_FEATURE, + }, "MessageComposerInput.dontSuggestEmoji": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td('Disable Emoji suggestions while typing'), From 201332d96cde1ef154abca0c40d99cf7c70cc845 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Mon, 16 Jul 2018 15:39:19 +0200 Subject: [PATCH 13/19] move comment after rebase --- src/components/structures/RoomView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 2eaf0180a93..9eb02999fdb 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -309,12 +309,12 @@ module.exports = React.createClass({ } }); } else if (room) { + //viewing a previously joined room, try to lazy load members + // Stop peeking because we have joined this room previously MatrixClientPeg.get().stopPeeking(); this.setState({isPeeking: false}); - //viewing a previously joined room, try to lazy load members - // lazy load members if enabled if (SettingsStore.isFeatureEnabled('feature_lazyloading')) { MatrixClientPeg.get().loadRoomMembersIfNeeded(room.roomId); From 34cb89e86a47b831a3d6bfea8add6b3b56746a50 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 18 Jul 2018 12:14:26 +0200 Subject: [PATCH 14/19] fix tests --- test/components/views/rooms/RoomList-test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/components/views/rooms/RoomList-test.js b/test/components/views/rooms/RoomList-test.js index f40a89777bf..c0a0b8eb67e 100644 --- a/test/components/views/rooms/RoomList-test.js +++ b/test/components/views/rooms/RoomList-test.js @@ -14,7 +14,7 @@ import dis from '../../../../src/dispatcher'; import DMRoomMap from '../../../../src/utils/DMRoomMap.js'; import GroupStore from '../../../../src/stores/GroupStore.js'; -import { Room, RoomMember } from 'matrix-js-sdk'; +import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk'; function generateRoomId() { return '!' + Math.random().toString().slice(2, 10) + ':domain'; @@ -48,6 +48,8 @@ describe('RoomList', () => { sandbox = TestUtils.stubClient(sandbox); client = MatrixClientPeg.get(); client.credentials = {userId: myUserId}; + //revert this to prototype method as the test-utils monkey-patches this to return a hardcoded value + client.getUserId = MatrixClient.prototype.getUserId; clock = lolex.install(); From 33f556066636cebf2ac55264e0496a06cd308bca Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 19 Jul 2018 15:04:39 +0200 Subject: [PATCH 15/19] move error message to caller of lazy loading --- src/components/structures/RoomView.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 9eb02999fdb..c7429753778 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -317,7 +317,12 @@ module.exports = React.createClass({ // lazy load members if enabled if (SettingsStore.isFeatureEnabled('feature_lazyloading')) { - MatrixClientPeg.get().loadRoomMembersIfNeeded(room.roomId); + MatrixClientPeg.get().loadRoomMembersIfNeeded(room.roomId).catch((err) => { + const errorMessage = `Fetching room members for ${this.roomId} failed.` + + " Room members will appear incomplete."; + console.error(errorMessage); + console.error(err); + }); } } } From f79e2eae40b75a87702e6dfcc7bcdb9176b6b4ef Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 25 Jul 2018 12:39:46 +0200 Subject: [PATCH 16/19] might not have loaded members here yet --- src/components/views/rooms/RoomPreviewBar.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/views/rooms/RoomPreviewBar.js b/src/components/views/rooms/RoomPreviewBar.js index 64c9b376dfc..5ec19d185ea 100644 --- a/src/components/views/rooms/RoomPreviewBar.js +++ b/src/components/views/rooms/RoomPreviewBar.js @@ -98,11 +98,11 @@ module.exports = React.createClass({ ); } - const myMember = this.props.room ? this.props.room.currentState.members[ - MatrixClientPeg.get().credentials.userId - ] : null; - const kicked = myMember.isKicked(); - const banned = myMember && myMember.membership == 'ban'; + const myMember = this.props.room ? + this.props.room.getMember(MatrixClientPeg.get().getUserId()) : + null; + const kicked = myMember && myMember.isKicked(); + const banned = myMember && myMember && myMember.membership == 'ban'; if (this.props.inviterName) { let emailMatchBlock; From 7ea913ccecbae5ccf887e16358bb3faa93bd7f57 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 25 Jul 2018 14:14:36 +0200 Subject: [PATCH 17/19] fall back to synced membership when own membership is not yet available (due to lazy loading) --- src/stores/RoomListStore.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 8dbfca88757..b95eafa2ab7 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -174,11 +174,11 @@ class RoomListStore extends Store { this._matrixClient.getRooms().forEach((room, index) => { const me = room.getMember(this._matrixClient.credentials.userId); - if (!me) return; + const membership = me ? me.membership : room.getSyncedMembership(); - if (me.membership == "invite") { + if (membership == "invite") { lists["im.vector.fake.invite"].push(room); - } else if (me.membership == "join" || me.membership === "ban" || me.isKicked()) { + } else if (membership == "join" || membership === "ban" || me.isKicked()) { // Used to split rooms via tags let tagNames = Object.keys(room.tags); @@ -205,10 +205,10 @@ class RoomListStore extends Store { } else { lists["im.vector.fake.recent"].push(room); } - } else if (me.membership === "leave") { + } else if (membership === "leave") { lists["im.vector.fake.archived"].push(room); } else { - console.error("unrecognised membership: " + me.membership + " - this should never happen"); + console.error("unrecognised membership: " + membership + " - this should never happen"); } }); From d87d34030aff688b6cf811e540f6bea2e3ff64da Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 25 Jul 2018 14:54:10 +0200 Subject: [PATCH 18/19] fix dm detection and conf call code with lazy loading --- src/Rooms.js | 46 ++++++++++++++------------ src/components/views/rooms/RoomList.js | 4 +-- src/stores/RoomListStore.js | 3 +- src/utils/DMRoomMap.js | 3 +- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/Rooms.js b/src/Rooms.js index aa025d7dc5d..2fda46450f4 100644 --- a/src/Rooms.js +++ b/src/Rooms.js @@ -31,26 +31,26 @@ export function getDisplayAliasForRoom(room) { * If the room contains only two members including the logged-in user, * return the other one. Otherwise, return null. */ -export function getOnlyOtherMember(room, me) { - const joinedMembers = room.getJoinedMembers(); +export function getOnlyOtherMember(room, myUserId) { - if (joinedMembers.length === 2) { - return joinedMembers.filter(function(m) { - return m.userId !== me.userId; + if (room.currentState.getJoinedMemberCount() === 2) { + return room.getJoinedMembers().filter(function(m) { + return m.userId !== myUserId; })[0]; } return null; } -function _isConfCallRoom(room, me, conferenceHandler) { +function _isConfCallRoom(room, myUserId, conferenceHandler) { if (!conferenceHandler) return false; - if (me.membership != "join") { + const myMembership = room.getMyMembership(myUserId); + if (myMembership != "join") { return false; } - const otherMember = getOnlyOtherMember(room, me); + const otherMember = getOnlyOtherMember(room, myUserId); if (otherMember === null) { return false; } @@ -68,28 +68,30 @@ const isConfCallRoomCache = { // $roomId: bool }; -export function isConfCallRoom(room, me, conferenceHandler) { +export function isConfCallRoom(room, myUserId, conferenceHandler) { if (isConfCallRoomCache[room.roomId] !== undefined) { return isConfCallRoomCache[room.roomId]; } - const result = _isConfCallRoom(room, me, conferenceHandler); + const result = _isConfCallRoom(room, myUserId, conferenceHandler); isConfCallRoomCache[room.roomId] = result; return result; } -export function looksLikeDirectMessageRoom(room, me) { - if (me.membership == "join" || me.membership === "ban" || me.isKicked()) { +export function looksLikeDirectMessageRoom(room, myUserId) { + const myMembership = room.getMyMembership(myUserId); + const me = room.getMember(myUserId); + + if (myMembership == "join" || myMembership === "ban" || (me && me.isKicked())) { // Used to split rooms via tags const tagNames = Object.keys(room.tags); // Used for 1:1 direct chats - const members = room.currentState.getMembers(); - // Show 1:1 chats in seperate "Direct Messages" section as long as they haven't // been moved to a different tag section - if (members.length === 2 && !tagNames.length) { + // TODO: Use SUMMARYAPI to take invited users into account + if (room.currentState.getJoinedMemberCount() === 2 && !tagNames.length) { return true; } } @@ -99,10 +101,10 @@ export function looksLikeDirectMessageRoom(room, me) { export function guessAndSetDMRoom(room, isDirect) { let newTarget; if (isDirect) { - const guessedTarget = guessDMRoomTarget( - room, room.getMember(MatrixClientPeg.get().credentials.userId), + const guessedUserId = guessDMRoomTargetId( + room, MatrixClientPeg.get().getUserId() ); - newTarget = guessedTarget.userId; + newTarget = guessedUserId; } else { newTarget = null; } @@ -158,13 +160,13 @@ export function setDMRoom(roomId, userId) { * Given a room, estimate which of its members is likely to * be the target if the room were a DM room and return that user. */ -export function guessDMRoomTarget(room, me) { +function guessDMRoomTargetId(room, myUserId) { let oldestTs; let oldestUser; // Pick the joined user who's been here longest (and isn't us), for (const user of room.getJoinedMembers()) { - if (user.userId == me.userId) continue; + if (user.userId == myUserId) continue; if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) { oldestUser = user; @@ -175,7 +177,7 @@ export function guessDMRoomTarget(room, me) { // if there are no joined members other than us, use the oldest member for (const user of room.currentState.getMembers()) { - if (user.userId == me.userId) continue; + if (user.userId == myUserId) continue; if (oldestTs === undefined || (user.events.member && user.events.member.getTs() < oldestTs)) { oldestUser = user; @@ -183,6 +185,6 @@ export function guessDMRoomTarget(room, me) { } } - if (oldestUser === undefined) return me; + if (oldestUser === undefined) return myUserId; return oldestUser; } diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js index 8533e3f61a0..9d48ed32c96 100644 --- a/src/components/views/rooms/RoomList.js +++ b/src/components/views/rooms/RoomList.js @@ -342,8 +342,8 @@ module.exports = React.createClass({ if (!taggedRoom) { return; } - const me = taggedRoom.getMember(MatrixClientPeg.get().credentials.userId); - if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(taggedRoom, me, this.props.ConferenceHandler)) { + const myUserId = MatrixClientPeg.get().getUserId(); + if (HIDE_CONFERENCE_CHANS && Rooms.isConfCallRoom(taggedRoom, myUserId, this.props.ConferenceHandler)) { return; } diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index b95eafa2ab7..38ad7e0b3d6 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -173,8 +173,7 @@ class RoomListStore extends Store { if (!this._matrixClient) return; this._matrixClient.getRooms().forEach((room, index) => { - const me = room.getMember(this._matrixClient.credentials.userId); - const membership = me ? me.membership : room.getSyncedMembership(); + const membership = room.getMyMembership(this._matrixClient.getUserId()); if (membership == "invite") { lists["im.vector.fake.invite"].push(room); diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index d47282f370a..acb1573cbfb 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -96,9 +96,10 @@ export default class DMRoomMap { if (this.roomToUser[roomId] === undefined) { // no entry? if the room is an invite, look for the is_direct hint. const room = this.matrixClient.getRoom(roomId); + // TODO Use SUMMARYAPI to fix DM detection? if (room) { const me = room.getMember(this.matrixClient.getUserId()); - return me.getDMInviter(); + return me && me.getDMInviter(); } } return this.roomToUser[roomId]; From cfd20c7e85c75671bf408c8eea6e3114bd78696d Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Wed, 25 Jul 2018 16:08:44 +0200 Subject: [PATCH 19/19] fix error/tests --- src/stores/RoomListStore.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js index 38ad7e0b3d6..e415389423e 100644 --- a/src/stores/RoomListStore.js +++ b/src/stores/RoomListStore.js @@ -173,11 +173,13 @@ class RoomListStore extends Store { if (!this._matrixClient) return; this._matrixClient.getRooms().forEach((room, index) => { - const membership = room.getMyMembership(this._matrixClient.getUserId()); + const myUserId = this._matrixClient.getUserId(); + const membership = room.getMyMembership(myUserId); + const me = room.getMember(myUserId); if (membership == "invite") { lists["im.vector.fake.invite"].push(room); - } else if (membership == "join" || membership === "ban" || me.isKicked()) { + } else if (membership == "join" || membership === "ban" || (me && me.isKicked())) { // Used to split rooms via tags let tagNames = Object.keys(room.tags);