aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website
diff options
context:
space:
mode:
authorfragosti <francesco.agosti93@gmail.com>2018-07-12 03:14:23 +0800
committerfragosti <francesco.agosti93@gmail.com>2018-07-12 03:14:23 +0800
commit9131a72a47690912db9b536186d05120daabd115 (patch)
treeedbf0fb3b572a9422410b6fac9f47c103c1c0218 /packages/website
parentd319b53e23047d4ff62415555475ef6da5f3d774 (diff)
downloaddexon-sol-tools-9131a72a47690912db9b536186d05120daabd115.tar
dexon-sol-tools-9131a72a47690912db9b536186d05120daabd115.tar.gz
dexon-sol-tools-9131a72a47690912db9b536186d05120daabd115.tar.bz2
dexon-sol-tools-9131a72a47690912db9b536186d05120daabd115.tar.lz
dexon-sol-tools-9131a72a47690912db9b536186d05120daabd115.tar.xz
dexon-sol-tools-9131a72a47690912db9b536186d05120daabd115.tar.zst
dexon-sol-tools-9131a72a47690912db9b536186d05120daabd115.zip
Replace calls to google analytics with calls to heap
Diffstat (limited to 'packages/website')
-rw-r--r--packages/website/package.json10
-rw-r--r--packages/website/ts/components/fill_order.tsx14
-rw-r--r--packages/website/ts/components/generate_order/generate_order_form.tsx36
-rw-r--r--packages/website/ts/components/inputs/allowance_toggle.tsx10
-rw-r--r--packages/website/ts/components/onboarding/portal_onboarding_flow.tsx15
-rw-r--r--packages/website/ts/components/portal/portal.tsx6
-rw-r--r--packages/website/ts/components/relayer_index/relayer_grid_tile.tsx6
-rw-r--r--packages/website/ts/components/relayer_index/relayer_top_tokens.tsx6
-rw-r--r--packages/website/ts/components/wallet/wallet.tsx4
-rw-r--r--packages/website/ts/components/wallet/wrap_ether_item.tsx29
-rw-r--r--packages/website/ts/index.tsx4
-rw-r--r--packages/website/ts/types.ts6
-rw-r--r--packages/website/ts/utils/analytics.ts80
-rw-r--r--packages/website/ts/utils/configs.ts1
-rw-r--r--packages/website/ts/utils/constants.ts1
-rw-r--r--packages/website/ts/utils/utils.ts1
16 files changed, 147 insertions, 82 deletions
diff --git a/packages/website/package.json b/packages/website/package.json
index b5b4b6119..3e48a3a26 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -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",
diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx
index 03ba1183d..46e33061f 100644
--- a/packages/website/ts/components/fill_order.tsx
+++ b/packages/website/ts/components/fill_order.tsx
@@ -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({
diff --git a/packages/website/ts/components/generate_order/generate_order_form.tsx b/packages/website/ts/components/generate_order/generate_order_form.tsx
index d26b5c3fa..53fb3fc91 100644
--- a/packages/website/ts/components/generate_order/generate_order_form.tsx
+++ b/packages/website/ts/components/generate_order/generate_order_form.tsx
@@ -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)) {
diff --git a/packages/website/ts/components/inputs/allowance_toggle.tsx b/packages/website/ts/components/inputs/allowance_toggle.tsx
index 0d5995696..b3f1aead2 100644
--- a/packages/website/ts/components/inputs/allowance_toggle.tsx
+++ b/packages/website/ts/components/inputs/allowance_toggle.tsx
@@ -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,
});
diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx
index 20a8f0a32..63b98cee7 100644
--- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx
+++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx
@@ -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);
diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index f983241fa..2e02f42f6 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -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 {
diff --git a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx
index 431cf145b..2eb04f2d6 100644
--- a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx
@@ -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;
diff --git a/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx
index c48b672e9..883c8d81b 100644
--- a/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx
@@ -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);
};
diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index 6c1c495d7..940cd6c58 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -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,
});
diff --git a/packages/website/ts/components/wallet/wrap_ether_item.tsx b/packages/website/ts/components/wallet/wrap_ether_item.tsx
index 2b4cf93fe..01d9bdb66 100644
--- a/packages/website/ts/components/wallet/wrap_ether_item.tsx
+++ b/packages/website/ts/components/wallet/wrap_ether_item.tsx
@@ -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);
}
diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx
index c7ccfdf1f..aba72f52a 100644
--- a/packages/website/ts/index.tsx
+++ b/packages/website/ts/index.tsx
@@ -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>
diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts
index e8dc694f6..f107b3b5e 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -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>;
diff --git a/packages/website/ts/utils/analytics.ts b/packages/website/ts/utils/analytics.ts
index f4bfa083f..9a1684813 100644
--- a/packages/website/ts/utils/analytics.ts
+++ b/packages/website/ts/utils/analytics.ts
@@ -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();
diff --git a/packages/website/ts/utils/configs.ts b/packages/website/ts/utils/configs.ts
index 97aabd13d..a2fd6a47e 100644
--- a/packages/website/ts/utils/configs.ts
+++ b/packages/website/ts/utils/configs.ts
@@ -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: [
diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts
index e43f541bf..d52b9b392 100644
--- a/packages/website/ts/utils/constants.ts
+++ b/packages/website/ts/utils/constants.ts
@@ -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,
diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts
index 8c76a7592..df7f8d10f 100644
--- a/packages/website/ts/utils/utils.ts
+++ b/packages/website/ts/utils/utils.ts
@@ -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