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

Commit

Permalink
Basic threads analytics into Posthog MVP (#7871)
Browse files Browse the repository at this point in the history
  • Loading branch information
t3chguy committed Feb 28, 2022
1 parent 182aedc commit 75e41b4
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 18 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"linkifyjs": "^4.0.0-beta.4",
"lodash": "^4.17.20",
"maplibre-gl": "^1.15.2",
"matrix-analytics-events": "github:matrix-org/matrix-analytics-events.git#8e75aaf0b3e045587daeaf97a7691dbfda2f20c0",
"matrix-analytics-events": "github:matrix-org/matrix-analytics-events.git#daad3faed54f0b1f1e026a7498b4653e4d01cd90",
"matrix-events-sdk": "^0.0.1-beta.7",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
"matrix-widget-api": "^0.1.0-beta.18",
Expand Down
4 changes: 2 additions & 2 deletions src/PosthogAnalytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,13 @@ export class PosthogAnalytics {
// we persist the last `$screen_name` and send it for all events until it is replaced
private lastScreen: ScreenName = "Loading";

private sanitizeProperties = (properties: posthog.Properties): posthog.Properties => {
private sanitizeProperties = (properties: posthog.Properties, eventName: string): posthog.Properties => {
// Callback from posthog to sanitize properties before sending them to the server.
//
// Here we sanitize posthog's built in properties which leak PII e.g. url reporting.
// See utils.js _.info.properties in posthog-js.

if (properties["eventName"] === "$pageview") {
if (eventName === "$pageview") {
this.lastScreen = properties["$current_url"];
}
// We inject a screen identifier in $current_url as per https://posthog.com/tutorials/spa
Expand Down
12 changes: 11 additions & 1 deletion src/components/structures/ThreadPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import TimelinePanel from './TimelinePanel';
import { Layout } from '../../settings/enums/Layout';
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
import Measured from '../views/elements/Measured';
import PosthogTrackers from "../../PosthogTrackers";
import { ButtonEvent } from "../views/elements/AccessibleButton";

export async function getThreadTimelineSet(
client: MatrixClient,
Expand Down Expand Up @@ -178,7 +180,15 @@ export const ThreadPanelHeader = ({ filterOption, setFilterOption, empty }: {
return <div className="mx_ThreadPanel__header">
<span>{ _t("Threads") }</span>
{ !empty && <>
<ContextMenuButton className="mx_ThreadPanel_dropdown" inputRef={button} isExpanded={menuDisplayed} onClick={() => menuDisplayed ? closeMenu() : openMenu()}>
<ContextMenuButton
className="mx_ThreadPanel_dropdown"
inputRef={button}
isExpanded={menuDisplayed}
onClick={(ev: ButtonEvent) => {
openMenu();
PosthogTrackers.trackInteraction("WebRightPanelThreadPanelFilterDropdown", ev);
}}
>
{ `${_t('Show:')} ${value.label}` }
</ContextMenuButton>
{ contextMenu }
Expand Down
5 changes: 5 additions & 0 deletions src/components/structures/ThreadView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import FileDropTarget from "./FileDropTarget";
import { getKeyBindingsManager } from "../../KeyBindingsManager";
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
import Measured from '../views/elements/Measured';
import PosthogTrackers from "../../PosthogTrackers";
import { ButtonEvent } from "../views/elements/AccessibleButton";

interface IProps {
room: Room;
Expand Down Expand Up @@ -321,6 +323,9 @@ export default class ThreadView extends React.Component<IProps, IState> {
header={this.renderThreadViewHeader()}
ref={this.card}
onKeyDown={this.onKeyDown}
onBack={(ev: ButtonEvent) => {
PosthogTrackers.trackInteraction("WebThreadViewBackButton", ev);
}}
>
<Measured
sensor={this.card.current}
Expand Down
7 changes: 4 additions & 3 deletions src/components/views/right_panel/HeaderButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ import classNames from 'classnames';
import Analytics from '../../../Analytics';
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { ButtonEvent } from "../elements/AccessibleButton";

interface IProps {
// Whether this button is highlighted
isHighlighted: boolean;
// click handler
onClick: () => void;
onClick: (ev: ButtonEvent) => void;
// The parameters to track the click event
analytics: Parameters<typeof Analytics.trackEvent>;

Expand All @@ -42,9 +43,9 @@ interface IProps {
// TODO: replace this, the composer buttons and the right panel buttons with a unified representation
@replaceableComponent("views.right_panel.HeaderButton")
export default class HeaderButton extends React.Component<IProps> {
private onClick = () => {
private onClick = (ev: ButtonEvent) => {
Analytics.trackEvent(...this.props.analytics);
this.props.onClick();
this.props.onClick(ev);
};

public render() {
Expand Down
5 changes: 4 additions & 1 deletion src/components/views/right_panel/RoomHeaderButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNo
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
import { ThreadsRoomNotificationState } from "../../../stores/notifications/ThreadsRoomNotificationState";
import { NotificationStateEvents } from "../../../stores/notifications/NotificationState";
import PosthogTrackers from "../../../PosthogTrackers";
import { ButtonEvent } from "../elements/AccessibleButton";

const ROOM_INFO_PHASES = [
RightPanelPhases.RoomSummary,
Expand Down Expand Up @@ -207,11 +209,12 @@ export default class RoomHeaderButtons extends HeaderButtons<IProps> {
this.setPhase(RightPanelPhases.Timeline);
};

private onThreadsPanelClicked = () => {
private onThreadsPanelClicked = (ev: ButtonEvent) => {
if (RoomHeaderButtons.THREAD_PHASES.includes(this.state.phase)) {
RightPanelStore.instance.togglePanel();
} else {
showThreadPanel();
PosthogTrackers.trackInteraction("WebRoomHeaderButtonsThreadsButton", ev);
}
};

Expand Down
18 changes: 13 additions & 5 deletions src/components/views/rooms/EventTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { createRef } from 'react';
import React, { createRef, MouseEvent } from 'react';
import classNames from "classnames";
import { EventType, MsgType, RelationType } from "matrix-js-sdk/src/@types/event";
import { EventStatus, MatrixEvent, MatrixEventEvent } from "matrix-js-sdk/src/models/event";
Expand Down Expand Up @@ -81,6 +81,7 @@ import { DecryptionFailureTracker } from '../../../DecryptionFailureTracker';
import RedactedBody from '../messages/RedactedBody';
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { shouldDisplayReply } from '../../../utils/Reply';
import PosthogTrackers from "../../../PosthogTrackers";

export type GetRelationsForEvent = (eventId: string, relationType: string, eventType: string) => Relations;

Expand Down Expand Up @@ -684,17 +685,19 @@ export default class EventTile extends React.Component<IProps, IState> {
return (
<CardContext.Consumer>
{ context =>
<div
<AccessibleButton
className="mx_ThreadInfo"
onClick={() => {
onClick={(ev: ButtonEvent) => {
showThread({ rootEvent: this.props.mxEvent, push: context.isCard });
PosthogTrackers.trackInteraction("WebRoomTimelineThreadSummaryButton", ev);
}}
aria-label={_t("Open thread")}
>
<span className="mx_ThreadInfo_threads-amount">
{ count }
</span>
{ this.renderThreadLastMessagePreview() }
</div>
</AccessibleButton>
}
</CardContext.Consumer>
);
Expand Down Expand Up @@ -1507,7 +1510,12 @@ export default class EventTile extends React.Component<IProps, IState> {
"data-notification": this.state.threadNotification,
"onMouseEnter": () => this.setState({ hover: true }),
"onMouseLeave": () => this.setState({ hover: false }),
"onClick": () => showThread({ rootEvent: this.props.mxEvent, push: true }),
"onClick": (ev: MouseEvent) => {
showThread({ rootEvent: this.props.mxEvent, push: true });
const target = ev.currentTarget as HTMLElement;
const index = Array.from(target.parentElement.children).indexOf(target);
PosthogTrackers.trackInteraction("WebThreadsPanelThreadItem", ev, index);
},
}, <>
{ sender }
{ avatar }
Expand Down
11 changes: 8 additions & 3 deletions src/components/views/rooms/SendMessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -345,12 +345,17 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
return;
}

PosthogAnalytics.instance.trackEvent<ComposerEvent>({
const posthogEvent: ComposerEvent = {
eventName: "Composer",
isEditing: false,
inThread: this.props.relation?.rel_type === RelationType.Thread,
isReply: !!this.props.replyToEvent,
});
inThread: this.props.relation?.rel_type === RelationType.Thread,
};
if (posthogEvent.inThread) {
const threadRoot = this.props.room.findEventById(this.props.relation.event_id);
posthogEvent.startsThread = threadRoot?.getThread()?.events.length === 1;
}
PosthogAnalytics.instance.trackEvent<ComposerEvent>(posthogEvent);

// Replace emoticon at the end of the message
if (SettingsStore.getValue('MessageComposerInput.autoReplaceEmoji')) {
Expand Down
1 change: 1 addition & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1659,6 +1659,7 @@
"From a thread": "From a thread",
"%(count)s reply|other": "%(count)s replies",
"%(count)s reply|one": "%(count)s reply",
"Open thread": "Open thread",
"This event could not be displayed": "This event could not be displayed",
"Your key share request has been sent - please check your other sessions for key share requests.": "Your key share request has been sent - please check your other sessions for key share requests.",
"Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.",
Expand Down
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6261,9 +6261,9 @@ mathml-tag-names@^2.1.3:
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==

"matrix-analytics-events@github:matrix-org/matrix-analytics-events.git#8e75aaf0b3e045587daeaf97a7691dbfda2f20c0":
"matrix-analytics-events@github:matrix-org/matrix-analytics-events.git#daad3faed54f0b1f1e026a7498b4653e4d01cd90":
version "0.0.1"
resolved "https://codeload.github.com/matrix-org/matrix-analytics-events/tar.gz/8e75aaf0b3e045587daeaf97a7691dbfda2f20c0"
resolved "https://codeload.github.com/matrix-org/matrix-analytics-events/tar.gz/daad3faed54f0b1f1e026a7498b4653e4d01cd90"

matrix-events-sdk@^0.0.1-beta.6:
version "0.0.1-beta.6"
Expand Down

0 comments on commit 75e41b4

Please sign in to comment.