Merge pull request #1300 from 0xProject/feature/instant/events-account
[instant] Implement account related events
This commit is contained in:
@@ -12,6 +12,7 @@ import { Action, actions } from '../redux/actions';
|
||||
import { asyncData } from '../redux/async_data';
|
||||
import { State } from '../redux/reducer';
|
||||
import { Network, Omit, OperatingSystem, ProviderState, StandardSlidingPanelContent } from '../types';
|
||||
import { analytics } from '../util/analytics';
|
||||
import { envUtil } from '../util/env';
|
||||
|
||||
export interface ConnectedAccountPaymentMethodProps {}
|
||||
@@ -40,8 +41,11 @@ const mapDispatchToProps = (
|
||||
ownProps: ConnectedAccountPaymentMethodProps,
|
||||
): ConnectedDispatch => ({
|
||||
openInstallWalletPanel: () => dispatch(actions.openStandardSlidingPanel(StandardSlidingPanelContent.InstallWallet)),
|
||||
unlockWalletAndDispatchToStore: async (providerState: ProviderState) =>
|
||||
asyncData.fetchAccountInfoAndDispatchToStore(providerState, dispatch, true),
|
||||
unlockWalletAndDispatchToStore: (providerState: ProviderState) => {
|
||||
analytics.trackAccountUnlockRequested();
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
asyncData.fetchAccountInfoAndDispatchToStore(providerState, dispatch, true);
|
||||
},
|
||||
});
|
||||
|
||||
const mergeProps = (
|
||||
|
@@ -10,20 +10,6 @@ import { Action, ActionTypes } from './actions';
|
||||
|
||||
import { State } from './reducer';
|
||||
|
||||
const shouldTriggerWalletReady = (prevAccount: Account, curAccount: Account): boolean => {
|
||||
const didJustTurnReady = curAccount.state === AccountState.Ready && prevAccount.state !== AccountState.Ready;
|
||||
if (didJustTurnReady) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (curAccount.state === AccountState.Ready && prevAccount.state === AccountState.Ready) {
|
||||
// Account was ready, and is now ready again, but address has changed
|
||||
return curAccount.address !== prevAccount.address;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
export const analyticsMiddleware: Middleware = store => next => middlewareAction => {
|
||||
const prevState = store.getState() as State;
|
||||
const prevAccount = prevState.providerState.account;
|
||||
@@ -35,10 +21,24 @@ export const analyticsMiddleware: Middleware = store => next => middlewareAction
|
||||
|
||||
switch (nextAction.type) {
|
||||
case ActionTypes.SET_ACCOUNT_STATE_READY:
|
||||
if (curAccount.state === AccountState.Ready && shouldTriggerWalletReady(prevAccount, curAccount)) {
|
||||
if (curAccount.state === AccountState.Ready) {
|
||||
const didJustTurnReady = prevAccount.state !== AccountState.Ready;
|
||||
const didJustUpdateAddress =
|
||||
prevAccount.state === AccountState.Ready && prevAccount.address !== curAccount.address;
|
||||
const ethAddress = curAccount.address;
|
||||
analytics.addUserProperties({ ethAddress });
|
||||
analytics.trackWalletReady();
|
||||
if (didJustTurnReady) {
|
||||
analytics.trackAccountReady(ethAddress);
|
||||
analytics.addUserProperties({ lastKnownEthAddress: ethAddress });
|
||||
} else if (didJustUpdateAddress) {
|
||||
analytics.trackAccountAddressChanged(ethAddress);
|
||||
analytics.addUserProperties({ lastKnownEthAddress: ethAddress });
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ActionTypes.SET_ACCOUNT_STATE_LOCKED:
|
||||
if (prevAccount.state !== AccountState.Locked && curAccount.state === AccountState.Locked) {
|
||||
// if we are moving from account not locked to account locked, track `Account - Locked`
|
||||
analytics.trackAccountLocked();
|
||||
}
|
||||
break;
|
||||
case ActionTypes.UPDATE_ACCOUNT_ETH_BALANCE:
|
||||
|
@@ -5,6 +5,7 @@ import { Dispatch } from 'redux';
|
||||
|
||||
import { BIG_NUMBER_ZERO } from '../constants';
|
||||
import { AccountState, ERC20Asset, OrderProcessState, ProviderState } from '../types';
|
||||
import { analytics } from '../util/analytics';
|
||||
import { assetUtils } from '../util/asset';
|
||||
import { buyQuoteUpdater } from '../util/buy_quote_updater';
|
||||
import { coinbaseApi } from '../util/coinbase_api';
|
||||
@@ -58,6 +59,7 @@ export const asyncData = {
|
||||
? await (provider as any).enable()
|
||||
: await web3Wrapper.getAvailableAddressesAsync();
|
||||
} catch (e) {
|
||||
analytics.trackAccountUnlockDenied();
|
||||
dispatch(actions.setAccountStateLocked());
|
||||
return;
|
||||
}
|
||||
|
@@ -1,6 +1,4 @@
|
||||
import { ObjectMap } from '@0x/types';
|
||||
|
||||
import { heapUtil } from './heap';
|
||||
import { EventProperties, heapUtil } from './heap';
|
||||
|
||||
let isDisabled = false;
|
||||
export const disableAnalytics = (shouldDisableAnalytics: boolean) => {
|
||||
@@ -15,11 +13,15 @@ export const evaluateIfEnabled = (fnCall: () => void) => {
|
||||
|
||||
enum EventNames {
|
||||
INSTANT_OPENED = 'Instant - Opened',
|
||||
WALLET_READY = 'Wallet - Ready',
|
||||
ACCOUNT_LOCKED = 'Account - Locked',
|
||||
ACCOUNT_READY = 'Account - Ready',
|
||||
ACCOUNT_UNLOCK_REQUESTED = 'Account - Unlock Requested',
|
||||
ACCOUNT_UNLOCK_DENIED = 'Account - Unlock Denied',
|
||||
ACCOUNT_ADDRESS_CHANGED = 'Account - Address Changed',
|
||||
}
|
||||
const track = (eventName: EventNames, eventData: ObjectMap<string | number> = {}): void => {
|
||||
const track = (eventName: EventNames, eventProperties: EventProperties = {}): void => {
|
||||
evaluateIfEnabled(() => {
|
||||
heapUtil.evaluateHeapCall(heap => heap.track(eventName, eventData));
|
||||
heapUtil.evaluateHeapCall(heap => heap.track(eventName, eventProperties));
|
||||
});
|
||||
};
|
||||
function trackingEventFnWithoutPayload(eventName: EventNames): () => void {
|
||||
@@ -28,16 +30,14 @@ function trackingEventFnWithoutPayload(eventName: EventNames): () => void {
|
||||
};
|
||||
}
|
||||
// tslint:disable-next-line:no-unused-variable
|
||||
function trackingEventFnWithPayload<T extends ObjectMap<string | number>>(
|
||||
eventName: EventNames,
|
||||
): (eventDataProperties: T) => void {
|
||||
return (eventDataProperties: T) => {
|
||||
track(eventName, eventDataProperties);
|
||||
function trackingEventFnWithPayload(eventName: EventNames): (eventProperties: EventProperties) => void {
|
||||
return (eventProperties: EventProperties) => {
|
||||
track(eventName, eventProperties);
|
||||
};
|
||||
}
|
||||
|
||||
export interface AnalyticsUserOptions {
|
||||
ethAddress?: string;
|
||||
lastKnownEthAddress?: string;
|
||||
ethBalanceInUnitAmount?: string;
|
||||
}
|
||||
export interface AnalyticsEventOptions {
|
||||
@@ -48,6 +48,7 @@ export interface AnalyticsEventOptions {
|
||||
gitSha?: string;
|
||||
npmVersion?: string;
|
||||
}
|
||||
|
||||
export const analytics = {
|
||||
addUserProperties: (properties: AnalyticsUserOptions): void => {
|
||||
evaluateIfEnabled(() => {
|
||||
@@ -59,6 +60,11 @@ export const analytics = {
|
||||
heapUtil.evaluateHeapCall(heap => heap.addEventProperties(properties));
|
||||
});
|
||||
},
|
||||
trackWalletReady: trackingEventFnWithoutPayload(EventNames.WALLET_READY),
|
||||
trackInstantOpened: trackingEventFnWithoutPayload(EventNames.INSTANT_OPENED),
|
||||
trackAccountLocked: trackingEventFnWithoutPayload(EventNames.ACCOUNT_LOCKED),
|
||||
trackAccountReady: (address: string) => trackingEventFnWithPayload(EventNames.ACCOUNT_READY)({ address }),
|
||||
trackAccountUnlockRequested: trackingEventFnWithoutPayload(EventNames.ACCOUNT_UNLOCK_REQUESTED),
|
||||
trackAccountUnlockDenied: trackingEventFnWithoutPayload(EventNames.ACCOUNT_UNLOCK_DENIED),
|
||||
trackAccountAddressChanged: (address: string) =>
|
||||
trackingEventFnWithPayload(EventNames.ACCOUNT_ADDRESS_CHANGED)({ address }),
|
||||
};
|
||||
|
@@ -6,11 +6,13 @@ import { HEAP_ANALYTICS_ID } from '../constants';
|
||||
|
||||
import { AnalyticsEventOptions, AnalyticsUserOptions } from './analytics';
|
||||
|
||||
export type EventProperties = ObjectMap<string | number>;
|
||||
|
||||
export interface HeapAnalytics {
|
||||
loaded: boolean;
|
||||
appid: string;
|
||||
identify(id: string, idType: string): void;
|
||||
track(eventName: string, eventProperties?: ObjectMap<string | number>): void;
|
||||
track(eventName: string, eventProperties?: EventProperties): void;
|
||||
resetIdentity(): void;
|
||||
addUserProperties(properties: AnalyticsUserOptions): void;
|
||||
addEventProperties(properties: AnalyticsEventOptions): void;
|
||||
|
Reference in New Issue
Block a user