Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Add slash command to switch to a room's virtual room #7839

Merged
merged 6 commits into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/SlashCommands.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -1129,6 +1130,26 @@ export const Commands = [
},
category: CommandCategories.advanced,
}),
new Command({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm moderately surprised the command isn't behind an isEnabled check as well - is there something we can use to disable the command in unintentional environments?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I didn't even notice isEnabled(). We could use the check for native/virtual lookup support on the server. I'm sort of surprised we're ever disabling commands though? Maybe for disabled labs features, but having command just disappear in certain situations rather than just return an error seems really confusing. Especially the 'op' command? I guess this seems to be the precedent though...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commands disappearing is definitely a concern, though I think for features like this it's moderately more confusing to have it show up compared to something like /op disappearing.

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);
if (!room) throw newTranslatableError("No virtual room for this room");
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: room.roomId,
metricsTrigger: "SlashCommand",
metricsViaKeyboard: true,
});
})());
},
}),
new Command({
command: "query",
description: _td("Opens chat with the given user"),
Expand Down
20 changes: 19 additions & 1 deletion src/VoipUserMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,20 @@ export default class VoipUserMapper {
return results[0].userid;
}

public async getOrCreateVirtualRoomForRoom(roomId: string): Promise<string> {
private async getVirtualUserForRoom(roomId: string): Promise<string | null> {
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<string | null> {
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, {
native_room: roomId,
Expand All @@ -59,6 +66,17 @@ 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<Room | null> {
const virtualUser = await this.getVirtualUserForRoom(roomId);
if (!virtualUser) return null;

return findDMForUser(MatrixClientPeg.get(), virtualUser);
}

public nativeRoomForVirtualRoom(roomId: string): string {
const cachedNativeRoomId = this.virtualToNativeRoomIdCache.get(roomId);
if (cachedNativeRoomId) {
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down