From ac7f86cf65eaa1b134c53cf500d7355c958ba130 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 13 Jan 2021 14:49:23 +0000 Subject: [PATCH 1/5] Convert DMRoomMap to typescript --- src/settings/Settings.ts | 4 ++ src/utils/{DMRoomMap.js => DMRoomMap.ts} | 58 +++++++++++++----------- 2 files changed, 35 insertions(+), 27 deletions(-) rename src/utils/{DMRoomMap.js => DMRoomMap.ts} (82%) diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index b239b809fe..4a1e4e630d 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -398,6 +398,10 @@ export const SETTINGS: {[setting: string]: ISetting} = { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, default: null, }, + "voip_mxid_translate_pattern": { + supportedLevels: LEVELS_UI_FEATURE, // not a UI feature, but same level (config only, maybe .well-known in future) + default: null, + }, "language": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: "en", diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.ts similarity index 82% rename from src/utils/DMRoomMap.js rename to src/utils/DMRoomMap.ts index 4e219b1611..fc6e3ec5d4 100644 --- a/src/utils/DMRoomMap.js +++ b/src/utils/DMRoomMap.ts @@ -1,6 +1,5 @@ /* -Copyright 2016 OpenMarket Ltd -Copyright 2019, 2020 The Matrix.org Foundation C.I.C. +Copyright 2016, 2019, 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,7 +16,9 @@ limitations under the License. import {MatrixClientPeg} from '../MatrixClientPeg'; import {uniq} from "lodash"; -import {Room} from "matrix-js-sdk/src/matrix"; +import {Room} from "matrix-js-sdk/src/models/room"; +import {Event} from "matrix-js-sdk/src/models/event"; +import {MatrixClient} from "matrix-js-sdk/src/client"; /** * Class that takes a Matrix Client and flips the m.direct map @@ -27,29 +28,31 @@ import {Room} from "matrix-js-sdk/src/matrix"; * With 'start', this can also keep itself up to date over time. */ export default class DMRoomMap { + private static sharedInstance: DMRoomMap; + + private matrixClient: MatrixClient; + // TODO: convert these to maps + private roomToUser: {[key: string]: string} = null; + private userToRooms: {[key: string]: string[]} = null; + private hasSentOutPatchDirectAccountDataPatch: boolean; + private mDirectEvent: Event; + 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' - // (use a static property arrow function for this when we can) - this._onAccountData = this._onAccountData.bind(this); + // see onAccountData + this.hasSentOutPatchDirectAccountDataPatch = false; const mDirectEvent = matrixClient.getAccountData('m.direct'); this.mDirectEvent = mDirectEvent ? mDirectEvent.getContent() : {}; - this.userToRooms = null; } /** * Makes and returns a new shared instance that can then be accessed * with shared(). This returned instance is not automatically started. */ - static makeShared() { - DMRoomMap._sharedInstance = new DMRoomMap(MatrixClientPeg.get()); - return DMRoomMap._sharedInstance; + static makeShared(): DMRoomMap { + DMRoomMap.sharedInstance = new DMRoomMap(MatrixClientPeg.get()); + return DMRoomMap.sharedInstance; } /** @@ -57,26 +60,27 @@ export default class DMRoomMap { * that uses the singleton matrix client * The shared instance must be started before use. */ - static shared() { - return DMRoomMap._sharedInstance; + static shared(): DMRoomMap { + return DMRoomMap.sharedInstance; } start() { this._populateRoomToUser(); - this.matrixClient.on("accountData", this._onAccountData); + this.matrixClient.on("accountData", this.onAccountData); } stop() { - this.matrixClient.removeListener("accountData", this._onAccountData); + this.matrixClient.removeListener("accountData", this.onAccountData); } - _onAccountData(ev) { + private onAccountData = (ev) => { if (ev.getType() == 'm.direct') { this.mDirectEvent = this.matrixClient.getAccountData('m.direct').getContent() || {}; this.userToRooms = null; this.roomToUser = null; } } + /** * 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 @@ -118,7 +122,7 @@ export default class DMRoomMap { } } - getDMRoomsForUserId(userId) { + getDMRoomsForUserId(userId): string[] { // Here, we return the empty list if there are no rooms, // since the number of conversations you have with this user is zero. return this._getUserToRooms()[userId] || []; @@ -129,7 +133,7 @@ export default class DMRoomMap { * @param {string[]} ids The identifiers (user IDs and email addresses) to look for. * @returns {Room} The DM room which all IDs given share, or falsey if no common room. */ - getDMRoomForIdentifiers(ids) { + getDMRoomForIdentifiers(ids: string[]): Room { // TODO: [Canonical DMs] Handle lookups for email addresses. // For now we'll pretend we only get user IDs and end up returning nothing for email addresses @@ -145,7 +149,7 @@ export default class DMRoomMap { return joinedRooms[0]; } - getUserIdForRoomId(roomId) { + getUserIdForRoomId(roomId: string) { if (this.roomToUser == null) { // we lazily populate roomToUser so you can use // this class just to call getDMRoomsForUserId @@ -175,9 +179,9 @@ export default class DMRoomMap { .reduce((obj, r) => (obj[r.userId] = r.room) && obj, {}); } - _getUserToRooms() { + _getUserToRooms(): {[key: string]: string[]} { if (!this.userToRooms) { - const userToRooms = this.mDirectEvent; + const userToRooms = this.mDirectEvent as {[key: string]: string[]}; const myUserId = this.matrixClient.getUserId(); const selfDMs = userToRooms[myUserId]; if (selfDMs && selfDMs.length) { @@ -187,8 +191,8 @@ export default class DMRoomMap { // version once. console.warn(`Invalid m.direct account data detected ` + `(self-chats that shouldn't be), patching it up.`); - if (neededPatching && !this._hasSentOutPatchDirectAccountDataPatch) { - this._hasSentOutPatchDirectAccountDataPatch = true; + if (neededPatching && !this.hasSentOutPatchDirectAccountDataPatch) { + this.hasSentOutPatchDirectAccountDataPatch = true; this.matrixClient.setAccountData('m.direct', userToRooms); } } From ea31d5821bb51a293ddd99d62609c61b0f6c2833 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 13 Jan 2021 14:54:12 +0000 Subject: [PATCH 2/5] Unintnetional commit (again) --- src/settings/Settings.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 4a1e4e630d..b239b809fe 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -398,10 +398,6 @@ export const SETTINGS: {[setting: string]: ISetting} = { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, default: null, }, - "voip_mxid_translate_pattern": { - supportedLevels: LEVELS_UI_FEATURE, // not a UI feature, but same level (config only, maybe .well-known in future) - default: null, - }, "language": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: "en", From 28fe6291d9206fbdc147965a1d0cc116f50183e7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 13 Jan 2021 15:37:49 +0000 Subject: [PATCH 3/5] add public/privates & de-underscore --- src/utils/DMRoomMap.ts | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/utils/DMRoomMap.ts b/src/utils/DMRoomMap.ts index fc6e3ec5d4..3a8c109b79 100644 --- a/src/utils/DMRoomMap.ts +++ b/src/utils/DMRoomMap.ts @@ -50,7 +50,7 @@ export default class DMRoomMap { * Makes and returns a new shared instance that can then be accessed * with shared(). This returned instance is not automatically started. */ - static makeShared(): DMRoomMap { + public static makeShared(): DMRoomMap { DMRoomMap.sharedInstance = new DMRoomMap(MatrixClientPeg.get()); return DMRoomMap.sharedInstance; } @@ -60,16 +60,16 @@ export default class DMRoomMap { * that uses the singleton matrix client * The shared instance must be started before use. */ - static shared(): DMRoomMap { + public static shared(): DMRoomMap { return DMRoomMap.sharedInstance; } - start() { - this._populateRoomToUser(); + public start() { + this.populateRoomToUser(); this.matrixClient.on("accountData", this.onAccountData); } - stop() { + public stop() { this.matrixClient.removeListener("accountData", this.onAccountData); } @@ -86,7 +86,7 @@ export default class DMRoomMap { * with ourself, not the other user. Fix it by guessing the other user and * modifying userToRooms */ - _patchUpSelfDMs(userToRooms) { + private patchUpSelfDMs(userToRooms) { const myUserId = this.matrixClient.getUserId(); const selfRoomIds = userToRooms[myUserId]; if (selfRoomIds) { @@ -122,10 +122,10 @@ export default class DMRoomMap { } } - getDMRoomsForUserId(userId): string[] { + public getDMRoomsForUserId(userId): string[] { // Here, we return the empty list if there are no rooms, // since the number of conversations you have with this user is zero. - return this._getUserToRooms()[userId] || []; + return this.getUserToRooms()[userId] || []; } /** @@ -133,7 +133,7 @@ export default class DMRoomMap { * @param {string[]} ids The identifiers (user IDs and email addresses) to look for. * @returns {Room} The DM room which all IDs given share, or falsey if no common room. */ - getDMRoomForIdentifiers(ids: string[]): Room { + public getDMRoomForIdentifiers(ids: string[]): Room { // TODO: [Canonical DMs] Handle lookups for email addresses. // For now we'll pretend we only get user IDs and end up returning nothing for email addresses @@ -149,7 +149,7 @@ export default class DMRoomMap { return joinedRooms[0]; } - getUserIdForRoomId(roomId: string) { + public getUserIdForRoomId(roomId: string) { if (this.roomToUser == null) { // we lazily populate roomToUser so you can use // this class just to call getDMRoomsForUserId @@ -157,7 +157,7 @@ export default class DMRoomMap { // convenient wrapper and there's no point // iterating through the map if getUserIdForRoomId() // is never called. - this._populateRoomToUser(); + this.populateRoomToUser(); } // Here, we return undefined if the room is not in the map: // the room ID you gave is not a DM room for any user. @@ -171,7 +171,7 @@ export default class DMRoomMap { return this.roomToUser[roomId]; } - getUniqueRoomsWithIndividuals(): {[userId: string]: Room} { + public getUniqueRoomsWithIndividuals(): {[userId: string]: Room} { if (!this.roomToUser) return {}; // No rooms means no map. return Object.keys(this.roomToUser) .map(r => ({userId: this.getUserIdForRoomId(r), room: this.matrixClient.getRoom(r)})) @@ -179,7 +179,7 @@ export default class DMRoomMap { .reduce((obj, r) => (obj[r.userId] = r.room) && obj, {}); } - _getUserToRooms(): {[key: string]: string[]} { + private getUserToRooms(): {[key: string]: string[]} { if (!this.userToRooms) { const userToRooms = this.mDirectEvent as {[key: string]: string[]}; const myUserId = this.matrixClient.getUserId(); @@ -201,7 +201,7 @@ export default class DMRoomMap { return this.userToRooms; } - _populateRoomToUser() { + private populateRoomToUser() { this.roomToUser = {}; for (const user of Object.keys(this._getUserToRooms())) { for (const roomId of this.userToRooms[user]) { From 008fdf8dfbc4cd45c2907d672a947fb46ddd72c7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 13 Jan 2021 15:44:33 +0000 Subject: [PATCH 4/5] Missed some underscores --- src/utils/DMRoomMap.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/DMRoomMap.ts b/src/utils/DMRoomMap.ts index 3a8c109b79..e49b74c380 100644 --- a/src/utils/DMRoomMap.ts +++ b/src/utils/DMRoomMap.ts @@ -185,7 +185,7 @@ export default class DMRoomMap { const myUserId = this.matrixClient.getUserId(); const selfDMs = userToRooms[myUserId]; if (selfDMs && selfDMs.length) { - const neededPatching = 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. @@ -203,7 +203,7 @@ export default class DMRoomMap { private populateRoomToUser() { this.roomToUser = {}; - for (const user of Object.keys(this._getUserToRooms())) { + for (const user of Object.keys(this.getUserToRooms())) { for (const roomId of this.userToRooms[user]) { this.roomToUser[roomId] = user; } From 6371a4abd1f3e7318b96e4dc40704e5607b133c5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 13 Jan 2021 16:02:35 +0000 Subject: [PATCH 5/5] Fix tests Remove stray file extensions in includes and update shared instance name. --- test/components/views/rooms/RoomList-test.js | 4 ++-- test/utils/ShieldUtils-test.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/components/views/rooms/RoomList-test.js b/test/components/views/rooms/RoomList-test.js index c2cad431f4..1c2a1c9992 100644 --- a/test/components/views/rooms/RoomList-test.js +++ b/test/components/views/rooms/RoomList-test.js @@ -9,8 +9,8 @@ import sdk from '../../../skinned-sdk'; import { DragDropContext } from 'react-beautiful-dnd'; import dis from '../../../../src/dispatcher/dispatcher'; -import DMRoomMap from '../../../../src/utils/DMRoomMap.js'; -import GroupStore from '../../../../src/stores/GroupStore.js'; +import DMRoomMap from '../../../../src/utils/DMRoomMap'; +import GroupStore from '../../../../src/stores/GroupStore'; import { MatrixClient, Room, RoomMember } from 'matrix-js-sdk'; import {DefaultTagID} from "../../../../src/stores/room-list/models"; diff --git a/test/utils/ShieldUtils-test.js b/test/utils/ShieldUtils-test.js index e4c0c671e3..8e3b19c1c4 100644 --- a/test/utils/ShieldUtils-test.js +++ b/test/utils/ShieldUtils-test.js @@ -42,7 +42,7 @@ describe("mkClient self-test", function() { describe("shieldStatusForMembership self-trust behaviour", function() { beforeAll(() => { - DMRoomMap._sharedInstance = { + DMRoomMap.sharedInstance = { getUserIdForRoomId: (roomId) => roomId === "DM" ? "@any:h" : null, }; });