diff --git a/src/BasePlatform.ts b/src/BasePlatform.ts index d9062f8ce4..4e02325bed 100644 --- a/src/BasePlatform.ts +++ b/src/BasePlatform.ts @@ -31,6 +31,7 @@ import { Action } from "./dispatcher/actions"; import { hideToast as hideUpdateToast } from "./toasts/UpdateToast"; import { MatrixClientPeg } from "./MatrixClientPeg"; import { idbLoad, idbSave, idbDelete } from "./utils/StorageManager"; +import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload"; export const SSO_HOMESERVER_URL_KEY = "mx_sso_hs_url"; export const SSO_ID_SERVER_URL_KEY = "mx_sso_is_url"; @@ -185,9 +186,10 @@ export default abstract class BasePlatform { const notification = new window.Notification(title, notifBody); notification.onclick = () => { - const payload: ActionPayload = { + const payload: ViewRoomPayload = { action: Action.ViewRoom, room_id: room.roomId, + _trigger: "Notification", }; if (ev.getThread()) { diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx index d7f3ea8fcf..699a97d12c 100644 --- a/src/CallHandler.tsx +++ b/src/CallHandler.tsx @@ -56,6 +56,7 @@ import { getIncomingCallToastKey } from './toasts/IncomingCallToast'; import ToastStore from './stores/ToastStore'; import IncomingCallToast from "./toasts/IncomingCallToast"; import Resend from './Resend'; +import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload"; export const PROTOCOL_PSTN = 'm.protocol.pstn'; export const PROTOCOL_PSTN_PREFIXED = 'im.vector.protocol.pstn'; @@ -890,9 +891,10 @@ export default class CallHandler extends EventEmitter { call.answer(); this.setActiveCallRoomId(roomId); CountlyAnalytics.instance.trackJoinCall(roomId, call.type === CallType.Video, false); - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: roomId, + _trigger: "WebAcceptCall", }); } @@ -927,9 +929,10 @@ export default class CallHandler extends EventEmitter { const roomId = await ensureDMExists(MatrixClientPeg.get(), nativeUserId); - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: roomId, + _trigger: "WebDialPad", }); await this.placeMatrixCall(roomId, CallType.Voice, null); @@ -957,11 +960,12 @@ export default class CallHandler extends EventEmitter { const dmRoomId = await ensureDMExists(MatrixClientPeg.get(), destination); this.placeCall(dmRoomId, call.type, call); - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: dmRoomId, should_peek: false, joining: false, + _trigger: undefined, // other }); } else { try { diff --git a/src/CountlyAnalytics.ts b/src/CountlyAnalytics.ts index bb4db04cc2..11196c1f3a 100644 --- a/src/CountlyAnalytics.ts +++ b/src/CountlyAnalytics.ts @@ -262,7 +262,7 @@ interface ICreateRoomEvent extends IEvent { }; } -interface IJoinRoomEvent extends IEvent { +export interface IJoinRoomEvent extends IEvent { key: Action.JoinRoom; dur: number; // how long it took to join (until remote echo) segmentation: { @@ -270,7 +270,7 @@ interface IJoinRoomEvent extends IEvent { num_users: number; is_encrypted: boolean; is_public: boolean; - type: "room_directory" | "slash_command" | "link" | "invite"; + type: "room_directory" | "slash_command" | "link" | "invite" | "tombstone"; }; } /* eslint-enable camelcase */ diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx index a8658538f5..81521c6a1d 100644 --- a/src/SlashCommands.tsx +++ b/src/SlashCommands.tsx @@ -64,6 +64,7 @@ import { TimelineRenderingType } from './contexts/RoomContext'; import RoomViewStore from "./stores/RoomViewStore"; import { XOR } from "./@types/common"; import { PosthogAnalytics } from "./PosthogAnalytics"; +import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload"; // XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816 interface HTMLInputEvent extends Event { @@ -344,11 +345,13 @@ export const Commands = [ logger.log( `/timestamp_to_event: found ${eventId} (${originServerTs}) for timestamp=${unixTimestamp}`, ); - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, event_id: eventId, highlighted: true, room_id: roomId, + _trigger: "SlashCommand", + _viaKeyboard: true, }); })()); } @@ -608,26 +611,24 @@ export const Commands = [ roomAlias += ':' + MatrixClientPeg.get().getDomain(); } - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_alias: roomAlias, auto_join: true, - _type: "slash_command", // instrumentation + _trigger: "SlashCommand", + _viaKeyboard: true, }); return success(); } else if (params[0][0] === '!') { const [roomId, ...viaServers] = params; - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: roomId, - opts: { - // These are passed down to the js-sdk's /join call - viaServers: viaServers, - }, via_servers: viaServers, // for the rejoin button auto_join: true, - _type: "slash_command", // instrumentation + _trigger: "SlashCommand", + _viaKeyboard: true, }); return success(); } else if (isPermalink) { @@ -649,10 +650,11 @@ export const Commands = [ const viaServers = permalinkParts.viaServers; const eventId = permalinkParts.eventId; - const dispatch = { + const dispatch: ViewRoomPayload = { action: Action.ViewRoom, auto_join: true, - _type: "slash_command", // instrumentation + _trigger: "SlashCommand", + _viaKeyboard: true, }; if (entity[0] === '!') dispatch["room_id"] = entity; @@ -1150,9 +1152,11 @@ export const Commands = [ const roomId = await ensureDMExists(MatrixClientPeg.get(), userId); - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: roomId, + _trigger: "SlashCommand", + _viaKeyboard: true, }); })()); }, @@ -1172,9 +1176,11 @@ export const Commands = [ return success((async () => { const cli = MatrixClientPeg.get(); const roomId = await ensureDMExists(cli, userId); - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: roomId, + _trigger: "SlashCommand", + _viaKeyboard: true, }); if (msg) { cli.sendTextMessage(roomId, msg); diff --git a/src/TextForEvent.tsx b/src/TextForEvent.tsx index 5de61dabc2..f5e8636639 100644 --- a/src/TextForEvent.tsx +++ b/src/TextForEvent.tsx @@ -45,6 +45,7 @@ import { ROOM_SECURITY_TAB } from "./components/views/dialogs/RoomSettingsDialog import AccessibleButton from './components/views/elements/AccessibleButton'; import RightPanelStore from './stores/right-panel/RightPanelStore'; import UserIdentifierCustomisations from './customisations/UserIdentifier'; +import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload"; export function getSenderName(event: MatrixEvent): string { return event.sender?.name ?? event.getSender() ?? _t("Someone"); @@ -522,11 +523,12 @@ function textForPowerEvent(event: MatrixEvent): () => string | null { } const onPinnedOrUnpinnedMessageClick = (messageId: string, roomId: string): void => { - defaultDispatcher.dispatch({ + defaultDispatcher.dispatch({ action: Action.ViewRoom, event_id: messageId, highlighted: true, room_id: roomId, + _trigger: undefined, // room doesn't change }); }; diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 58b937b87b..d27de7a37a 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -119,6 +119,7 @@ import { ActionPayload } from "../../dispatcher/payloads"; import { SummarizedNotificationState } from "../../stores/notifications/SummarizedNotificationState"; import GenericToast from '../views/toasts/GenericToast'; import Views from '../../Views'; +import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; // legacy export export { default as Views } from "../../Views"; @@ -140,25 +141,6 @@ interface IScreen { params?: QueryDict; } -/* eslint-disable camelcase */ -interface IRoomInfo { - room_id?: string; - room_alias?: string; - event_id?: string; - - auto_join?: boolean; - highlighted?: boolean; - oob_data?: object; - via_servers?: string[]; - threepid_invite?: IThreepidInvite; - - justCreatedOpts?: IOpts; - - // Whether or not to override default behaviour to end up at a timeline - forceTimeline?: boolean; -} -/* eslint-enable camelcase */ - interface IProps { // TODO type things better config: { piwik: { @@ -675,7 +657,7 @@ export default class MatrixChat extends React.PureComponent { // known to be in (eg. user clicks on a room in the recents panel), supply the ID // If the user is clicking on a room in the context of the alias being presented // to them, supply the room alias. If both are supplied, the room ID will be ignored. - const promise = this.viewRoom(payload as any); + const promise = this.viewRoom(payload as ViewRoomPayload); if (payload.deferred_action) { promise.then(() => { dis.dispatch(payload.deferred_action); @@ -894,21 +876,7 @@ export default class MatrixChat extends React.PureComponent { } // switch view to the given room - // - // @param {Object} roomInfo Object containing data about the room to be joined - // @param {string=} roomInfo.room_id ID of the room to join. One of room_id or room_alias must be given. - // @param {string=} roomInfo.room_alias Alias of the room to join. One of room_id or room_alias must be given. - // @param {boolean=} roomInfo.auto_join If true, automatically attempt to join the room if not already a member. - // @param {string=} roomInfo.event_id ID of the event in this room to show: this will cause a switch to the - // context of that particular event. - // @param {boolean=} roomInfo.highlighted If true, add event_id to the hash of the URL - // and alter the EventTile to appear highlighted. - // @param {Object=} roomInfo.threepid_invite Object containing data about the third party - // we received to join the room, if any. - // @param {Object=} roomInfo.oob_data Object of additional data about the room - // that has been passed out-of-band (eg. - // room name and avatar from an invite email) - private async viewRoom(roomInfo: IRoomInfo) { + private async viewRoom(roomInfo: ViewRoomPayload) { this.focusComposer = true; if (roomInfo.room_alias) { @@ -1120,9 +1088,10 @@ export default class MatrixChat extends React.PureComponent { const dmRooms = dmRoomMap.getDMRoomsForUserId(userId); if (dmRooms.length > 0) { - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: dmRooms[0], + _trigger: "MessageUser", }); } else { dis.dispatch({ @@ -1395,9 +1364,10 @@ export default class MatrixChat extends React.PureComponent { } private viewLastRoom() { - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: localStorage.getItem('mx_last_room_id'), + _trigger: undefined, // other }); } @@ -1823,7 +1793,7 @@ export default class MatrixChat extends React.PureComponent { else via = params.via; } - const payload = { + const payload: ViewRoomPayload = { action: Action.ViewRoom, event_id: eventId, via_servers: via, @@ -1842,6 +1812,7 @@ export default class MatrixChat extends React.PureComponent { }, room_alias: undefined, room_id: undefined, + _trigger: undefined, // unknown or external trigger }; if (roomString[0] === '#') { payload.room_alias = roomString; diff --git a/src/components/structures/RoomDirectory.tsx b/src/components/structures/RoomDirectory.tsx index e683f3d172..662e8c7c45 100644 --- a/src/components/structures/RoomDirectory.tsx +++ b/src/components/structures/RoomDirectory.tsx @@ -46,10 +46,10 @@ import BaseDialog from "../views/dialogs/BaseDialog"; import DirectorySearchBox from "../views/elements/DirectorySearchBox"; import ScrollPanel from "./ScrollPanel"; import Spinner from "../views/elements/Spinner"; -import { ActionPayload } from "../../dispatcher/payloads"; import { getDisplayAliasForAliasSet } from "../../Rooms"; import { Action } from "../../dispatcher/actions"; import PosthogTrackers from "../../PosthogTrackers"; +import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; const MAX_NAME_LENGTH = 80; const MAX_TOPIC_LENGTH = 800; @@ -494,11 +494,11 @@ export default class RoomDirectory extends React.Component { private showRoom(room: IPublicRoomsChunkRoom, roomAlias?: string, autoJoin = false, shouldPeek = false) { this.onFinished(); - const payload: ActionPayload = { + const payload: ViewRoomPayload = { action: Action.ViewRoom, auto_join: autoJoin, should_peek: shouldPeek, - _type: "room_directory", // instrumentation + _trigger: "RoomDirectory", }; if (room) { // Don't let the user view a room they won't be able to either @@ -524,9 +524,6 @@ export default class RoomDirectory extends React.Component { if (this.state.roomServer) { payload.via_servers = [this.state.roomServer]; - payload.opts = { - viaServers: [this.state.roomServer], - }; } } // It's not really possible to join Matrix rooms by ID because the HS has no way to know diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 3f7fb31a22..1c230eed7a 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -101,6 +101,7 @@ import AppsDrawer from '../views/rooms/AppsDrawer'; import { RightPanelPhases } from '../../stores/right-panel/RightPanelStorePhases'; import { ActionPayload } from "../../dispatcher/payloads"; import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts"; +import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; const DEBUG = false; let debuglog = function(msg: string) {}; @@ -767,12 +768,13 @@ export class RoomView extends React.Component { private onUserScroll = () => { if (this.state.initialEventId && this.state.isInitialEventHighlighted) { - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: this.state.room.roomId, event_id: this.state.initialEventId, highlighted: false, replyingToEvent: this.state.replyToEvent, + _trigger: undefined, // room doesn't change }); } }; @@ -871,10 +873,11 @@ export class RoomView extends React.Component { } setImmediate(() => { - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: roomId, deferred_action: payload, + _trigger: "MessageSearch", }); }); } @@ -1171,9 +1174,10 @@ export class RoomView extends React.Component { if (ev.getType() === EventType.RoomCanonicalAlias) { // re-view the room so MatrixChat can manage the alias in the URL properly - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: this.state.room.roomId, + _trigger: undefined, // room doesn't change }); return; // this event cannot affect permissions so bail } @@ -1643,9 +1647,10 @@ export class RoomView extends React.Component { // If we were viewing a highlighted event, firing view_room without // an event will take care of both clearing the URL fragment and // jumping to the bottom - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: this.state.room.roomId, + _trigger: undefined, // room doesn't change }); } else { // Otherwise we have to jump manually @@ -1778,9 +1783,10 @@ export class RoomView extends React.Component { onHiddenHighlightsClick = () => { const oldRoom = this.getOldRoom(); if (!oldRoom) return; - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: oldRoom.roomId, + _trigger: "Predecessor", }); }; diff --git a/src/components/structures/SpaceHierarchy.tsx b/src/components/structures/SpaceHierarchy.tsx index 92ab8d80c6..459f9fd0e3 100644 --- a/src/components/structures/SpaceHierarchy.tsx +++ b/src/components/structures/SpaceHierarchy.tsx @@ -62,6 +62,7 @@ import { useEventEmitterState } from "../../hooks/useEventEmitter"; import { IOOBData } from "../../stores/ThreepidInviteStore"; import { awaitRoomDownSync } from "../../utils/RoomUpgrade"; import RoomViewStore from "../../stores/RoomViewStore"; +import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; interface IProps { space: Room; @@ -326,10 +327,9 @@ export const showRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: st } const roomAlias = getDisplayAliasForRoom(room) || undefined; - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, should_peek: true, - _type: "room_directory", // instrumentation room_alias: roomAlias, room_id: room.room_id, via_servers: Array.from(hierarchy.viaMap.get(roomId) || []), @@ -339,6 +339,7 @@ export const showRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: st name: room.name || roomAlias || _t("Unnamed room"), roomType, } as IOOBData, + _trigger: "RoomDirectory", }); }; diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx index 75bd3cc4e4..a1df9930a4 100644 --- a/src/components/structures/SpaceRoomView.tsx +++ b/src/components/structures/SpaceRoomView.tsx @@ -85,6 +85,7 @@ import { shouldShowComponent } from "../../customisations/helpers/UIComponents"; import { UIComponent } from "../../settings/UIFeature"; import { UPDATE_EVENT } from "../../stores/AsyncStore"; import PosthogTrackers from "../../PosthogTrackers"; +import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; interface IProps { space: Room; @@ -865,9 +866,10 @@ export default class SpaceRoomView extends React.PureComponent { private goToFirstRoom = async () => { if (this.state.firstRoomId) { - defaultDispatcher.dispatch({ + defaultDispatcher.dispatch({ action: Action.ViewRoom, room_id: this.state.firstRoomId, + _trigger: undefined, // other }); return; } diff --git a/src/components/structures/ThreadView.tsx b/src/components/structures/ThreadView.tsx index ee95eff22c..b10e5a923d 100644 --- a/src/components/structures/ThreadView.tsx +++ b/src/components/structures/ThreadView.tsx @@ -46,6 +46,7 @@ import { _t } from '../../languageHandler'; import ThreadListContextMenu from '../views/context_menus/ThreadListContextMenu'; import RightPanelStore from '../../stores/right-panel/RightPanelStore'; import SettingsStore from "../../settings/SettingsStore"; +import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; interface IProps { room: Room; @@ -195,12 +196,13 @@ export default class ThreadView extends React.Component { private onScroll = (): void => { if (this.props.initialEvent && this.props.isInitialEventHighlighted) { - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: this.props.room.roomId, event_id: this.props.initialEvent?.getId(), highlighted: false, replyingToEvent: this.state.replyToEvent, + _trigger: undefined, // room doesn't change }); } }; diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index 632b56d03d..d5103424ab 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -52,6 +52,7 @@ import Spinner from "../views/elements/Spinner"; import EditorStateTransfer from '../../utils/EditorStateTransfer'; import ErrorDialog from '../views/dialogs/ErrorDialog'; import CallEventGrouper from "./CallEventGrouper"; +import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload"; const PAGINATE_SIZE = 20; const INITIAL_SIZE = 20; @@ -1191,9 +1192,10 @@ class TimelinePanel extends React.Component { if (eventId) { onFinished = () => { // go via the dispatcher so that the URL is updated - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: this.props.timelineSet.room.roomId, + _trigger: undefined, // room doesn't change }); }; } diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx index b86be93f2e..f4e00b1d61 100644 --- a/src/components/views/context_menus/MessageContextMenu.tsx +++ b/src/components/views/context_menus/MessageContextMenu.tsx @@ -47,6 +47,7 @@ import { WidgetLayoutStore } from '../../../stores/widgets/WidgetLayoutStore'; import EndPollDialog from '../dialogs/EndPollDialog'; import { isPollEnded } from '../messages/MPollBody'; import { createMapSiteLink } from "../messages/MLocationBody"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; export function canCancel(status: EventStatus): boolean { return status === EventStatus.QUEUED || status === EventStatus.NOT_SENT || status === EventStatus.ENCRYPTING; @@ -263,11 +264,12 @@ export default class MessageContextMenu extends React.Component } private viewInRoom = () => { - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, event_id: this.props.mxEvent.getId(), highlighted: true, room_id: this.props.mxEvent.getRoomId(), + _trigger: undefined, // room doesn't change }); this.closeMenu(); }; diff --git a/src/components/views/context_menus/RoomContextMenu.tsx b/src/components/views/context_menus/RoomContextMenu.tsx index ac8ca84cde..73dac3e791 100644 --- a/src/components/views/context_menus/RoomContextMenu.tsx +++ b/src/components/views/context_menus/RoomContextMenu.tsx @@ -44,6 +44,7 @@ import RightPanelStore from "../../../stores/right-panel/RightPanelStore"; import DMRoomMap from "../../../utils/DMRoomMap"; import { Action } from "../../../dispatcher/actions"; import PosthogTrackers from "../../../PosthogTrackers"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; interface IProps extends IContextMenuProps { room: Room; @@ -198,7 +199,7 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => { ev.preventDefault(); ev.stopPropagation(); - ensureViewingRoom(); + ensureViewingRoom(ev); RightPanelStore.instance.pushCard({ phase: RightPanelPhases.RoomMemberList }, false); onFinished(); PosthogTrackers.trackInteraction("WebRoomHeaderContextMenuPeopleItem", ev); @@ -247,11 +248,13 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => { } }; - const ensureViewingRoom = () => { + const ensureViewingRoom = (ev: ButtonEvent) => { if (RoomViewStore.getRoomId() === room.roomId) return; - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: room.roomId, + _trigger: "RoomList", + _viaKeyboard: ev.type !== "click", }, true); }; @@ -267,7 +270,7 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => { ev.preventDefault(); ev.stopPropagation(); - ensureViewingRoom(); + ensureViewingRoom(ev); RightPanelStore.instance.pushCard({ phase: RightPanelPhases.FilePanel }, false); onFinished(); }} @@ -280,7 +283,7 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => { ev.preventDefault(); ev.stopPropagation(); - ensureViewingRoom(); + ensureViewingRoom(ev); RightPanelStore.instance.setCard({ phase: RightPanelPhases.RoomSummary }, false); onFinished(); }} diff --git a/src/components/views/context_menus/SpaceContextMenu.tsx b/src/components/views/context_menus/SpaceContextMenu.tsx index 9f51dd610e..f5fb09ad25 100644 --- a/src/components/views/context_menus/SpaceContextMenu.tsx +++ b/src/components/views/context_menus/SpaceContextMenu.tsx @@ -39,6 +39,7 @@ import { Action } from "../../../dispatcher/actions"; import { shouldShowComponent } from "../../../customisations/helpers/UIComponents"; import { UIComponent } from "../../../settings/UIFeature"; import PosthogTrackers from "../../../PosthogTrackers"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; interface IProps extends IContextMenuProps { space: Room; @@ -115,10 +116,11 @@ const SpaceContextMenu = ({ space, hideHeader, onFinished, ...props }: IProps) = ev.preventDefault(); ev.stopPropagation(); - defaultDispatcher.dispatch({ + defaultDispatcher.dispatch({ action: Action.ViewRoom, room_id: space.roomId, forceTimeline: true, + _trigger: undefined, // room doesn't change }); onFinished(); }; @@ -192,9 +194,10 @@ const SpaceContextMenu = ({ space, hideHeader, onFinished, ...props }: IProps) = ev.preventDefault(); ev.stopPropagation(); - defaultDispatcher.dispatch({ + defaultDispatcher.dispatch({ action: Action.ViewRoom, room_id: space.roomId, + _trigger: undefined, // other }); onFinished(); }; diff --git a/src/components/views/context_menus/ThreadListContextMenu.tsx b/src/components/views/context_menus/ThreadListContextMenu.tsx index 012b2dbae4..0340109811 100644 --- a/src/components/views/context_menus/ThreadListContextMenu.tsx +++ b/src/components/views/context_menus/ThreadListContextMenu.tsx @@ -28,6 +28,7 @@ import IconizedContextMenu, { IconizedContextMenuOption, IconizedContextMenuOpti import { WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore"; import { MatrixClientPeg } from "../../../MatrixClientPeg"; import { useRovingTabIndex } from "../../../accessibility/RovingTabIndex"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; interface IProps { mxEvent: MatrixEvent; @@ -75,11 +76,12 @@ const ThreadListContextMenu: React.FC = ({ const viewInRoom = useCallback((evt: ButtonEvent): void => { evt.preventDefault(); evt.stopPropagation(); - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, event_id: mxEvent.getId(), highlighted: true, room_id: mxEvent.getRoomId(), + _trigger: undefined, // room doesn't change }); closeThreadOptions(); }, [mxEvent, closeThreadOptions]); diff --git a/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx b/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx index 45b72aac5b..5f68968613 100644 --- a/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx +++ b/src/components/views/dialogs/CreateCommunityPrototypeDialog.tsx @@ -29,6 +29,7 @@ import { Action } from '../../../dispatcher/actions'; import { showCommunityRoomInviteDialog } from "../../../RoomInvite"; import GroupStore from "../../../stores/GroupStore"; import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; interface IProps extends IDialogProps { } @@ -100,9 +101,10 @@ export default class CreateCommunityPrototypeDialog extends React.PureComponent< if (result.room_id) { // Force the group store to update as it might have missed the general chat await GroupStore.refreshGroupRooms(result.group_id); - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: result.room_id, + _trigger: undefined, // Deprecated groups }); showCommunityRoomInviteDialog(result.room_id, this.state.name); } else { diff --git a/src/components/views/dialogs/CreateSpaceFromCommunityDialog.tsx b/src/components/views/dialogs/CreateSpaceFromCommunityDialog.tsx index 1c91a624a5..8c3d9a25f7 100644 --- a/src/components/views/dialogs/CreateSpaceFromCommunityDialog.tsx +++ b/src/components/views/dialogs/CreateSpaceFromCommunityDialog.tsx @@ -42,6 +42,7 @@ import { UserTab } from "./UserSettingsDialog"; import TagOrderActions from "../../../actions/TagOrderActions"; import { inviteUsersToRoom } from "../../../RoomInvite"; import ProgressBar from "../elements/ProgressBar"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; interface IProps { matrixClient: MatrixClient; @@ -226,9 +227,10 @@ const CreateSpaceFromCommunityDialog: React.FC = ({ matrixClient: cli, g onFinished(roomId); const onSpaceClick = () => { - dis.dispatch({ + dis.dispatch({ action: Action.ViewRoom, room_id: roomId, + _trigger: undefined, // other }); }; diff --git a/src/components/views/dialogs/ForwardDialog.tsx b/src/components/views/dialogs/ForwardDialog.tsx index b19a878edf..b1983a7e72 100644 --- a/src/components/views/dialogs/ForwardDialog.tsx +++ b/src/components/views/dialogs/ForwardDialog.tsx @@ -46,6 +46,8 @@ import BaseAvatar from "../avatars/BaseAvatar"; import SpaceStore from "../../../stores/spaces/SpaceStore"; import { roomContextDetailsText } from "../../../Rooms"; import { Action } from "../../../dispatcher/actions"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; +import { ButtonEvent } from "../elements/AccessibleButton"; const AVATAR_SIZE = 30; @@ -75,10 +77,12 @@ enum SendState { const Entry: React.FC = ({ room, event, matrixClient: cli, onFinished }) => { const [sendState, setSendState] = useState(SendState.CanSend); - const jumpToRoom = () => { - dis.dispatch({ + const jumpToRoom = (ev: ButtonEvent) => { + dis.dispatch({ action: Action.ViewRoom, room_id: room.roomId, + _trigger: "WebForwardShortcut", + _viaKeyboard: ev.type !== "click", }); onFinished(true); }; diff --git a/src/components/views/dialogs/InviteDialog.tsx b/src/components/views/dialogs/InviteDialog.tsx index 37301c26b9..bf4e1e1b2a 100644 --- a/src/components/views/dialogs/InviteDialog.tsx +++ b/src/components/views/dialogs/InviteDialog.tsx @@ -71,6 +71,7 @@ import CallHandler from "../../../CallHandler"; import UserIdentifierCustomisations from '../../../customisations/UserIdentifier'; import CopyableText from "../elements/CopyableText"; import { ScreenName } from '../../../PosthogTrackers'; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; // we have a number of types defined from the Matrix spec which can't reasonably be altered here. /* eslint-disable camelcase */ @@ -679,11 +680,12 @@ export default class InviteDialog extends React.PureComponent({ action: Action.ViewRoom, room_id: existingRoom.roomId, should_peek: false, joining: false, + _trigger: "MessageUser", }); this.props.onFinished(true); return; diff --git a/src/components/views/dialogs/SpotlightDialog.tsx b/src/components/views/dialogs/SpotlightDialog.tsx index f18d8206d0..2d60d4fbf3 100644 --- a/src/components/views/dialogs/SpotlightDialog.tsx +++ b/src/components/views/dialogs/SpotlightDialog.tsx @@ -68,6 +68,7 @@ import { BetaPill } from "../beta/BetaCard"; import { UserTab } from "./UserSettingsDialog"; import BetaFeedbackDialog from "./BetaFeedbackDialog"; import SdkConfig from "../../../SdkConfig"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; const MAX_RECENT_SEARCHES = 10; const SECTION_LIMIT = 50; // only show 50 results per section for performance reasons @@ -214,7 +215,7 @@ const SpotlightDialog: React.FC = ({ initialText = "", onFinished }) => }); }; - const viewRoom = (roomId: string, persist = false) => { + const viewRoom = (roomId: string, persist = false, viaKeyboard = false) => { if (persist) { const recents = new Set(SettingsStore.getValue("SpotlightSearch.recentSearches", null).reverse()); // remove & add the room to put it at the end @@ -229,9 +230,11 @@ const SpotlightDialog: React.FC = ({ initialText = "", onFinished }) => ); } - defaultDispatcher.dispatch({ + defaultDispatcher.dispatch({ action: Action.ViewRoom, room_id: roomId, + _trigger: "WebUnifiedSearch", + _viaKeyboard: viaKeyboard, }); onFinished(); }; @@ -249,8 +252,8 @@ const SpotlightDialog: React.FC = ({ initialText = "", onFinished }) =>