Add analytics for the ViewRoom action (#7666)

This commit is contained in:
Michael Telatynski 2022-02-10 14:29:55 +00:00 committed by GitHub
parent 20e9d0c159
commit 0d6ef76605
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 332 additions and 159 deletions

View file

@ -77,6 +77,7 @@ import { CardContext } from '../right_panel/BaseCard';
import { copyPlaintext } from '../../../utils/strings';
import { DecryptionFailureTracker } from '../../../DecryptionFailureTracker';
import RedactedBody from '../messages/RedactedBody';
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
const eventTileTypes = {
[EventType.RoomMessage]: 'messages.MessageEvent',
@ -714,11 +715,12 @@ export default class EventTile extends React.Component<IProps, IState> {
private viewInRoom = (evt: ButtonEvent): void => {
evt.preventDefault();
evt.stopPropagation();
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
event_id: this.props.mxEvent.getId(),
highlighted: true,
room_id: this.props.mxEvent.getRoomId(),
_trigger: undefined, // room doesn't change
});
};
@ -1016,11 +1018,12 @@ export default class EventTile extends React.Component<IProps, IState> {
// This allows the permalink to be opened in a new tab/window or copied as
// matrix.to, but also for it to enable routing within Element when clicked.
e.preventDefault();
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
event_id: this.props.mxEvent.getId(),
highlighted: true,
room_id: this.props.mxEvent.getRoomId(),
_trigger: this.props.timelineRenderingType === TimelineRenderingType.Search ? "MessageSearch" : undefined,
});
};

View file

@ -23,6 +23,7 @@ import {
} from "../../../accessibility/RovingTabIndex";
import NotificationBadge from "./NotificationBadge";
import { NotificationState } from "../../../stores/notifications/NotificationState";
import { ButtonEvent } from "../elements/AccessibleButton";
interface IProps {
isMinimized: boolean;
@ -30,7 +31,7 @@ interface IProps {
displayName: string;
avatar: React.ReactElement;
notificationState?: NotificationState;
onClick: () => void;
onClick: (ev: ButtonEvent) => void;
}
interface IState {

View file

@ -49,6 +49,7 @@ import RoomContext from '../../../contexts/RoomContext';
import { SettingUpdatedPayload } from "../../../dispatcher/payloads/SettingUpdatedPayload";
import MessageComposerButtons from './MessageComposerButtons';
import { ButtonEvent } from '../elements/AccessibleButton';
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
let instanceCount = 0;
const NARROW_MODE_BREAKPOINT = 500;
@ -227,21 +228,17 @@ export default class MessageComposer extends React.Component<IProps, IState> {
}
const viaServers = [this.state.tombstone.getSender().split(':').slice(1).join(':')];
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
highlighted: true,
event_id: createEventId,
room_id: replacementRoomId,
auto_join: true,
_type: "tombstone", // instrumentation
// Try to join via the server that sent the event. This converts @something:example.org
// into a server domain by splitting on colons and ignoring the first entry ("@something").
via_servers: viaServers,
opts: {
// These are passed down to the js-sdk's /join call
viaServers: viaServers,
},
_trigger: "Tombstone",
_viaKeyboard: ev.type !== "click",
});
};

View file

@ -31,6 +31,7 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { getUserNameColorClass } from "../../../utils/FormattingUtils";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { TileShape } from "./EventTile";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
interface IProps {
room: Room;
@ -45,11 +46,12 @@ export default class PinnedEventTile extends React.Component<IProps> {
public static contextType = MatrixClientContext;
private onTileClicked = () => {
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
event_id: this.props.event.getId(),
highlighted: true,
room_id: this.props.event.getRoomId(),
_trigger: undefined, // room doesn't change
});
};

View file

@ -26,6 +26,7 @@ import InteractiveTooltip, { Direction } from "../elements/InteractiveTooltip";
import { roomContextDetailsText } from "../../../Rooms";
import { Action } from "../../../dispatcher/actions";
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
const RecentlyViewedButton = () => {
const tooltipRef = useRef<InteractiveTooltip>();
@ -39,10 +40,12 @@ const RecentlyViewedButton = () => {
return <MenuItem
key={crumb.roomId}
onClick={() => {
dis.dispatch({
onClick={(ev) => {
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: crumb.roomId,
_trigger: "WebVerticalBreadcrumbs",
_viaKeyboard: ev.type !== "click",
});
tooltipRef.current?.hideTooltip();
}}

View file

@ -32,6 +32,7 @@ import { replaceableComponent } from '../../../utils/replaceableComponent';
import { getEventDisplayInfo, isVoiceMessage } from '../../../utils/EventUtils';
import MFileBody from "../messages/MFileBody";
import MVoiceMessageBody from "../messages/MVoiceMessageBody";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
interface IProps {
mxEvent: MatrixEvent;
@ -94,11 +95,12 @@ export default class ReplyTile extends React.PureComponent<IProps> {
if (this.props.toggleExpandedQuote && e.shiftKey) {
this.props.toggleExpandedQuote();
} else {
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
event_id: this.props.mxEvent.getId(),
highlighted: true,
room_id: this.props.mxEvent.getRoomId(),
_trigger: undefined, // room doesn't change
});
}
}

View file

@ -29,6 +29,8 @@ import Toolbar from "../../../accessibility/Toolbar";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { Action } from "../../../dispatcher/actions";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { ButtonEvent } from "../elements/AccessibleButton";
interface IProps {
}
@ -44,7 +46,7 @@ interface IState {
skipFirst: boolean;
}
const RoomBreadcrumbTile = ({ room, onClick }: { room: Room, onClick: () => void }) => {
const RoomBreadcrumbTile = ({ room, onClick }: { room: Room, onClick: (ev: ButtonEvent) => void }) => {
const [onFocus, isActive, ref] = useRovingTabIndex();
return (
@ -103,18 +105,24 @@ export default class RoomBreadcrumbs extends React.PureComponent<IProps, IState>
setTimeout(() => this.setState({ doAnimation: true, skipFirst: false }), 0);
};
private viewRoom = (room: Room, index: number) => {
private viewRoom = (room: Room, index: number, viaKeyboard = false) => {
Analytics.trackEvent("Breadcrumbs", "click_node", String(index));
defaultDispatcher.dispatch({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: room.roomId,
_trigger: "WebHorizontalBreadcrumbs",
_viaKeyboard: viaKeyboard,
});
};
public render(): React.ReactElement {
const tiles = BreadcrumbsStore.instance.rooms.map((r, i) => {
return <RoomBreadcrumbTile key={r.roomId} room={r} onClick={() => this.viewRoom(r, i)} />;
});
const tiles = BreadcrumbsStore.instance.rooms.map((r, i) => (
<RoomBreadcrumbTile
key={r.roomId}
room={r}
onClick={(ev: ButtonEvent) => this.viewRoom(r, i, ev.type !== "click")}
/>
));
if (tiles.length > 0) {
// NOTE: The CSSTransition timeout MUST match the timeout in our CSS!

View file

@ -23,6 +23,7 @@ import { Action } from '../../../dispatcher/actions';
import { _t } from '../../../languageHandler';
import { replaceableComponent } from "../../../utils/replaceableComponent";
import RoomDetailRow from "./RoomDetailRow";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
interface IProps {
rooms?: Room[];
@ -39,10 +40,11 @@ export default class RoomDetailList extends React.Component<IProps> {
}
private onDetailsClick = (ev: React.MouseEvent, room: Room): void => {
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: room.roomId,
room_alias: room.getCanonicalAlias() || (room.getAltAliases() || [])[0],
_trigger: undefined, // Deprecated groups
});
};

View file

@ -65,6 +65,7 @@ import { ChevronFace, ContextMenuTooltipButton, useContextMenu } from "../../str
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import SettingsStore from "../../../settings/SettingsStore";
import PosthogTrackers from "../../../PosthogTrackers";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
interface IProps {
onKeyDown: (ev: React.KeyboardEvent, state: IRovingTabIndexState) => void;
@ -217,9 +218,10 @@ const UntaggedAuxButton = ({ tabIndex }: IAuxButtonProps) => {
e.preventDefault();
e.stopPropagation();
closeMenu();
defaultDispatcher.dispatch({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: activeSpace.roomId,
_trigger: undefined, // other
});
}}
/>
@ -417,10 +419,12 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
const currentRoomId = RoomViewStore.getRoomId();
const room = this.getRoomDelta(currentRoomId, viewRoomDeltaPayload.delta, viewRoomDeltaPayload.unread);
if (room) {
defaultDispatcher.dispatch({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: room.roomId,
show_room_tile: true, // to make sure the room gets scrolled into view
_trigger: "WebKeyboardShortcut",
_viaKeyboard: true,
});
}
} else if (payload.action === Action.PstnSupportUpdated) {
@ -501,9 +505,10 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
private onExplore = () => {
if (!isMetaSpace(this.props.activeSpace)) {
defaultDispatcher.dispatch({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: this.props.activeSpace,
_trigger: undefined, // other
});
} else {
const initialText = RoomListStore.instance.getFirstNameFilterCondition()?.search;
@ -525,16 +530,18 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
resizeMethod="crop"
/>
);
const viewRoom = () => {
defaultDispatcher.dispatch({
const viewRoom = (ev) => {
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_alias: room.canonical_alias || room.aliases?.[0],
room_id: room.room_id,
via_servers: room.viaServers,
oobData: {
oob_data: {
avatarUrl: room.avatar_url,
name,
},
_trigger: "RoomList",
_viaKeyboard: ev.type !== "click",
});
};
return (

View file

@ -60,6 +60,7 @@ import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
import TooltipTarget from "../elements/TooltipTarget";
import { BetaPill } from "../beta/BetaCard";
import PosthogTrackers from "../../../PosthogTrackers";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
const contextMenuBelow = (elementRect: DOMRect) => {
// align the context menu's icons with the icon which opened the context menu
@ -104,9 +105,10 @@ const PrototypeCommunityContextMenu = (props: ComponentProps<typeof SpaceContext
// anyways.
const chat = CommunityPrototypeStore.instance.getSelectedCommunityGeneralChat();
if (chat) {
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: chat.roomId,
_trigger: undefined, // Deprecated groups
}, true);
RightPanelStore.instance.setCard({ phase: RightPanelPhases.RoomMemberList }, undefined, chat.roomId);
} else {
@ -274,9 +276,10 @@ const RoomListHeader = ({ spacePanelDisabled, onVisibilityChange }: IProps) => {
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
defaultDispatcher.dispatch({
defaultDispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: activeSpace.roomId,
_trigger: undefined, // other
});
closePlusMenu();
}}

View file

@ -57,6 +57,7 @@ import { ListNotificationState } from "../../../stores/notifications/ListNotific
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
const SHOW_N_BUTTON_HEIGHT = 28; // As defined by CSS
const RESIZE_HANDLE_HEIGHT = 4; // As defined by CSS
@ -428,10 +429,12 @@ export default class RoomSublist extends React.Component<IProps, IState> {
}
if (room) {
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: room.roomId,
show_room_tile: true, // to make sure the room gets scrolled into view
_trigger: "WebRoomListNotificationBadge",
_viaKeyboard: ev.type !== "click",
});
}
};

View file

@ -53,6 +53,7 @@ import IconizedContextMenu, {
import { CommunityPrototypeStore, IRoomProfile } from "../../../stores/CommunityPrototypeStore";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import PosthogTrackers from "../../../PosthogTrackers";
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
interface IProps {
room: Room;
@ -239,11 +240,13 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
private onTileClick = (ev: React.KeyboardEvent) => {
ev.preventDefault();
ev.stopPropagation();
dis.dispatch({
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
show_room_tile: true, // make sure the room is visible in the list
room_id: this.props.room.roomId,
clear_search: (ev && (ev.key === Key.ENTER || ev.key === Key.SPACE)),
_trigger: "RoomList",
_viaKeyboard: ev.type !== "click",
});
};