Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add analytics to install modal #1189

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"patch-package": "^6.4.7",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"rollup-plugin-node-polyfills": "^0.2.1",
"serve": "^14.2.1",
"ts-jest": "^29.0.3",
"typescript": "^4.3.5"
Expand Down
3 changes: 3 additions & 0 deletions packages/sdk-communication-layer/src/types/TrackingEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ export enum TrackingEvents {
SDK_RPC_REQUEST_DONE = 'sdk_rpc_request_done',
SDK_EXTENSION_UTILIZED = 'sdk_extension_utilized',
SDK_USE_INAPP_BROWSER = 'sdk_use_inapp_browser',
SDK_MODAL_VIEWED = 'sdk_modal_viewed',
SDK_MODAL_BUTTON_CLICKED = 'sdk_modal_button_clicked',
SDK_MODAL_TOGGLE_CHANGED = 'sdk_modal_toggle_changed',
}
1 change: 1 addition & 0 deletions packages/sdk-install-modal-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
}
},
"dependencies": {
"@metamask/sdk-communication-layer": "workspace:*",
"@paulmillr/qr": "^0.2.1"
}
}
4 changes: 4 additions & 0 deletions packages/sdk-install-modal-web/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* It contains typing information for all components that exist in this project.
*/
import { HTMLStencilElement, JSXBase } from "@stencil/core/internal";
import { TrackingEvents } from "@metamask/sdk-communication-layer";
export { TrackingEvents } from "@metamask/sdk-communication-layer";
export namespace Components {
interface MmInstallModal {
/**
Expand Down Expand Up @@ -47,6 +49,7 @@ declare global {
interface HTMLMmInstallModalElementEventMap {
"close": any;
"startDesktopOnboarding": any;
"trackAnalytics": { event: TrackingEvents, params?: Record<string, unknown> };
chakra-guy marked this conversation as resolved.
Show resolved Hide resolved
}
interface HTMLMmInstallModalElement extends Components.MmInstallModal, HTMLStencilElement {
addEventListener<K extends keyof HTMLMmInstallModalElementEventMap>(type: K, listener: (this: HTMLMmInstallModalElement, ev: MmInstallModalCustomEvent<HTMLMmInstallModalElementEventMap[K]>) => any, options?: boolean | AddEventListenerOptions): void;
Expand Down Expand Up @@ -113,6 +116,7 @@ declare namespace LocalJSX {
"link"?: string;
"onClose"?: (event: MmInstallModalCustomEvent<any>) => void;
"onStartDesktopOnboarding"?: (event: MmInstallModalCustomEvent<any>) => void;
"onTrackAnalytics"?: (event: MmInstallModalCustomEvent<{ event: TrackingEvents, params?: Record<string, unknown> }>) => void;
"preferDesktop"?: boolean;
"sdkVersion"?: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import CloseButton from '../misc/CloseButton';
import Logo from '../misc/Logo';
import encodeQR from '@paulmillr/qr';
import { SimpleI18n } from '../misc/simple-i18n';
import { TrackingEvents } from '@metamask/sdk-communication-layer';

@Component({
tag: 'mm-install-modal',
styleUrl: '../style.css',
Expand All @@ -31,6 +33,8 @@ export class InstallModal {

@Event() startDesktopOnboarding: EventEmitter;

@Event() trackAnalytics: EventEmitter<{ event: TrackingEvents, params?: Record<string, unknown> }>;

@State() tab: number = 1;

@State() isDefaultTab: boolean = true;
Expand All @@ -47,6 +51,14 @@ export class InstallModal {
this.setTab(this.preferDesktop ? 1 : 2);

this.i18nInstance = new SimpleI18n();

this.trackAnalytics.emit({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit: it's probably best to have this be invoked inside componentDidLoad() lifecycle method. This may be more correct to do, but you'll need to add the lifecycle method to these components

event: TrackingEvents.SDK_MODAL_VIEWED,
params: {
extensionInstalled: false,
tab: this.tab === 1 ? 'desktop' : 'mobile',
},
});
}

async connectedCallback() {
Expand All @@ -70,11 +82,27 @@ export class InstallModal {
}

onStartDesktopOnboardingHandler() {
this.trackAnalytics.emit({
event: TrackingEvents.SDK_MODAL_BUTTON_CLICKED,
params: {
button_type: 'install_extension',
tab: 'desktop',
},
});
this.startDesktopOnboarding.emit();
}

setTab(newTab: number) {
this.tab = newTab
setTab(newTab: number, isUserAction: boolean = false) {
if (isUserAction) {
this.trackAnalytics.emit({
event: TrackingEvents.SDK_MODAL_TOGGLE_CHANGED,
params: {
toggle: this.tab === 1 ? 'desktop_to_mobile' : 'mobile_to_desktop',
},
});
}

this.tab = newTab;
this.isDefaultTab = false;
}

Expand All @@ -84,16 +112,13 @@ export class InstallModal {
}

const t = (key: string) => this.i18nInstance.t(key);

const currentTab = this.isDefaultTab ? this.preferDesktop ? 1 : 2 : this.tab
const currentTab = this.isDefaultTab ? this.preferDesktop ? 1 : 2 : this.tab;

const svgElement = encodeQR(this.link, "svg", {
ecc: "medium",
scale: 2
});

console.log(`Showing modal with link ${this.link} and SVG QRCode ${svgElement}`)

return (
<WidgetWrapper className="install-model">
<div class='backdrop' onClick={this.onClose}></div>
Expand All @@ -112,13 +137,13 @@ export class InstallModal {
<div class='tabcontainer'>
<div class='flexContainer'>
<div
onClick={() => this.setTab(1)}
onClick={() => this.setTab(1, true)}
class={`tab flexItem ${currentTab === 1 ? 'tabactive': ''}`}
>
{t('DESKTOP')}
</div>
<div
onClick={() => this.setTab(2)}
onClick={() => this.setTab(2, true)}
class={`tab flexItem ${currentTab === 2 ? 'tabactive': ''}`}
>
{t('MOBILE')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export class SelectModal {
{t('SELECT_MODAL.CRYPTO_TAKE_CONTROL_TEXT')}
</div>

<button class='button' onClick={this.connectWithExtensionHandler}>
<button class='button' onClick={() => this.connectWithExtensionHandler()}>
<ConnectIcon />
<span class='installExtensionText'>
{t('CONNECT_WITH_EXTENSION')}
Expand Down
4 changes: 4 additions & 0 deletions packages/sdk-install-modal-web/stencil.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Config } from '@stencil/core';
import { visualizer } from 'rollup-plugin-visualizer';
import nodePolyfills from 'rollup-plugin-node-polyfills';

export const config: Config = {
namespace: 'sdk-install-modal-web',
Expand All @@ -18,6 +19,9 @@ export const config: Config = {
testing: {
browserHeadless: "new",
},
plugins: [
nodePolyfills(),
chakra-guy marked this conversation as resolved.
Show resolved Hide resolved
],
rollupPlugins: {
after: [
process.env.NODE_ENV === 'development' ? visualizer() : null
Expand Down
4 changes: 3 additions & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@
"socket.io-client>engine.io-client>ws>utf-8-validate": false,
"@metamask/sdk-communication-layer>bufferutil": false,
"@metamask/sdk-communication-layer>eciesjs>secp256k1": false,
"@metamask/sdk-communication-layer>utf-8-validate": false
"@metamask/sdk-communication-layer>utf-8-validate": false,
chakra-guy marked this conversation as resolved.
Show resolved Hide resolved
"@metamask/sdk-install-modal-web>@metamask/sdk-communication-layer>bufferutil": false,
"@metamask/sdk-install-modal-web>@metamask/sdk-communication-layer>utf-8-validate": false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ describe('showInstallModal', () => {
terminate: expect.any(Function),
debug: state.developerMode,
connectWithExtension: expect.any(Function),
onAnalyticsEvent: expect.any(Function),
});
expect(mockModalsInstall).toHaveBeenCalledTimes(1);
expect(mockInstallModalMount).toHaveBeenCalledWith(link);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TrackingEvents } from '@metamask/sdk-communication-layer';
import { logger } from '../../../utils/logger';
import {
RemoteConnectionProps,
Expand Down Expand Up @@ -34,6 +35,22 @@
options.connectWithExtensionProvider?.();
return false;
},
onAnalyticsEvent: ({
event,
params,
}: {
event: TrackingEvents;
params?: Record<string, any>;
}) => {
const extended = {

Check warning on line 45 in packages/sdk/src/services/RemoteConnection/ModalManager/showInstallModal.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/services/RemoteConnection/ModalManager/showInstallModal.ts#L44-L45

Added lines #L44 - L45 were not covered by tests
...params,
sdkVersion: options.sdk.getVersion(),
dappId: options.dappMetadata?.name,

Check warning on line 48 in packages/sdk/src/services/RemoteConnection/ModalManager/showInstallModal.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/services/RemoteConnection/ModalManager/showInstallModal.ts#L48

Added line #L48 was not covered by tests
source: options._source,
url: options.dappMetadata?.url,

Check warning on line 50 in packages/sdk/src/services/RemoteConnection/ModalManager/showInstallModal.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/services/RemoteConnection/ModalManager/showInstallModal.ts#L50

Added line #L50 was not covered by tests
};
state.analytics?.send({ event, params: extended });

Check warning on line 52 in packages/sdk/src/services/RemoteConnection/ModalManager/showInstallModal.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/services/RemoteConnection/ModalManager/showInstallModal.ts#L52

Added line #L52 was not covered by tests
},
});
state.installModal?.mount?.(link);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
KeyInfo,
RemoteCommunication,
StorageManagerProps,
TrackingEvents,
} from '@metamask/sdk-communication-layer';
import { MetaMaskInstaller } from '../../Platform/MetaMaskInstaller';
import { PlatformManager } from '../../Platform/PlatfformManager';
Expand Down Expand Up @@ -55,13 +56,20 @@ export interface RemoteConnectionProps {
*/
modals: {
onPendingModalDisconnect?: () => void;
install?: (params: {
install?: (args: {
link: string;
debug?: boolean;
preferDesktop?: boolean;
installer: MetaMaskInstaller;
terminate?: () => void;
connectWithExtension?: () => void;
onAnalyticsEvent: ({
event,
params,
}: {
event: TrackingEvents;
params?: Record<string, unknown>;
}) => void;
}) => {
unmount?: (shouldTerminate?: boolean) => void;
mount?: (link: string) => void;
Expand Down
10 changes: 10 additions & 0 deletions packages/sdk/src/ui/InstallModal/InstallModal-web.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TrackingEvents } from '@metamask/sdk-communication-layer';
import packageJson from '../../../package.json';
import { MetaMaskInstaller } from '../../Platform/MetaMaskInstaller';
import { logger } from '../../utils/logger';
Expand All @@ -10,13 +11,21 @@ const sdkWebInstallModal = ({
terminate,
connectWithExtension,
preferDesktop,
onAnalyticsEvent,
}: {
link: string;
debug?: boolean;
preferDesktop?: boolean;
installer: MetaMaskInstaller;
terminate?: () => void;
connectWithExtension?: () => void;
onAnalyticsEvent: ({
event,
params,
}: {
event: TrackingEvents;
params?: Record<string, unknown>;
}) => void;
}) => {
let modalLoader: ModalLoader | null = null;
let div: HTMLDivElement | null = null;
Expand Down Expand Up @@ -94,6 +103,7 @@ const sdkWebInstallModal = ({
link,
metaMaskInstaller: installer,
onClose: unmount,
onAnalyticsEvent,
})
.catch((err) => {
console.error(`[UI: InstallModal-web: sdkWebInstallModal()]`, err);
Expand Down
8 changes: 8 additions & 0 deletions packages/sdk/src/ui/InstallModal/Modal-web.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { TrackingEvents } from '@metamask/sdk-communication-layer';
import type { Components } from '@metamask/sdk-install-modal-web';

export interface InstallWidgetProps extends Components.MmInstallModal {
Expand All @@ -6,6 +7,10 @@
metaMaskInstaller: {
startDesktopOnboarding: () => void;
};
onAnalyticsEvent: (event: {
event: TrackingEvents;
params?: Record<string, unknown>;
}) => void;
}

export interface PendingWidgetProps extends Components.MmPendingModal {
Expand Down Expand Up @@ -80,6 +85,9 @@
'startDesktopOnboarding',
props.metaMaskInstaller.startDesktopOnboarding,
);

modal.addEventListener('trackAnalytics', ((e: CustomEvent) =>
props.onAnalyticsEvent?.(e.detail)) as EventListener);

Check warning on line 90 in packages/sdk/src/ui/InstallModal/Modal-web.ts

View check run for this annotation

Codecov / codecov/patch

packages/sdk/src/ui/InstallModal/Modal-web.ts#L89-L90

Added lines #L89 - L90 were not covered by tests
props.parentElement.appendChild(modal);
}

Expand Down
26 changes: 24 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11023,6 +11023,7 @@ __metadata:
dependencies:
"@lavamoat/allow-scripts": ^2.3.1
"@metamask/auto-changelog": 3.1.0
"@metamask/sdk-communication-layer": "workspace:*"
"@paulmillr/qr": ^0.2.1
"@size-limit/preset-big-lib": ^11.0.2
"@stencil/core": ^4.22.2
Expand Down Expand Up @@ -37702,7 +37703,7 @@ __metadata:
languageName: node
linkType: hard

"magic-string@npm:^0.25.0, magic-string@npm:^0.25.1, magic-string@npm:^0.25.7, magic-string@npm:^0.25.9":
"magic-string@npm:^0.25.0, magic-string@npm:^0.25.1, magic-string@npm:^0.25.3, magic-string@npm:^0.25.7, magic-string@npm:^0.25.9":
version: 0.25.9
resolution: "magic-string@npm:0.25.9"
dependencies:
Expand Down Expand Up @@ -38090,6 +38091,7 @@ __metadata:
patch-package: ^6.4.7
prettier: ^2.3.2
rimraf: ^3.0.2
rollup-plugin-node-polyfills: ^0.2.1
serve: ^14.2.1
ts-jest: ^29.0.3
ts-node: ^10.9.1
Expand Down Expand Up @@ -45545,6 +45547,17 @@ __metadata:
languageName: node
linkType: hard

"rollup-plugin-inject@npm:^3.0.0":
version: 3.0.2
resolution: "rollup-plugin-inject@npm:3.0.2"
dependencies:
estree-walker: ^0.6.1
magic-string: ^0.25.3
rollup-pluginutils: ^2.8.1
checksum: a014972c80fe34b8c8154056fa2533a8440066a31de831e3793fc21b15d108d92c22d8f7f472397bd5783d7c5e04d8cbf112fb72c5a26e997726e4eb090edad1
languageName: node
linkType: hard

"rollup-plugin-jscc@npm:^2.0.0":
version: 2.0.0
resolution: "rollup-plugin-jscc@npm:2.0.0"
Expand Down Expand Up @@ -45596,6 +45609,15 @@ __metadata:
languageName: node
linkType: hard

"rollup-plugin-node-polyfills@npm:^0.2.1":
version: 0.2.1
resolution: "rollup-plugin-node-polyfills@npm:0.2.1"
dependencies:
rollup-plugin-inject: ^3.0.0
checksum: e84645212c443aca3cfae2ba69f01c6d8c5c250f0bf651416b69a4572b60aae9da7cdd687de3ab9b903f7a1ab96b06b71f0c4927d1b02a37485360d2b563937b
languageName: node
linkType: hard

"rollup-plugin-peer-deps-external@npm:^2.2.4":
version: 2.2.4
resolution: "rollup-plugin-peer-deps-external@npm:2.2.4"
Expand Down Expand Up @@ -45772,7 +45794,7 @@ __metadata:
languageName: node
linkType: hard

"rollup-pluginutils@npm:^2.0.1, rollup-pluginutils@npm:^2.3.1, rollup-pluginutils@npm:^2.8.2":
"rollup-pluginutils@npm:^2.0.1, rollup-pluginutils@npm:^2.3.1, rollup-pluginutils@npm:^2.8.1, rollup-pluginutils@npm:^2.8.2":
version: 2.8.2
resolution: "rollup-pluginutils@npm:2.8.2"
dependencies:
Expand Down
Loading