feat(instant): Heap middleware and first tracking events
This commit is contained in:
@@ -10,6 +10,7 @@ import { SelectedAssetInstantHeading } from '../containers/selected_asset_instan
|
||||
import { ColorOption } from '../style/theme';
|
||||
import { zIndex } from '../style/z_index';
|
||||
import { OrderProcessState, SlideAnimationState } from '../types';
|
||||
import { analytics } from '../util/analytics';
|
||||
|
||||
import { CSSReset } from './css_reset';
|
||||
import { SlidingPanel } from './sliding_panel';
|
||||
@@ -68,6 +69,10 @@ export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantCon
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
// tslint:disable-next-line:prefer-function-over-method
|
||||
public componentDidMount(): void {
|
||||
analytics.track('Widget - Opened');
|
||||
}
|
||||
private readonly _handleSymbolClick = (): void => {
|
||||
this.setState({
|
||||
tokenSelectionPanelAnimationState: 'slidIn',
|
||||
|
38
packages/instant/src/redux/analytics_middleware.ts
Normal file
38
packages/instant/src/redux/analytics_middleware.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { ObjectMap } from '@0x/types';
|
||||
import * as _ from 'lodash';
|
||||
import { Middleware } from 'redux';
|
||||
|
||||
import { analytics } from '../util/analytics';
|
||||
|
||||
import { AccountState } from './../types';
|
||||
import { Action, ActionTypes } from './actions';
|
||||
import { State } from './reducer';
|
||||
|
||||
export const analyticsMiddleware: Middleware = store => next => middlewareAction => {
|
||||
const prevState = store.getState() as State;
|
||||
const nextAction = next(middlewareAction) as Action;
|
||||
const nextState = store.getState() as State;
|
||||
|
||||
const curAccount = nextState.providerState.account;
|
||||
const prevAccount = prevState.providerState.account;
|
||||
switch (nextAction.type) {
|
||||
case ActionTypes.SET_ACCOUNT_STATE_READY:
|
||||
if (curAccount.state === AccountState.Ready && !_.isEqual(curAccount, prevAccount)) {
|
||||
const ethAddress = curAccount.address;
|
||||
analytics.addUserProperties({ ethAddress });
|
||||
analytics.track('Wallet - Ready');
|
||||
}
|
||||
break;
|
||||
case ActionTypes.UPDATE_ACCOUNT_ETH_BALANCE:
|
||||
if (
|
||||
curAccount.state === AccountState.Ready &&
|
||||
curAccount.ethBalanceInWei &&
|
||||
!_.isEqual(curAccount, prevAccount)
|
||||
) {
|
||||
const ethBalanceInWei = curAccount.ethBalanceInWei.toString();
|
||||
analytics.addUserProperties({ ethBalanceInWei });
|
||||
}
|
||||
}
|
||||
|
||||
return nextAction;
|
||||
};
|
@@ -1,7 +1,8 @@
|
||||
import * as _ from 'lodash';
|
||||
import { createStore, Store as ReduxStore } from 'redux';
|
||||
import { devToolsEnhancer } from 'redux-devtools-extension/developmentOnly';
|
||||
import { applyMiddleware, createStore, Store as ReduxStore } from 'redux';
|
||||
import { composeWithDevTools, devToolsEnhancer } from 'redux-devtools-extension/developmentOnly';
|
||||
|
||||
import { analyticsMiddleware } from './analytics_middleware';
|
||||
import { createReducer, State } from './reducer';
|
||||
|
||||
export type Store = ReduxStore<State>;
|
||||
@@ -9,6 +10,6 @@ export type Store = ReduxStore<State>;
|
||||
export const store = {
|
||||
create: (initialState: State): Store => {
|
||||
const reducer = createReducer(initialState);
|
||||
return createStore(reducer, initialState, devToolsEnhancer({}));
|
||||
return createStore(reducer, initialState, composeWithDevTools(applyMiddleware(analyticsMiddleware)));
|
||||
},
|
||||
};
|
||||
|
35
packages/instant/src/util/analytics.ts
Normal file
35
packages/instant/src/util/analytics.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { ObjectMap } from '@0x/types';
|
||||
import { logUtils } from '@0x/utils';
|
||||
|
||||
import { HeapAnalytics, heapUtil } from './heap';
|
||||
|
||||
export class Analytics {
|
||||
public static init(): Analytics {
|
||||
return new Analytics();
|
||||
}
|
||||
public track(eventName: string, eventProperties?: ObjectMap<string | number>): void {
|
||||
console.log('HEAP: tracking', eventName, eventProperties);
|
||||
this._evaluteHeapCall(heap => heap.track(eventName, eventProperties));
|
||||
}
|
||||
public addUserProperties(properties: ObjectMap<string | number>): void {
|
||||
console.log('HEAP: adding user properties', properties);
|
||||
this._evaluteHeapCall(heap => heap.addUserProperties(properties));
|
||||
}
|
||||
public addEventProperties(properties: ObjectMap<string | number>): void {
|
||||
this._evaluteHeapCall(heap => heap.addEventProperties(properties));
|
||||
}
|
||||
private _evaluteHeapCall(heapFunctionCall: (heap: HeapAnalytics) => void): void {
|
||||
const curHeap = heapUtil.getHeap();
|
||||
if (curHeap) {
|
||||
try {
|
||||
heapFunctionCall(curHeap);
|
||||
} catch (e) {
|
||||
// We never want analytics to crash our React component
|
||||
// TODO: error reporter here
|
||||
logUtils.log('Analytics error', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const analytics = Analytics.init();
|
@@ -20,8 +20,13 @@ interface ModifiedWindow {
|
||||
const getWindow = (): ModifiedWindow => {
|
||||
return window as ModifiedWindow;
|
||||
};
|
||||
// Typescript-compatible version of https://docs.heapanalytics.com/docs/installation
|
||||
|
||||
const setupZeroExInstantHeap = () => {
|
||||
const curWindow = getWindow();
|
||||
// Set property to specify that this is zeroEx's heap
|
||||
curWindow.zeroExInstantLoadedHeap = true;
|
||||
|
||||
// Typescript-compatible version of https://docs.heapanalytics.com/docs/installation
|
||||
/* tslint:disable */
|
||||
((window as any).heap = (window as any).heap || []),
|
||||
((window as any).heap.load = function(e: any, t: any) {
|
||||
@@ -60,9 +65,6 @@ const setupZeroExInstantHeap = () => {
|
||||
(window as any).heap.load(HEAP_ANALYTICS_DEVELOPMENT_APP_ID);
|
||||
/* tslint:enable */
|
||||
|
||||
const curWindow = getWindow();
|
||||
// Set property to specify that this is zeroEx's heap
|
||||
curWindow.zeroExInstantLoadedHeap = true;
|
||||
return curWindow.heap as HeapAnalytics;
|
||||
};
|
||||
|
||||
@@ -71,17 +73,14 @@ export const heapUtil = {
|
||||
const curWindow = getWindow();
|
||||
const hasOtherExistingHeapIntegration = curWindow.heap && !curWindow.zeroExInstantLoadedHeap;
|
||||
if (hasOtherExistingHeapIntegration) {
|
||||
logUtils.log('Heap integration already exists');
|
||||
return null;
|
||||
}
|
||||
|
||||
const zeroExInstantHeapIntegration = curWindow.zeroExInstantLoadedHeap && curWindow.heap;
|
||||
if (zeroExInstantHeapIntegration) {
|
||||
logUtils.log('Using existing 0x instant heap');
|
||||
return zeroExInstantHeapIntegration;
|
||||
}
|
||||
|
||||
logUtils.log('Setting up heap');
|
||||
return setupZeroExInstantHeap();
|
||||
},
|
||||
};
|
||||
|
Reference in New Issue
Block a user