@@ -27,6 +27,8 @@ export default class DMRoomMap {
27
27
constructor ( matrixClient ) {
28
28
this . matrixClient = matrixClient ;
29
29
this . roomToUser = null ;
30
+ // see _onAccountData
31
+ this . _hasSentOutPatchDirectAccountDataPatch = false ;
30
32
31
33
// XXX: Force-bind the event handler method because it
32
34
// doesn't call it with our object as the 'this'
@@ -70,10 +72,68 @@ export default class DMRoomMap {
70
72
71
73
_onAccountData ( ev ) {
72
74
if ( ev . getType ( ) == 'm.direct' ) {
73
- this . userToRooms = this . matrixClient . getAccountData ( 'm.direct' ) . getContent ( ) ;
75
+ const userToRooms = this . matrixClient . getAccountData ( 'm.direct' ) . getContent ( ) || { } ;
76
+ const myUserId = this . matrixClient . getUserId ( ) ;
77
+ const selfDMs = userToRooms [ myUserId ] ;
78
+ if ( selfDMs && selfDMs . length ) {
79
+ const neededPatching = this . _patchUpSelfDMs ( userToRooms ) ;
80
+ // to avoid multiple devices fighting to correct
81
+ // the account data, only try to send the corrected
82
+ // version once.
83
+ if ( neededPatching && ! this . _hasSentOutPatchDirectAccountDataPatch ) {
84
+ this . _hasSentOutPatchDirectAccountDataPatch = true ;
85
+ this . matrixClient . setAccountData ( 'm.direct' , userToRooms ) ;
86
+ }
87
+ }
88
+ this . userToRooms = userToRooms ;
74
89
this . _populateRoomToUser ( ) ;
75
90
}
76
91
}
92
+ /**
93
+ * some client bug somewhere is causing some DMs to be marked
94
+ * with ourself, not the other user. Fix it by guessing the other user and
95
+ * modifying userToRooms
96
+ */
97
+ _patchUpSelfDMs ( userToRooms ) {
98
+ const myUserId = this . matrixClient . getUserId ( ) ;
99
+ const selfRoomIds = userToRooms [ myUserId ] ;
100
+ if ( selfRoomIds ) {
101
+ // any self-chats that should not be self-chats?
102
+ const guessedUserIdsThatChanged = selfRoomIds . map ( ( roomId ) => {
103
+ const room = this . matrixClient . getRoom ( roomId ) ;
104
+ if ( room ) {
105
+ const userId = room . guessDMUserId ( ) ;
106
+ if ( userId && userId !== myUserId ) {
107
+ return { userId, roomId} ;
108
+ }
109
+ }
110
+ } ) . filter ( ( ids ) => ! ! ids ) ; //filter out
111
+ // these are actually all legit self-chats
112
+ // bail out
113
+ if ( ! guessedUserIdsThatChanged . length ) {
114
+ return false ;
115
+ }
116
+ userToRooms [ myUserId ] = selfRoomIds . filter ( ( roomId ) => {
117
+ return guessedUserIdsThatChanged
118
+ . some ( ( ids ) => ids . roomId === roomId ) ;
119
+ } ) ;
120
+
121
+ guessedUserIdsThatChanged . forEach ( ( { userId, roomId} ) => {
122
+ if ( ! userId ) {
123
+ // if not able to guess the other user (unlikely)
124
+ // still put it in the map so the room stays marked
125
+ // as a DM, we just wont be able to show an avatar.
126
+ userId = "" ;
127
+ }
128
+ let roomIds = userToRooms [ userId ] ;
129
+ if ( ! roomIds ) {
130
+ roomIds = userToRooms [ userId ] = [ ] ;
131
+ }
132
+ roomIds . push ( roomId ) ;
133
+ } ) ;
134
+ return true ;
135
+ }
136
+ }
77
137
78
138
getDMRoomsForUserId ( userId ) {
79
139
// Here, we return the empty list if there are no rooms,
0 commit comments