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); } }