Send layout analytics as WebLayout (#9482)
This commit is contained in:
parent
a347525781
commit
28ecdc0cb4
4 changed files with 125 additions and 14 deletions
|
@ -56,7 +56,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.12.5",
|
"@babel/runtime": "^7.12.5",
|
||||||
"@matrix-org/analytics-events": "^0.2.0",
|
"@matrix-org/analytics-events": "^0.3.0",
|
||||||
"@matrix-org/matrix-wysiwyg": "^0.3.2",
|
"@matrix-org/matrix-wysiwyg": "^0.3.2",
|
||||||
"@matrix-org/react-sdk-module-api": "^0.0.3",
|
"@matrix-org/react-sdk-module-api": "^0.0.3",
|
||||||
"@sentry/browser": "^6.11.0",
|
"@sentry/browser": "^6.11.0",
|
||||||
|
|
|
@ -25,6 +25,11 @@ import SdkConfig from './SdkConfig';
|
||||||
import { MatrixClientPeg } from "./MatrixClientPeg";
|
import { MatrixClientPeg } from "./MatrixClientPeg";
|
||||||
import SettingsStore from "./settings/SettingsStore";
|
import SettingsStore from "./settings/SettingsStore";
|
||||||
import { ScreenName } from "./PosthogTrackers";
|
import { ScreenName } from "./PosthogTrackers";
|
||||||
|
import { ActionPayload } from "./dispatcher/payloads";
|
||||||
|
import { Action } from "./dispatcher/actions";
|
||||||
|
import { SettingUpdatedPayload } from "./dispatcher/payloads/SettingUpdatedPayload";
|
||||||
|
import dis from "./dispatcher/dispatcher";
|
||||||
|
import { Layout } from "./settings/enums/Layout";
|
||||||
|
|
||||||
/* Posthog analytics tracking.
|
/* Posthog analytics tracking.
|
||||||
*
|
*
|
||||||
|
@ -153,8 +158,41 @@ export class PosthogAnalytics {
|
||||||
} else {
|
} else {
|
||||||
this.enabled = false;
|
this.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dis.register(this.onAction);
|
||||||
|
SettingsStore.monitorSetting("layout", null);
|
||||||
|
SettingsStore.monitorSetting("useCompactLayout", null);
|
||||||
|
this.onLayoutUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onLayoutUpdated = () => {
|
||||||
|
let layout: UserProperties["WebLayout"];
|
||||||
|
|
||||||
|
switch (SettingsStore.getValue("layout")) {
|
||||||
|
case Layout.IRC:
|
||||||
|
layout = "IRC";
|
||||||
|
break;
|
||||||
|
case Layout.Bubble:
|
||||||
|
layout = "Bubble";
|
||||||
|
break;
|
||||||
|
case Layout.Group:
|
||||||
|
layout = SettingsStore.getValue("useCompactLayout") ? "Compact" : "Group";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is known to clobber other devices but is a good enough solution
|
||||||
|
// to get an idea of how much use each layout gets.
|
||||||
|
this.setProperty("WebLayout", layout);
|
||||||
|
};
|
||||||
|
|
||||||
|
private onAction = (payload: ActionPayload) => {
|
||||||
|
if (payload.action !== Action.SettingUpdated) return;
|
||||||
|
const settingsPayload = payload as SettingUpdatedPayload;
|
||||||
|
if (["layout", "useCompactLayout"].includes(settingsPayload.settingName)) {
|
||||||
|
this.onLayoutUpdated();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// we persist the last `$screen_name` and send it for all events until it is replaced
|
// we persist the last `$screen_name` and send it for all events until it is replaced
|
||||||
private lastScreen: ScreenName = "Loading";
|
private lastScreen: ScreenName = "Loading";
|
||||||
|
|
||||||
|
@ -192,7 +230,7 @@ export class PosthogAnalytics {
|
||||||
|
|
||||||
private static async getPlatformProperties(): Promise<PlatformProperties> {
|
private static async getPlatformProperties(): Promise<PlatformProperties> {
|
||||||
const platform = PlatformPeg.get();
|
const platform = PlatformPeg.get();
|
||||||
let appVersion;
|
let appVersion: string;
|
||||||
try {
|
try {
|
||||||
appVersion = await platform.getAppVersion();
|
appVersion = await platform.getAppVersion();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -17,15 +17,14 @@ limitations under the License.
|
||||||
import { mocked } from 'jest-mock';
|
import { mocked } from 'jest-mock';
|
||||||
import { PostHog } from 'posthog-js';
|
import { PostHog } from 'posthog-js';
|
||||||
|
|
||||||
import {
|
import { Anonymity, getRedactedCurrentLocation, IPosthogEvent, PosthogAnalytics } from '../src/PosthogAnalytics';
|
||||||
Anonymity,
|
|
||||||
|
|
||||||
getRedactedCurrentLocation,
|
|
||||||
IPosthogEvent,
|
|
||||||
PosthogAnalytics,
|
|
||||||
} from '../src/PosthogAnalytics';
|
|
||||||
import SdkConfig from '../src/SdkConfig';
|
import SdkConfig from '../src/SdkConfig';
|
||||||
import { getMockClientWithEventEmitter } from './test-utils';
|
import { getMockClientWithEventEmitter } from './test-utils';
|
||||||
|
import SettingsStore from "../src/settings/SettingsStore";
|
||||||
|
import { Layout } from "../src/settings/enums/Layout";
|
||||||
|
import defaultDispatcher from "../src/dispatcher/dispatcher";
|
||||||
|
import { Action } from "../src/dispatcher/actions";
|
||||||
|
import { SettingLevel } from "../src/settings/SettingLevel";
|
||||||
|
|
||||||
const getFakePosthog = (): PostHog => ({
|
const getFakePosthog = (): PostHog => ({
|
||||||
capture: jest.fn(),
|
capture: jest.fn(),
|
||||||
|
@ -37,7 +36,7 @@ const getFakePosthog = (): PostHog => ({
|
||||||
|
|
||||||
export interface ITestEvent extends IPosthogEvent {
|
export interface ITestEvent extends IPosthogEvent {
|
||||||
eventName: "JestTestEvents";
|
eventName: "JestTestEvents";
|
||||||
foo: string;
|
foo?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("PosthogAnalytics", () => {
|
describe("PosthogAnalytics", () => {
|
||||||
|
@ -180,4 +179,78 @@ describe("PosthogAnalytics", () => {
|
||||||
expect(mocked(fakePosthog).identify.mock.calls[0][0]).toBe("existing_analytics_id");
|
expect(mocked(fakePosthog).identify.mock.calls[0][0]).toBe("existing_analytics_id");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("WebLayout", () => {
|
||||||
|
let analytics: PosthogAnalytics;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
SdkConfig.put({
|
||||||
|
brand: "Testing",
|
||||||
|
posthog: {
|
||||||
|
project_api_key: "foo",
|
||||||
|
api_host: "bar",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
analytics = new PosthogAnalytics(fakePosthog);
|
||||||
|
analytics.setAnonymity(Anonymity.Pseudonymous);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should send layout IRC correctly", async () => {
|
||||||
|
await SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
|
||||||
|
defaultDispatcher.dispatch({
|
||||||
|
action: Action.SettingUpdated,
|
||||||
|
settingName: "layout",
|
||||||
|
}, true);
|
||||||
|
analytics.trackEvent<ITestEvent>({
|
||||||
|
eventName: "JestTestEvents",
|
||||||
|
});
|
||||||
|
expect(mocked(fakePosthog).capture.mock.calls[0][1]["$set"]).toStrictEqual({
|
||||||
|
"WebLayout": "IRC",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should send layout Bubble correctly", async () => {
|
||||||
|
await SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.Bubble);
|
||||||
|
defaultDispatcher.dispatch({
|
||||||
|
action: Action.SettingUpdated,
|
||||||
|
settingName: "layout",
|
||||||
|
}, true);
|
||||||
|
analytics.trackEvent<ITestEvent>({
|
||||||
|
eventName: "JestTestEvents",
|
||||||
|
});
|
||||||
|
expect(mocked(fakePosthog).capture.mock.calls[0][1]["$set"]).toStrictEqual({
|
||||||
|
"WebLayout": "Bubble",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should send layout Group correctly", async () => {
|
||||||
|
await SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.Group);
|
||||||
|
defaultDispatcher.dispatch({
|
||||||
|
action: Action.SettingUpdated,
|
||||||
|
settingName: "layout",
|
||||||
|
}, true);
|
||||||
|
analytics.trackEvent<ITestEvent>({
|
||||||
|
eventName: "JestTestEvents",
|
||||||
|
});
|
||||||
|
expect(mocked(fakePosthog).capture.mock.calls[0][1]["$set"]).toStrictEqual({
|
||||||
|
"WebLayout": "Group",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should send layout Compact correctly", async () => {
|
||||||
|
await SettingsStore.setValue("layout", null, SettingLevel.DEVICE, Layout.Group);
|
||||||
|
await SettingsStore.setValue("useCompactLayout", null, SettingLevel.DEVICE, true);
|
||||||
|
defaultDispatcher.dispatch({
|
||||||
|
action: Action.SettingUpdated,
|
||||||
|
settingName: "useCompactLayout",
|
||||||
|
}, true);
|
||||||
|
analytics.trackEvent<ITestEvent>({
|
||||||
|
eventName: "JestTestEvents",
|
||||||
|
});
|
||||||
|
expect(mocked(fakePosthog).capture.mock.calls[0][1]["$set"]).toStrictEqual({
|
||||||
|
"WebLayout": "Compact",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1664,10 +1664,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe"
|
resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe"
|
||||||
integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==
|
integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==
|
||||||
|
|
||||||
"@matrix-org/analytics-events@^0.2.0":
|
"@matrix-org/analytics-events@^0.3.0":
|
||||||
version "0.2.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@matrix-org/analytics-events/-/analytics-events-0.2.0.tgz#453925c939ecdd5ca6c797d293deb8cf0933f1b8"
|
resolved "https://registry.yarnpkg.com/@matrix-org/analytics-events/-/analytics-events-0.3.0.tgz#a428f7e3f164ffadf38f35bc0f0f9a3e47369ce6"
|
||||||
integrity sha512-+0/Sydm4MNOcqd8iySJmojVPB74Axba4BXlwTsiKmL5fgYqdUkwmqkO39K7Pn8i+a+8pg11oNvBPkpWs3O5Qww==
|
integrity sha512-f1WIMA8tjNB3V5g1C34yIpIJK47z6IJ4SLiY4j+J9Gw4X8C3TKGTAx563rMcMvW3Uk/PFqnIBXtkavHBXoYJ9A==
|
||||||
|
|
||||||
"@matrix-org/matrix-wysiwyg@^0.3.2":
|
"@matrix-org/matrix-wysiwyg@^0.3.2":
|
||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
|
|
Loading…
Reference in a new issue