From 7b13c2221a91f7abd9aa08e749e9cd88dc7264a7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 17 Feb 2022 18:20:21 +0000 Subject: [PATCH 1/6] Add slash command to switch to a room's virtual room --- src/SlashCommands.tsx | 18 ++++++++++++++++++ src/VoipUserMapper.ts | 18 +++++++++++++++++- src/i18n/strings/en_EN.json | 2 ++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 637f324743f..6353caac540 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -65,6 +65,7 @@ import RoomViewStore from "./stores/RoomViewStore"; import { XOR } from "./@types/common"; import { PosthogAnalytics } from "./PosthogAnalytics"; import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload"; +import VoipUserMapper from './VoipUserMapper'; // XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816 interface HTMLInputEvent extends Event { @@ -1129,6 +1130,23 @@ export const Commands = [ }, category: CommandCategories.advanced, }), + new Command({ + command: "tovirtual", + description: _td("Switches to this room's virtual room, if it has one"), + category: CommandCategories.advanced, + runFn: (roomId) => { + return success((async () => { + const room = await VoipUserMapper.sharedInstance().getVirtualRoomForRoom(roomId); + if (!room) throw _t("No virtual room for this room"); + dis.dispatch({ + action: Action.ViewRoom, + room_id: room.roomId, + _trigger: "SlashCommand", + _viaKeyboard: true, + }); + })()); + }, + }), new Command({ command: "query", description: _td("Opens chat with the given user"), diff --git a/src/VoipUserMapper.ts b/src/VoipUserMapper.ts index c98c39a88d4..e1218b6b7db 100644 --- a/src/VoipUserMapper.ts +++ b/src/VoipUserMapper.ts @@ -42,13 +42,19 @@ export default class VoipUserMapper { return results[0].userid; } - public async getOrCreateVirtualRoomForRoom(roomId: string): Promise { + private async getVirtualUserForRoom(roomId: string): Promise { const userId = DMRoomMap.shared().getUserIdForRoomId(roomId); if (!userId) return null; const virtualUser = await this.userToVirtualUser(userId); if (!virtualUser) return null; + return virtualUser; + } + + public async getOrCreateVirtualRoomForRoom(roomId: string): Promise { + const virtualUser = await this.getVirtualUserForRoom(roomId); + const virtualRoomId = await ensureVirtualRoomExists(MatrixClientPeg.get(), virtualUser, roomId); MatrixClientPeg.get().setRoomAccountData(virtualRoomId, VIRTUAL_ROOM_EVENT_TYPE, { native_room: roomId, @@ -59,6 +65,16 @@ export default class VoipUserMapper { return virtualRoomId; } + /** + * Gets the ID of the virtual room for a room, or null if the room has no + * virtual room + */ + public async getVirtualRoomForRoom(roomId: string): Promise { + const virtualUser = await this.getVirtualUserForRoom(roomId); + + return findDMForUser(MatrixClientPeg.get(), virtualUser); + } + public nativeRoomForVirtualRoom(roomId: string): string { const cachedNativeRoomId = this.virtualToNativeRoomIdCache.get(roomId); if (cachedNativeRoomId) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 997bebff288..8223e6927e7 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -486,6 +486,8 @@ "Displays list of commands with usages and descriptions": "Displays list of commands with usages and descriptions", "Displays information about a user": "Displays information about a user", "Send a bug report with logs": "Send a bug report with logs", + "Switches to this room's virtual room, if it has one": "Switches to this room's virtual room, if it has one", + "No virtual room for this room": "No virtual room for this room", "Opens chat with the given user": "Opens chat with the given user", "Unable to find Matrix ID for phone number": "Unable to find Matrix ID for phone number", "Sends a message to the given user": "Sends a message to the given user", From e51645474070d9b32b16c30322e29405d46d5553 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 17 Feb 2022 18:24:58 +0000 Subject: [PATCH 2/6] Update to new interface --- src/SlashCommands.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 6353caac540..7f33c279f1e 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -1141,8 +1141,8 @@ export const Commands = [ dis.dispatch({ action: Action.ViewRoom, room_id: room.roomId, - _trigger: "SlashCommand", - _viaKeyboard: true, + metricsTrigger: "SlashCommand", + metricsViaKeyboard: true, }); })()); }, From 0baf9325d70013833190d851bd2f15f2d01fff3a Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 17 Feb 2022 18:53:22 +0000 Subject: [PATCH 3/6] Return null if no virtual user --- src/VoipUserMapper.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/VoipUserMapper.ts b/src/VoipUserMapper.ts index e1218b6b7db..fd5a35b489d 100644 --- a/src/VoipUserMapper.ts +++ b/src/VoipUserMapper.ts @@ -54,6 +54,7 @@ export default class VoipUserMapper { public async getOrCreateVirtualRoomForRoom(roomId: string): Promise { const virtualUser = await this.getVirtualUserForRoom(roomId); + if (!virtualUser) return null; const virtualRoomId = await ensureVirtualRoomExists(MatrixClientPeg.get(), virtualUser, roomId); MatrixClientPeg.get().setRoomAccountData(virtualRoomId, VIRTUAL_ROOM_EVENT_TYPE, { @@ -71,6 +72,7 @@ export default class VoipUserMapper { */ public async getVirtualRoomForRoom(roomId: string): Promise { const virtualUser = await this.getVirtualUserForRoom(roomId); + if (!virtualUser) return null; return findDMForUser(MatrixClientPeg.get(), virtualUser); } From c77886b8c211cb92eda7af08b4ccd89f889ac40f Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 21 Feb 2022 11:53:36 +0000 Subject: [PATCH 4/6] Throw newTranslateableError --- src/SlashCommands.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 7f33c279f1e..47419339685 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -1137,7 +1137,7 @@ export const Commands = [ runFn: (roomId) => { return success((async () => { const room = await VoipUserMapper.sharedInstance().getVirtualRoomForRoom(roomId); - if (!room) throw _t("No virtual room for this room"); + if (!room) throw newTranslatableError("No virtual room for this room"); dis.dispatch({ action: Action.ViewRoom, room_id: room.roomId, From 8749354cc89b5f4cad9235e166e3d7812698e265 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 21 Feb 2022 12:04:34 +0000 Subject: [PATCH 5/6] Types --- src/VoipUserMapper.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VoipUserMapper.ts b/src/VoipUserMapper.ts index fd5a35b489d..cb39d9affb4 100644 --- a/src/VoipUserMapper.ts +++ b/src/VoipUserMapper.ts @@ -42,7 +42,7 @@ export default class VoipUserMapper { return results[0].userid; } - private async getVirtualUserForRoom(roomId: string): Promise { + private async getVirtualUserForRoom(roomId: string): Promise { const userId = DMRoomMap.shared().getUserIdForRoomId(roomId); if (!userId) return null; @@ -52,7 +52,7 @@ export default class VoipUserMapper { return virtualUser; } - public async getOrCreateVirtualRoomForRoom(roomId: string): Promise { + public async getOrCreateVirtualRoomForRoom(roomId: string): Promise { const virtualUser = await this.getVirtualUserForRoom(roomId); if (!virtualUser) return null; @@ -70,7 +70,7 @@ export default class VoipUserMapper { * Gets the ID of the virtual room for a room, or null if the room has no * virtual room */ - public async getVirtualRoomForRoom(roomId: string): Promise { + public async getVirtualRoomForRoom(roomId: string): Promise { const virtualUser = await this.getVirtualUserForRoom(roomId); if (!virtualUser) return null; From c67998af9447c4f3be76aba9ccc81bbe7b87478d Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 21 Feb 2022 12:16:27 +0000 Subject: [PATCH 6/6] Disable tovirtual if virtual rooms not supported --- src/SlashCommands.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index 47419339685..395cf556b8a 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -1134,6 +1134,9 @@ export const Commands = [ command: "tovirtual", description: _td("Switches to this room's virtual room, if it has one"), category: CommandCategories.advanced, + isEnabled(): boolean { + return CallHandler.instance.getSupportsVirtualRooms(); + }, runFn: (roomId) => { return success((async () => { const room = await VoipUserMapper.sharedInstance().getVirtualRoomForRoom(roomId);