Track room list sorting algorithm changes (#32556)
* Update analytics package * Add method for tracking event * Track event on resort * Add test * Fix lint
This commit is contained in:
+1
-1
@@ -58,7 +58,7 @@
|
|||||||
"@fontsource/fira-code": "^5",
|
"@fontsource/fira-code": "^5",
|
||||||
"@fontsource/inter": "^5",
|
"@fontsource/inter": "^5",
|
||||||
"@formatjs/intl-segmenter": "^12.0.0",
|
"@formatjs/intl-segmenter": "^12.0.0",
|
||||||
"@matrix-org/analytics-events": "^0.31.0",
|
"@matrix-org/analytics-events": "^0.32.0",
|
||||||
"@matrix-org/emojibase-bindings": "^1.5.0",
|
"@matrix-org/emojibase-bindings": "^1.5.0",
|
||||||
"@matrix-org/react-sdk-module-api": "^2.4.0",
|
"@matrix-org/react-sdk-module-api": "^2.4.0",
|
||||||
"@sentry/browser": "^10.0.0",
|
"@sentry/browser": "^10.0.0",
|
||||||
|
|||||||
Generated
+5
-5
@@ -100,8 +100,8 @@ importers:
|
|||||||
specifier: ^12.0.0
|
specifier: ^12.0.0
|
||||||
version: 12.1.1
|
version: 12.1.1
|
||||||
'@matrix-org/analytics-events':
|
'@matrix-org/analytics-events':
|
||||||
specifier: ^0.31.0
|
specifier: ^0.32.0
|
||||||
version: 0.31.0
|
version: 0.32.0
|
||||||
'@matrix-org/emojibase-bindings':
|
'@matrix-org/emojibase-bindings':
|
||||||
specifier: ^1.5.0
|
specifier: ^1.5.0
|
||||||
version: 1.5.0
|
version: 1.5.0
|
||||||
@@ -2642,8 +2642,8 @@ packages:
|
|||||||
'@maplibre/vt-pbf@4.2.1':
|
'@maplibre/vt-pbf@4.2.1':
|
||||||
resolution: {integrity: sha512-IxZBGq/+9cqf2qdWlFuQ+ZfoMhWpxDUGQZ/poPHOJBvwMUT1GuxLo6HgYTou+xxtsOsjfbcjI8PZaPCtmt97rA==}
|
resolution: {integrity: sha512-IxZBGq/+9cqf2qdWlFuQ+ZfoMhWpxDUGQZ/poPHOJBvwMUT1GuxLo6HgYTou+xxtsOsjfbcjI8PZaPCtmt97rA==}
|
||||||
|
|
||||||
'@matrix-org/analytics-events@0.31.0':
|
'@matrix-org/analytics-events@0.32.0':
|
||||||
resolution: {integrity: sha512-rZrtHt6X1cnleWPPSp56fngYBiq2Db1jQt+bATEUlDwwiMCrG3D5ojYqOQ03MlgySLIZLBAAam//bZAqiGWOwQ==}
|
resolution: {integrity: sha512-Z5hl4wJdIvskFCOzHAh/7tQKlyvJ/5/JdvfTTySuJ/v47VmkCGvkdDD6ODT9+15psj3O8Cc2Ofgh2KqDJjd6kg==}
|
||||||
|
|
||||||
'@matrix-org/emojibase-bindings@1.5.0':
|
'@matrix-org/emojibase-bindings@1.5.0':
|
||||||
resolution: {integrity: sha512-+W9/ow2Z3iQa7ZOF698PBhwNcgGkn36B5Sr8VDPx8N8CH7+Uw+7TrtbtKPZVdgf4m/THmgmfX40jS5YDBsLaYg==}
|
resolution: {integrity: sha512-+W9/ow2Z3iQa7ZOF698PBhwNcgGkn36B5Sr8VDPx8N8CH7+Uw+7TrtbtKPZVdgf4m/THmgmfX40jS5YDBsLaYg==}
|
||||||
@@ -12612,7 +12612,7 @@ snapshots:
|
|||||||
pbf: 4.0.1
|
pbf: 4.0.1
|
||||||
supercluster: 8.0.1
|
supercluster: 8.0.1
|
||||||
|
|
||||||
'@matrix-org/analytics-events@0.31.0': {}
|
'@matrix-org/analytics-events@0.32.0': {}
|
||||||
|
|
||||||
'@matrix-org/emojibase-bindings@1.5.0':
|
'@matrix-org/emojibase-bindings@1.5.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -10,10 +10,12 @@ import { PureComponent, type SyntheticEvent } from "react";
|
|||||||
import { type WebScreen as ScreenEvent } from "@matrix-org/analytics-events/types/typescript/WebScreen";
|
import { type WebScreen as ScreenEvent } from "@matrix-org/analytics-events/types/typescript/WebScreen";
|
||||||
import { type Interaction as InteractionEvent } from "@matrix-org/analytics-events/types/typescript/Interaction";
|
import { type Interaction as InteractionEvent } from "@matrix-org/analytics-events/types/typescript/Interaction";
|
||||||
import { type PinUnpinAction } from "@matrix-org/analytics-events/types/typescript/PinUnpinAction";
|
import { type PinUnpinAction } from "@matrix-org/analytics-events/types/typescript/PinUnpinAction";
|
||||||
|
import { type RoomListSortingAlgorithmChanged } from "@matrix-org/analytics-events/types/typescript/RoomListSortingAlgorithmChanged";
|
||||||
|
|
||||||
import PageType from "./PageTypes";
|
import PageType from "./PageTypes";
|
||||||
import Views from "./Views";
|
import Views from "./Views";
|
||||||
import { PosthogAnalytics } from "./PosthogAnalytics";
|
import { PosthogAnalytics } from "./PosthogAnalytics";
|
||||||
|
import { SortingAlgorithm } from "./stores/room-list-v3/skip-list/sorters";
|
||||||
|
|
||||||
export type ScreenName = ScreenEvent["$current_url"];
|
export type ScreenName = ScreenEvent["$current_url"];
|
||||||
export type InteractionName = InteractionEvent["name"];
|
export type InteractionName = InteractionEvent["name"];
|
||||||
@@ -38,6 +40,12 @@ const loggedInPageTypeMap: Record<PageType | string, ScreenName> = {
|
|||||||
[PageType.UserView]: "User",
|
[PageType.UserView]: "User",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SortingAlgorithmMap: Record<SortingAlgorithm, RoomListSortingAlgorithmChanged["newAlgorithm"]> = {
|
||||||
|
[SortingAlgorithm.Recency]: "Activity",
|
||||||
|
[SortingAlgorithm.Unread]: "Unread",
|
||||||
|
[SortingAlgorithm.Alphabetic]: "Alphabetic",
|
||||||
|
};
|
||||||
|
|
||||||
export default class PosthogTrackers {
|
export default class PosthogTrackers {
|
||||||
private static internalInstance: PosthogTrackers;
|
private static internalInstance: PosthogTrackers;
|
||||||
|
|
||||||
@@ -112,6 +120,22 @@ export default class PosthogTrackers {
|
|||||||
from,
|
from,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track when the user chooses a different sorting algorithm for the room-list.
|
||||||
|
* @param oldAlgorithm - The old algorithm.
|
||||||
|
* @param newAlgorithm - The new algorithm.
|
||||||
|
*/
|
||||||
|
public static trackRoomListSortingAlgorithmChange(
|
||||||
|
oldAlgorithm: SortingAlgorithm,
|
||||||
|
newAlgorithm: SortingAlgorithm,
|
||||||
|
): void {
|
||||||
|
PosthogAnalytics.instance.trackEvent<RoomListSortingAlgorithmChanged>({
|
||||||
|
eventName: "RoomListSortingAlgorithmChanged",
|
||||||
|
oldAlgorithm: SortingAlgorithmMap[oldAlgorithm],
|
||||||
|
newAlgorithm: SortingAlgorithmMap[newAlgorithm],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PosthogScreenTracker extends PureComponent<{ screenName: ScreenName }> {
|
export class PosthogScreenTracker extends PureComponent<{ screenName: ScreenName }> {
|
||||||
|
|||||||
@@ -170,20 +170,26 @@ export class RoomListHeaderViewModel
|
|||||||
};
|
};
|
||||||
|
|
||||||
public sort = (option: SortOption): void => {
|
public sort = (option: SortOption): void => {
|
||||||
let sortingAlgorithm: SortingAlgorithm;
|
const oldSortingAlgorithm = RoomListStoreV3.instance.activeSortAlgorithm;
|
||||||
|
let newSortingAlgorithm: SortingAlgorithm;
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case "alphabetical":
|
case "alphabetical":
|
||||||
sortingAlgorithm = SortingAlgorithm.Alphabetic;
|
newSortingAlgorithm = SortingAlgorithm.Alphabetic;
|
||||||
break;
|
break;
|
||||||
case "recent":
|
case "recent":
|
||||||
sortingAlgorithm = SortingAlgorithm.Recency;
|
newSortingAlgorithm = SortingAlgorithm.Recency;
|
||||||
break;
|
break;
|
||||||
case "unread-first":
|
case "unread-first":
|
||||||
sortingAlgorithm = SortingAlgorithm.Unread;
|
newSortingAlgorithm = SortingAlgorithm.Unread;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
RoomListStoreV3.instance.resort(sortingAlgorithm);
|
RoomListStoreV3.instance.resort(newSortingAlgorithm);
|
||||||
this.snapshot.merge({ activeSortOption: option });
|
this.snapshot.merge({ activeSortOption: option });
|
||||||
|
|
||||||
|
// Record analytics for this action
|
||||||
|
if (oldSortingAlgorithm) {
|
||||||
|
PosthogTrackers.trackRoomListSortingAlgorithmChange(oldSortingAlgorithm, newSortingAlgorithm);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public toggleMessagePreview = (): void => {
|
public toggleMessagePreview = (): void => {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
} from "../../../src/utils/space";
|
} from "../../../src/utils/space";
|
||||||
import { createTestClient, mkSpace } from "../../test-utils";
|
import { createTestClient, mkSpace } from "../../test-utils";
|
||||||
import { createRoom, hasCreateRoomRights } from "../../../src/viewmodels/room-list/utils";
|
import { createRoom, hasCreateRoomRights } from "../../../src/viewmodels/room-list/utils";
|
||||||
|
import PosthogTrackers from "../../../src/PosthogTrackers";
|
||||||
|
|
||||||
jest.mock("../../../src/PosthogTrackers", () => ({
|
jest.mock("../../../src/PosthogTrackers", () => ({
|
||||||
trackInteraction: jest.fn(),
|
trackInteraction: jest.fn(),
|
||||||
@@ -276,10 +277,25 @@ describe("RoomListHeaderViewModel", () => {
|
|||||||
const resortSpy = jest.spyOn(RoomListStoreV3.instance, "resort").mockImplementation(jest.fn());
|
const resortSpy = jest.spyOn(RoomListStoreV3.instance, "resort").mockImplementation(jest.fn());
|
||||||
vm = new RoomListHeaderViewModel({ matrixClient, spaceStore: SpaceStore.instance });
|
vm = new RoomListHeaderViewModel({ matrixClient, spaceStore: SpaceStore.instance });
|
||||||
vm.sort(option);
|
vm.sort(option);
|
||||||
|
|
||||||
expect(resortSpy).toHaveBeenCalledWith(expectedAlgorithm);
|
expect(resortSpy).toHaveBeenCalledWith(expectedAlgorithm);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should track analytics on resort", () => {
|
||||||
|
jest.spyOn(RoomListStoreV3.instance, "activeSortAlgorithm", "get").mockReturnValue(
|
||||||
|
SortingAlgorithm.Alphabetic,
|
||||||
|
);
|
||||||
|
PosthogTrackers.trackRoomListSortingAlgorithmChange = jest.fn();
|
||||||
|
|
||||||
|
vm = new RoomListHeaderViewModel({ matrixClient, spaceStore: SpaceStore.instance });
|
||||||
|
jest.spyOn(RoomListStoreV3.instance, "resort").mockImplementation(jest.fn());
|
||||||
|
vm.sort("unread-first");
|
||||||
|
|
||||||
|
expect(PosthogTrackers.trackRoomListSortingAlgorithmChange).toHaveBeenCalledWith(
|
||||||
|
SortingAlgorithm.Alphabetic,
|
||||||
|
SortingAlgorithm.Unread,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("should toggle message preview from enabled to disabled", () => {
|
it("should toggle message preview from enabled to disabled", () => {
|
||||||
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName: string) => {
|
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName: string) => {
|
||||||
if (settingName === "RoomList.showMessagePreview") return true;
|
if (settingName === "RoomList.showMessagePreview") return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user