Replace calls to google analytics with calls to heap
This commit is contained in:
@@ -11,12 +11,9 @@
|
||||
"clean": "shx rm -f public/bundle*",
|
||||
"lint": "tslint --project . 'ts/**/*.ts' 'ts/**/*.tsx'",
|
||||
"watch_without_deps": "webpack-dev-server --content-base public --https",
|
||||
"deploy_dogfood":
|
||||
"npm run build; aws s3 sync ./public/. s3://dogfood.0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
|
||||
"deploy_staging":
|
||||
"npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
|
||||
"deploy_live":
|
||||
"npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --exclude *.map.js"
|
||||
"deploy_dogfood": "npm run build; aws s3 sync ./public/. s3://dogfood.0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
|
||||
"deploy_staging": "npm run build; aws s3 sync ./public/. s3://staging-0xproject --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers",
|
||||
"deploy_live": "npm run build; aws s3 sync ./public/. s3://0xproject.com --profile 0xproject --region us-east-1 --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --exclude *.map.js"
|
||||
},
|
||||
"author": "Fabio Berger",
|
||||
"license": "Apache-2.0",
|
||||
@@ -49,7 +46,6 @@
|
||||
"react-copy-to-clipboard": "^4.2.3",
|
||||
"react-document-title": "^2.0.3",
|
||||
"react-dom": "15.6.1",
|
||||
"react-ga": "^2.4.1",
|
||||
"react-popper": "^1.0.0-beta.6",
|
||||
"react-redux": "^5.0.3",
|
||||
"react-router-dom": "^4.1.1",
|
||||
|
@@ -506,6 +506,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
|
||||
await this._checkForUntrackedTokensAndAskToAddAsync();
|
||||
}
|
||||
private _trackOrderEvent(eventName: string): void {
|
||||
const parsedOrder = this.state.parsedOrder;
|
||||
analytics.trackOrderEvent(eventName, parsedOrder);
|
||||
}
|
||||
private async _onFillOrderClickFireAndForgetAsync(): Promise<void> {
|
||||
if (this.props.blockchainErr !== BlockchainErrs.NoError || _.isEmpty(this.props.userAddress)) {
|
||||
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
|
||||
@@ -552,14 +556,12 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
});
|
||||
return;
|
||||
}
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
const eventLabel = `${parsedOrder.metadata.takerToken.symbol}-${networkName}`;
|
||||
try {
|
||||
const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync(
|
||||
signedOrder,
|
||||
this.props.orderFillAmount,
|
||||
);
|
||||
analytics.logEvent('Portal', 'Fill Order Success', eventLabel, parsedOrder.signedOrder.takerTokenAmount);
|
||||
this._trackOrderEvent('Fill Order Success');
|
||||
// After fill completes, let's force fetch the token balances
|
||||
this.props.dispatcher.forceTokenStateRefetch();
|
||||
this.setState({
|
||||
@@ -573,7 +575,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
this.setState({
|
||||
isFilling: false,
|
||||
});
|
||||
analytics.logEvent('Portal', 'Fill Order Failure', eventLabel, parsedOrder.signedOrder.takerTokenAmount);
|
||||
this._trackOrderEvent('Fill Order Failure');
|
||||
const errMsg = `${err}`;
|
||||
if (utils.didUserDenyWeb3Request(errMsg)) {
|
||||
return;
|
||||
@@ -638,7 +640,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
globalErrMsg: '',
|
||||
unavailableTakerAmount: takerTokenAmount,
|
||||
});
|
||||
analytics.logEvent('Portal', 'Cancel Order Success', eventLabel, parsedOrder.signedOrder.makerTokenAmount);
|
||||
this._trackOrderEvent('Cancel Order Success');
|
||||
return;
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
@@ -648,7 +650,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> {
|
||||
if (utils.didUserDenyWeb3Request(errMsg)) {
|
||||
return;
|
||||
}
|
||||
analytics.logEvent('Portal', 'Cancel Order Failure', eventLabel, parsedOrder.signedOrder.makerTokenAmount);
|
||||
this._trackOrderEvent('Cancel Order Failure');
|
||||
globalErrMsg = 'Failed to cancel order, please refresh and try again';
|
||||
logUtils.log(`${err}`);
|
||||
this.setState({
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { generatePseudoRandomSalt, getOrderHashHex } from '@0xproject/order-utils';
|
||||
import { colors, constants as sharedConstants } from '@0xproject/react-shared';
|
||||
import { ECSignature, Order } from '@0xproject/types';
|
||||
import { ECSignature, Order as ZeroExOrder } from '@0xproject/types';
|
||||
import { BigNumber, logUtils } from '@0xproject/utils';
|
||||
import * as _ from 'lodash';
|
||||
import Dialog from 'material-ui/Dialog';
|
||||
@@ -20,7 +20,7 @@ import { SwapIcon } from 'ts/components/ui/swap_icon';
|
||||
import { Dispatcher } from 'ts/redux/dispatcher';
|
||||
import { portalOrderSchema } from 'ts/schemas/portal_order_schema';
|
||||
import { validator } from 'ts/schemas/validator';
|
||||
import { AlertTypes, BlockchainErrs, HashData, Side, SideToAssetToken, Token, TokenByAddress } from 'ts/types';
|
||||
import { AlertTypes, BlockchainErrs, HashData, Side, SideToAssetToken, Token, TokenByAddress, Order } from 'ts/types';
|
||||
import { analytics } from 'ts/utils/analytics';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { errorReporter } from 'ts/utils/error_reporter';
|
||||
@@ -254,7 +254,8 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
userAddressIfExists,
|
||||
debitToken.address,
|
||||
);
|
||||
const receiveAmount = this.props.sideToAssetToken[Side.Receive].amount;
|
||||
const receiveToken = this.props.sideToAssetToken[Side.Receive];
|
||||
const receiveAmount = receiveToken.amount;
|
||||
if (
|
||||
!_.isUndefined(debitToken.amount) &&
|
||||
!_.isUndefined(receiveAmount) &&
|
||||
@@ -264,24 +265,28 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
debitBalance.gte(debitToken.amount) &&
|
||||
debitAllowance.gte(debitToken.amount)
|
||||
) {
|
||||
const didSignSuccessfully = await this._signTransactionAsync();
|
||||
if (didSignSuccessfully) {
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
const eventLabel = `${this.props.tokenByAddress[debitToken.address].symbol}-${networkName}`;
|
||||
analytics.logEvent('Portal', 'Sign Order Success', eventLabel, debitToken.amount.toNumber());
|
||||
const signedOrder = await this._signTransactionAsync();
|
||||
const doesSignedOrderExist = !_.isUndefined(signedOrder);
|
||||
if (doesSignedOrderExist) {
|
||||
analytics.trackOrderEvent('Sign Order Success', signedOrder);
|
||||
this.setState({
|
||||
globalErrMsg: '',
|
||||
shouldShowIncompleteErrs: false,
|
||||
});
|
||||
}
|
||||
return didSignSuccessfully;
|
||||
return doesSignedOrderExist;
|
||||
} else {
|
||||
let globalErrMsg = 'You must fix the above errors in order to generate a valid order';
|
||||
if (this.props.userAddress === '') {
|
||||
globalErrMsg = 'You must enable wallet communication';
|
||||
this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true);
|
||||
}
|
||||
analytics.logEvent('Portal', 'Sign Order Failure', globalErrMsg);
|
||||
analytics.track('Sign Order Failure', {
|
||||
makerTokenAmount: debitToken.amount.toString(),
|
||||
makerToken: this.props.tokenByAddress[debitToken.address].symbol,
|
||||
takerTokenAmount: receiveToken.amount.toString(),
|
||||
takerToken: this.props.tokenByAddress[receiveToken.address].symbol,
|
||||
});
|
||||
this.setState({
|
||||
globalErrMsg,
|
||||
shouldShowIncompleteErrs: true,
|
||||
@@ -289,7 +294,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private async _signTransactionAsync(): Promise<boolean> {
|
||||
private async _signTransactionAsync(): Promise<Order | undefined> {
|
||||
this.setState({
|
||||
signingState: SigningState.SIGNING,
|
||||
});
|
||||
@@ -299,11 +304,11 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
this.setState({
|
||||
signingState: SigningState.UNSIGNED,
|
||||
});
|
||||
return false;
|
||||
return undefined;
|
||||
}
|
||||
const hashData = this.props.hashData;
|
||||
|
||||
const zeroExOrder: Order = {
|
||||
const zeroExOrder: ZeroExOrder = {
|
||||
exchangeContractAddress: exchangeContractAddr,
|
||||
expirationUnixTimestampSec: hashData.orderExpiryTimestamp,
|
||||
feeRecipient: hashData.feeRecipientAddress,
|
||||
@@ -320,9 +325,10 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
const orderHash = getOrderHashHex(zeroExOrder);
|
||||
|
||||
let globalErrMsg = '';
|
||||
let order;
|
||||
try {
|
||||
const ecSignature = await this.props.blockchain.signOrderHashAsync(orderHash);
|
||||
const order = utils.generateOrder(
|
||||
order = utils.generateOrder(
|
||||
exchangeContractAddr,
|
||||
this.props.sideToAssetToken,
|
||||
hashData.orderExpiryTimestamp,
|
||||
@@ -356,7 +362,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G
|
||||
signingState: globalErrMsg === '' ? SigningState.SIGNED : SigningState.UNSIGNED,
|
||||
globalErrMsg,
|
||||
});
|
||||
return globalErrMsg === '';
|
||||
return order;
|
||||
}
|
||||
private _updateOrderAddress(address?: string): void {
|
||||
if (!_.isUndefined(address)) {
|
||||
|
@@ -111,14 +111,16 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
|
||||
if (!this._isAllowanceSet()) {
|
||||
newAllowanceAmountInBaseUnits = DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS;
|
||||
}
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
const eventLabel = `${this.props.token.symbol}-${networkName}`;
|
||||
const logData = {
|
||||
tokenSymbol: this.props.token.symbol,
|
||||
newAllowance: newAllowanceAmountInBaseUnits.toNumber(),
|
||||
};
|
||||
try {
|
||||
await this.props.blockchain.setProxyAllowanceAsync(this.props.token, newAllowanceAmountInBaseUnits);
|
||||
analytics.logEvent('Portal', 'Set Allowance Success', eventLabel, newAllowanceAmountInBaseUnits.toNumber());
|
||||
analytics.track('Set Allowances Success', logData);
|
||||
await this.props.refetchTokenStateAsync();
|
||||
} catch (err) {
|
||||
analytics.logEvent('Portal', 'Set Allowance Failure', eventLabel, newAllowanceAmountInBaseUnits.toNumber());
|
||||
analytics.track('Set Allowance Failure', logData);
|
||||
this.setState({
|
||||
isSpinnerVisible: false,
|
||||
});
|
||||
|
@@ -225,20 +225,25 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
||||
(this.props.stepIndex === 0 && !this.props.isRunning && this.props.blockchainIsLoaded) ||
|
||||
(!this.props.isRunning && !this.props.hasBeenClosed && this.props.blockchainIsLoaded)
|
||||
) {
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
analytics.logEvent('Portal', 'Onboarding Started - Automatic', networkName, this.props.stepIndex);
|
||||
analytics.track('Onboarding Started', {
|
||||
reason: 'automatic',
|
||||
stepIndex: this.props.stepIndex,
|
||||
});
|
||||
this.props.updateIsRunning(true);
|
||||
}
|
||||
}
|
||||
private _updateOnboardingStep(stepIndex: number): void {
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
this.props.updateOnboardingStep(stepIndex);
|
||||
analytics.logEvent('Portal', 'Update Onboarding Step', networkName, stepIndex);
|
||||
analytics.track('Update Onboarding Step', {
|
||||
stepIndex,
|
||||
});
|
||||
}
|
||||
private _closeOnboarding(): void {
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
this.props.updateIsRunning(false);
|
||||
analytics.logEvent('Portal', 'Onboarding Closed', networkName, this.props.stepIndex);
|
||||
analytics.track('OnboardingClosed', {
|
||||
stepIndex: this.props.stepIndex,
|
||||
});
|
||||
}
|
||||
private _renderZrxAllowanceToggle(): React.ReactNode {
|
||||
const zrxToken = utils.getZrxToken(this.props.tokenByAddress);
|
||||
|
@@ -390,8 +390,10 @@ export class Portal extends React.Component<PortalProps, PortalState> {
|
||||
}
|
||||
|
||||
private _startOnboarding(): void {
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
analytics.logEvent('Portal', 'Onboarding Started - Manual', networkName, this.props.portalOnboardingStep);
|
||||
analytics.track('Onboarding Started', {
|
||||
reason: 'manual',
|
||||
stepIndex: this.props.portalOnboardingStep,
|
||||
});
|
||||
this.props.dispatcher.updatePortalOnboardingShowing(true);
|
||||
}
|
||||
private _renderWalletSection(): React.ReactNode {
|
||||
|
@@ -64,10 +64,10 @@ export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = (
|
||||
const link = props.relayerInfo.appUrl || props.relayerInfo.url;
|
||||
const topTokens = props.relayerInfo.topTokens;
|
||||
const weeklyTxnVolume = props.relayerInfo.weeklyTxnVolume;
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[props.networkId];
|
||||
const eventLabel = `${props.relayerInfo.name}-${networkName}`;
|
||||
const onClick = () => {
|
||||
analytics.logEvent('Portal', 'Relayer Click', eventLabel);
|
||||
analytics.track('Relayer Click', {
|
||||
name: props.relayerInfo.name,
|
||||
});
|
||||
utils.openUrl(link);
|
||||
};
|
||||
const headerImageUrl = props.relayerInfo.logoImgUrl;
|
||||
|
@@ -46,11 +46,11 @@ class TokenLink extends React.Component<TokenLinkProps, TokenLinkState> {
|
||||
};
|
||||
}
|
||||
public render(): React.ReactNode {
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
const eventLabel = `${this.props.tokenInfo.symbol}-${networkName}`;
|
||||
const onClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||
event.stopPropagation();
|
||||
analytics.logEvent('Portal', 'Token Click', eventLabel);
|
||||
analytics.track('Token Click', {
|
||||
tokenSymbol: this.props.tokenInfo.symbol,
|
||||
});
|
||||
const tokenLink = this._tokenLinkFromToken(this.props.tokenInfo, this.props.networkId);
|
||||
utils.openUrl(tokenLink);
|
||||
};
|
||||
|
@@ -491,7 +491,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
const action =
|
||||
wrappedEtherDirection === Side.Deposit ? 'Wallet - Wrap ETH Opened' : 'Wallet - Unwrap WETH Opened';
|
||||
analytics.logEvent('Portal', action, networkName);
|
||||
analytics.track(action);
|
||||
this.setState({
|
||||
wrappedEtherDirection,
|
||||
});
|
||||
@@ -500,7 +500,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
const action =
|
||||
wrappedEtherDirection === Side.Deposit ? 'Wallet - Wrap ETH Closed' : 'Wallet - Unwrap WETH Closed';
|
||||
analytics.logEvent('Portal', action, networkName);
|
||||
analytics.track(action);
|
||||
this.setState({
|
||||
wrappedEtherDirection: undefined,
|
||||
});
|
||||
|
@@ -188,20 +188,23 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
|
||||
this.setState({
|
||||
isEthConversionHappening: true,
|
||||
});
|
||||
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
|
||||
const etherToken = this.props.etherToken;
|
||||
const amountToConvert = this.state.currentInputAmount;
|
||||
const ethAmount = Web3Wrapper.toUnitAmount(amountToConvert, constants.DECIMAL_PLACES_ETH).toString();
|
||||
const tokenAmount = Web3Wrapper.toUnitAmount(amountToConvert, etherToken.decimals).toString();
|
||||
try {
|
||||
const etherToken = this.props.etherToken;
|
||||
const amountToConvert = this.state.currentInputAmount;
|
||||
if (this.props.direction === Side.Deposit) {
|
||||
await this.props.blockchain.convertEthToWrappedEthTokensAsync(etherToken.address, amountToConvert);
|
||||
const ethAmount = Web3Wrapper.toUnitAmount(amountToConvert, constants.DECIMAL_PLACES_ETH);
|
||||
this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount.toString()} ETH to WETH`);
|
||||
analytics.logEvent('Portal', 'Wrap ETH Successfully', networkName);
|
||||
this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount} ETH to WETH`);
|
||||
analytics.track('Wrap ETH Success', {
|
||||
amount: ethAmount,
|
||||
});
|
||||
} else {
|
||||
await this.props.blockchain.convertWrappedEthTokensToEthAsync(etherToken.address, amountToConvert);
|
||||
const tokenAmount = Web3Wrapper.toUnitAmount(amountToConvert, etherToken.decimals);
|
||||
this.props.dispatcher.showFlashMessage(`Successfully unwrapped ${tokenAmount.toString()} WETH to ETH`);
|
||||
analytics.logEvent('Portal', 'Unwrap WETH Successfully', networkName);
|
||||
this.props.dispatcher.showFlashMessage(`Successfully unwrapped ${tokenAmount} WETH to ETH`);
|
||||
analytics.track('Unwrap WETH Success', {
|
||||
amount: tokenAmount,
|
||||
});
|
||||
}
|
||||
await this.props.refetchEthTokenStateAsync();
|
||||
this.props.onConversionSuccessful();
|
||||
@@ -214,10 +217,14 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
|
||||
logUtils.log(err.stack);
|
||||
if (this.props.direction === Side.Deposit) {
|
||||
this.props.dispatcher.showFlashMessage('Failed to wrap your ETH. Please try again.');
|
||||
analytics.logEvent('Portal', 'Wrap ETH Failed', networkName);
|
||||
analytics.track('Wrap ETH Failure', {
|
||||
amount: ethAmount,
|
||||
});
|
||||
} else {
|
||||
this.props.dispatcher.showFlashMessage('Failed to unwrap your WETH. Please try again.');
|
||||
analytics.logEvent('Portal', 'Unwrap WETH Failed', networkName);
|
||||
analytics.track('Unwrap WETH Failed', {
|
||||
amount: tokenAmount,
|
||||
});
|
||||
}
|
||||
await errorReporter.reportAsync(err);
|
||||
}
|
||||
|
@@ -74,10 +74,6 @@ const LazyEthereumTypesDocumentation = createLazyComponent('Documentation', asyn
|
||||
System.import<any>(/* webpackChunkName: "ethereumTypesDocs" */ 'ts/containers/ethereum_types_documentation'),
|
||||
);
|
||||
|
||||
analytics.init();
|
||||
// tslint:disable-next-line:no-floating-promises
|
||||
analytics.logProviderAsync((window as any).web3);
|
||||
|
||||
render(
|
||||
<Router>
|
||||
<div>
|
||||
|
@@ -516,8 +516,10 @@ export interface OutdatedWrappedEtherByNetworkId {
|
||||
};
|
||||
}
|
||||
|
||||
export interface ItemByAddress<T> {
|
||||
[address: string]: T;
|
||||
export type ItemByAddress<T> = ObjectMap<T>;
|
||||
|
||||
export interface ObjectMap<T> {
|
||||
[key: string]: T;
|
||||
}
|
||||
|
||||
export type TokenStateByAddress = ItemByAddress<TokenState>;
|
||||
|
@@ -1,27 +1,71 @@
|
||||
import * as _ from 'lodash';
|
||||
import * as ReactGA from 'react-ga';
|
||||
import { InjectedWeb3 } from 'ts/types';
|
||||
import { InjectedWeb3, ObjectMap, Order } from 'ts/types';
|
||||
import { configs } from 'ts/utils/configs';
|
||||
import { utils } from 'ts/utils/utils';
|
||||
|
||||
export const analytics = {
|
||||
init(): void {
|
||||
ReactGA.initialize(configs.GOOGLE_ANALYTICS_ID);
|
||||
},
|
||||
logEvent(category: string, action: string, label: string, value?: any): void {
|
||||
ReactGA.event({
|
||||
category,
|
||||
action,
|
||||
label,
|
||||
value,
|
||||
});
|
||||
},
|
||||
async logProviderAsync(web3IfExists: InjectedWeb3): Promise<void> {
|
||||
export interface HeapAnalytics {
|
||||
indentify(id: string, idType: string): void;
|
||||
track(eventName: string, eventProperties?: ObjectMap<string | number>): void;
|
||||
resetIdentity(): void;
|
||||
addUserProperties(properties: ObjectMap<string | number>): void;
|
||||
addEventProperties(properties: ObjectMap<string | number>): void;
|
||||
removeEventProperty(property: string): void;
|
||||
clearEventProperties(): void;
|
||||
}
|
||||
|
||||
export class Analytics implements HeapAnalytics {
|
||||
private _heap: HeapAnalytics;
|
||||
public static init(): Analytics {
|
||||
const heap = (window as any).heap;
|
||||
if (!_.isUndefined(heap)) {
|
||||
return new Analytics(heap);
|
||||
} else {
|
||||
throw new Error('Could not find the Heap SDK on the page.');
|
||||
}
|
||||
}
|
||||
constructor(heap: HeapAnalytics) {
|
||||
this._heap = heap;
|
||||
}
|
||||
// HeapAnalytics Wrappers
|
||||
public indentify(id: string, idType: string): void {
|
||||
this._heap.indentify(id, idType);
|
||||
}
|
||||
public track(eventName: string, eventProperties?: ObjectMap<string | number>): void {
|
||||
this._heap.track(eventName, eventProperties);
|
||||
}
|
||||
public resetIdentity(): void {
|
||||
this._heap.resetIdentity();
|
||||
}
|
||||
public addUserProperties(properties: ObjectMap<string | number>): void {
|
||||
this._heap.addUserProperties(properties);
|
||||
}
|
||||
public addEventProperties(properties: ObjectMap<string | number>): void {
|
||||
this._heap.addEventProperties(properties);
|
||||
}
|
||||
public removeEventProperty(property: string): void {
|
||||
this._heap.removeEventProperty(property);
|
||||
}
|
||||
public clearEventProperties(): void {
|
||||
this._heap.clearEventProperties();
|
||||
}
|
||||
// Custom methods
|
||||
public trackOrderEvent(eventName: string, order: Order): void {
|
||||
const orderLoggingData = {
|
||||
takerTokenAmount: order.signedOrder.takerTokenAmount,
|
||||
makeTokenAmount: order.signedOrder.makerTokenAmount,
|
||||
takerToken: order.metadata.takerToken.symbol,
|
||||
makerToken: order.metadata.makerToken.symbol,
|
||||
};
|
||||
this.track(eventName, orderLoggingData);
|
||||
}
|
||||
public async logProviderAsync(web3IfExists: InjectedWeb3): Promise<void> {
|
||||
await utils.onPageLoadAsync();
|
||||
const providerType =
|
||||
!_.isUndefined(web3IfExists) && !_.isUndefined(web3IfExists.currentProvider)
|
||||
? utils.getProviderType(web3IfExists.currentProvider)
|
||||
: 'NONE';
|
||||
ReactGA.ga('set', 'dimension1', providerType);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Assume heap library has loaded.
|
||||
export const analytics = Analytics.init();
|
||||
|
@@ -23,6 +23,7 @@ export const configs = {
|
||||
DOMAIN_PRODUCTION: '0xproject.com',
|
||||
ENVIRONMENT: isDevelopment ? Environments.DEVELOPMENT : Environments.PRODUCTION,
|
||||
GOOGLE_ANALYTICS_ID: 'UA-98720122-1',
|
||||
HEAP_APP_ID: '410099666',
|
||||
LAST_LOCAL_STORAGE_FILL_CLEARANCE_DATE: '2017-11-22',
|
||||
LAST_LOCAL_STORAGE_TRACKED_TOKEN_CLEARANCE_DATE: '2018-7-5',
|
||||
OUTDATED_WRAPPED_ETHERS: [
|
||||
|
@@ -34,6 +34,7 @@ export const constants = {
|
||||
PROVIDER_NAME_GENERIC: 'Injected Web3',
|
||||
PROVIDER_NAME_PUBLIC: '0x Public',
|
||||
ROLLBAR_ACCESS_TOKEN: '32c39bfa4bb6440faedc1612a9c13d28',
|
||||
HEAP_APP_ID: '410099666',
|
||||
S3_DOC_BUCKET_ROOT: 'https://s3.amazonaws.com/doc-jsons',
|
||||
S3_STAGING_DOC_BUCKET_ROOT: 'https://s3.amazonaws.com/staging-doc-jsons',
|
||||
SUCCESS_STATUS: 200,
|
||||
|
@@ -313,6 +313,7 @@ export const utils = {
|
||||
const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}`;
|
||||
return baseUrl;
|
||||
},
|
||||
// TODO: Fix this, it's a lie.
|
||||
async onPageLoadAsync(): Promise<void> {
|
||||
if (document.readyState === 'complete') {
|
||||
return; // Already loaded
|
||||
|
Reference in New Issue
Block a user