From 5afb3bfb2959a3d61e8a024a042080785fafc7d2 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 10:53:25 +0200 Subject: [PATCH 1/7] patch up DMs marked to self (can happy if any client has a bug here) --- src/utils/DMRoomMap.js | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index d95eda490d..93ff565080 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -70,10 +70,46 @@ export default class DMRoomMap { _onAccountData(ev) { if (ev.getType() == 'm.direct') { - this.userToRooms = this.matrixClient.getAccountData('m.direct').getContent(); + let userToRooms = this.matrixClient.getAccountData('m.direct').getContent(); + const myUserId = this.matrixClient.getUserId(); + if (userToRooms[myUserId]) { + userToRooms = this._patchUpSelfDMs(userToRooms); + this.matrixClient.setAccountData('m.direct', userToRooms); + } + this.userToRooms = userToRooms; this._populateRoomToUser(); } } + /** + * some client bug somewhere is causing some DMs to be marked + * with ourself, not the other user. Fix it by guessing the other user and + * modifying userToRooms + */ + _patchUpSelfDMs(userToRooms) { + const myUserId = this.matrixClient.getUserId(); + const selfRoomIds = userToRooms[myUserId]; + if (selfRoomIds) { + const guessedUserIds = selfRoomIds.map((roomId) => { + const room = this.matrixClient.getRoom(roomId); + return room.guessDMUserId(); + }); + delete userToRooms[myUserId]; + guessedUserIds.forEach((userId, i) => { + if (!userId) { + // if not able to guess the other user (unlikely) + // still put it in the map so the room stays marked + // as a DM, we just wont be able to show an avatar. + userId = ""; + } + const roomId = selfRoomIds[i]; + const roomIds = userToRooms[userId]; + if (!roomIds) { + roomIds = userToRooms[userId] = []; + } + roomIds.push(roomId); + }); + } + } getDMRoomsForUserId(userId) { // Here, we return the empty list if there are no rooms, From d7868dbe3346a99aedc8facfb9d6cf83b6c8a5ab Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 10:54:01 +0200 Subject: [PATCH 2/7] delegate avatar selection to room for rooms with two members (but not in m.direct) --- src/components/views/avatars/RoomAvatar.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/components/views/avatars/RoomAvatar.js b/src/components/views/avatars/RoomAvatar.js index e0105159fb..7b9cb10d51 100644 --- a/src/components/views/avatars/RoomAvatar.js +++ b/src/components/views/avatars/RoomAvatar.js @@ -119,15 +119,7 @@ module.exports = React.createClass({ } else { // if the room is not marked as a 1:1, but only has max 2 members // then still try to show any avatar (pref. other member) - const totalMemberCount = room.getJoinedMemberCount() + - room.getInvitedMemberCount(); - const members = room.currentState.getMembers(); - if (totalMemberCount == 2) { - const myUserId = MatrixClientPeg.get().getUserId(); - otherMember = members.find(m => m.userId !== myUserId); - } else if (totalMemberCount == 1) { - otherMember = members[0]; - } + otherMember = room.getAvatarFallbackMember(); } if (otherMember) { return otherMember.getAvatarUrl( From caff60d56d85b9db0bca1e9e238fd2507c7c2c62 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 11:37:13 +0200 Subject: [PATCH 3/7] fix var decl --- src/utils/DMRoomMap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index 93ff565080..7974ab5681 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -102,7 +102,7 @@ export default class DMRoomMap { userId = ""; } const roomId = selfRoomIds[i]; - const roomIds = userToRooms[userId]; + let roomIds = userToRooms[userId]; if (!roomIds) { roomIds = userToRooms[userId] = []; } From 379ddfff2961faf381d12560ec78095314ed8018 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 11:50:57 +0200 Subject: [PATCH 4/7] dont reassign userToRooms as we're just patching it up, also better check if we really have self DMs --- src/utils/DMRoomMap.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index 7974ab5681..1db8e7f970 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -72,8 +72,9 @@ export default class DMRoomMap { if (ev.getType() == 'm.direct') { let userToRooms = this.matrixClient.getAccountData('m.direct').getContent(); const myUserId = this.matrixClient.getUserId(); - if (userToRooms[myUserId]) { - userToRooms = this._patchUpSelfDMs(userToRooms); + const selfDMs = userToRooms[myUserId]; + if (selfDMs && selfDMs.length) { + this._patchUpSelfDMs(userToRooms); this.matrixClient.setAccountData('m.direct', userToRooms); } this.userToRooms = userToRooms; From 85b6f157c1314d51b904f62cdef5080cf690efce Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 12:01:13 +0200 Subject: [PATCH 5/7] only patch m.direct data on server once per session to avoid request storm --- src/utils/DMRoomMap.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index 1db8e7f970..ff0a7cbbf0 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -27,6 +27,8 @@ export default class DMRoomMap { constructor(matrixClient) { this.matrixClient = matrixClient; this.roomToUser = null; + // see _onAccountData + this._hasSentOutPatchDirectAccountDataPatch = false; // XXX: Force-bind the event handler method because it // doesn't call it with our object as the 'this' @@ -75,7 +77,13 @@ export default class DMRoomMap { const selfDMs = userToRooms[myUserId]; if (selfDMs && selfDMs.length) { this._patchUpSelfDMs(userToRooms); - this.matrixClient.setAccountData('m.direct', userToRooms); + // to avoid multiple devices fighting to correct + // the account data, only try to send the corrected + // version once. + if (!this._hasSentOutPatchDirectAccountDataPatch) { + this._hasSentOutPatchDirectAccountDataPatch = true; + this.matrixClient.setAccountData('m.direct', userToRooms); + } } this.userToRooms = userToRooms; this._populateRoomToUser(); From d8f15e11594fde3dc1feda692d32b53659ff8be1 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 12:06:34 +0200 Subject: [PATCH 6/7] make sure we still have the room --- src/utils/DMRoomMap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index ff0a7cbbf0..7767e6bc8b 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -100,7 +100,7 @@ export default class DMRoomMap { if (selfRoomIds) { const guessedUserIds = selfRoomIds.map((roomId) => { const room = this.matrixClient.getRoom(roomId); - return room.guessDMUserId(); + return room && room.guessDMUserId(); }); delete userToRooms[myUserId]; guessedUserIds.forEach((userId, i) => { From fb0a0d5d9e83c0b4bd38f6346fb990456c8d92e7 Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Thu, 30 Aug 2018 12:36:53 +0200 Subject: [PATCH 7/7] allow self-chats --- src/utils/DMRoomMap.js | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js index 7767e6bc8b..0c5e696c5f 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.js @@ -72,15 +72,15 @@ export default class DMRoomMap { _onAccountData(ev) { if (ev.getType() == 'm.direct') { - let userToRooms = this.matrixClient.getAccountData('m.direct').getContent(); + const userToRooms = this.matrixClient.getAccountData('m.direct').getContent() || {}; const myUserId = this.matrixClient.getUserId(); const selfDMs = userToRooms[myUserId]; if (selfDMs && selfDMs.length) { - this._patchUpSelfDMs(userToRooms); + const neededPatching = this._patchUpSelfDMs(userToRooms); // to avoid multiple devices fighting to correct // the account data, only try to send the corrected // version once. - if (!this._hasSentOutPatchDirectAccountDataPatch) { + if (neededPatching && !this._hasSentOutPatchDirectAccountDataPatch) { this._hasSentOutPatchDirectAccountDataPatch = true; this.matrixClient.setAccountData('m.direct', userToRooms); } @@ -98,25 +98,40 @@ export default class DMRoomMap { const myUserId = this.matrixClient.getUserId(); const selfRoomIds = userToRooms[myUserId]; if (selfRoomIds) { - const guessedUserIds = selfRoomIds.map((roomId) => { + // any self-chats that should not be self-chats? + const guessedUserIdsThatChanged = selfRoomIds.map((roomId) => { const room = this.matrixClient.getRoom(roomId); - return room && room.guessDMUserId(); + if (room) { + const userId = room.guessDMUserId(); + if (userId && userId !== myUserId) { + return {userId, roomId}; + } + } + }).filter((ids) => !!ids); //filter out + // these are actually all legit self-chats + // bail out + if (!guessedUserIdsThatChanged.length) { + return false; + } + userToRooms[myUserId] = selfRoomIds.filter((roomId) => { + return guessedUserIdsThatChanged + .some((ids) => ids.roomId === roomId); }); - delete userToRooms[myUserId]; - guessedUserIds.forEach((userId, i) => { + + guessedUserIdsThatChanged.forEach(({userId, roomId}) => { if (!userId) { // if not able to guess the other user (unlikely) // still put it in the map so the room stays marked // as a DM, we just wont be able to show an avatar. userId = ""; } - const roomId = selfRoomIds[i]; let roomIds = userToRooms[userId]; if (!roomIds) { roomIds = userToRooms[userId] = []; } roomIds.push(roomId); }); + return true; } }