From 4a444591c11933a4dc2ee74b8eca1b4d7172362d Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 13 Nov 2018 17:14:13 +0100 Subject: Implement 0x launch kit landing page --- .../public/images/launch_kit/0x_cupboard.svg | 53 ++++ .../public/images/launch_kit/enable_trading.svg | 9 + packages/website/public/images/launch_kit/fork.svg | 4 + .../images/launch_kit/in_game_marketplace.svg | 11 + .../public/images/launch_kit/local_market.svg | 12 + .../public/images/launch_kit/secondary_market.svg | 6 + .../public/images/launch_kit/shared_liquidity.svg | 28 ++ packages/website/translations/chinese.json | 6 + packages/website/translations/english.json | 6 + packages/website/translations/korean.json | 6 + packages/website/translations/russian.json | 6 + packages/website/translations/spanish.json | 6 + packages/website/ts/components/footer.tsx | 6 +- packages/website/ts/components/ui/container.tsx | 2 + packages/website/ts/containers/launch_kit.ts | 27 ++ packages/website/ts/index.tsx | 2 + .../website/ts/pages/launch_kit/launch_kit.tsx | 297 +++++++++++++++++++++ packages/website/ts/types.ts | 7 + 18 files changed, 493 insertions(+), 1 deletion(-) create mode 100644 packages/website/public/images/launch_kit/0x_cupboard.svg create mode 100644 packages/website/public/images/launch_kit/enable_trading.svg create mode 100644 packages/website/public/images/launch_kit/fork.svg create mode 100644 packages/website/public/images/launch_kit/in_game_marketplace.svg create mode 100644 packages/website/public/images/launch_kit/local_market.svg create mode 100644 packages/website/public/images/launch_kit/secondary_market.svg create mode 100644 packages/website/public/images/launch_kit/shared_liquidity.svg create mode 100644 packages/website/ts/containers/launch_kit.ts create mode 100644 packages/website/ts/pages/launch_kit/launch_kit.tsx diff --git a/packages/website/public/images/launch_kit/0x_cupboard.svg b/packages/website/public/images/launch_kit/0x_cupboard.svg new file mode 100644 index 000000000..4c4e6ba1b --- /dev/null +++ b/packages/website/public/images/launch_kit/0x_cupboard.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/website/public/images/launch_kit/enable_trading.svg b/packages/website/public/images/launch_kit/enable_trading.svg new file mode 100644 index 000000000..84a081629 --- /dev/null +++ b/packages/website/public/images/launch_kit/enable_trading.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/website/public/images/launch_kit/fork.svg b/packages/website/public/images/launch_kit/fork.svg new file mode 100644 index 000000000..83d2f6d65 --- /dev/null +++ b/packages/website/public/images/launch_kit/fork.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/website/public/images/launch_kit/in_game_marketplace.svg b/packages/website/public/images/launch_kit/in_game_marketplace.svg new file mode 100644 index 000000000..853efe7ca --- /dev/null +++ b/packages/website/public/images/launch_kit/in_game_marketplace.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/packages/website/public/images/launch_kit/local_market.svg b/packages/website/public/images/launch_kit/local_market.svg new file mode 100644 index 000000000..05f7fd993 --- /dev/null +++ b/packages/website/public/images/launch_kit/local_market.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/website/public/images/launch_kit/secondary_market.svg b/packages/website/public/images/launch_kit/secondary_market.svg new file mode 100644 index 000000000..bc7d94f65 --- /dev/null +++ b/packages/website/public/images/launch_kit/secondary_market.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/website/public/images/launch_kit/shared_liquidity.svg b/packages/website/public/images/launch_kit/shared_liquidity.svg new file mode 100644 index 000000000..0647ecf0d --- /dev/null +++ b/packages/website/public/images/launch_kit/shared_liquidity.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/website/translations/chinese.json b/packages/website/translations/chinese.json index 95b9bda62..489b6b5ae 100644 --- a/packages/website/translations/chinese.json +++ b/packages/website/translations/chinese.json @@ -95,6 +95,12 @@ "LIBRARIES_AND_TOOLS_DESCRIPTION": "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", + "LAUNCH_KIT": "0x launch kit", + "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "GET_STARTED": "get started", + "GET_IN_TOUCH": "get in touch", + "EXPLORE_THE_DOCS": "explore the docs", + "LEARN_MORE": "learn more", "START_BUILDING_ON_0X": "Start building on 0x", "START_BUILDING_ON_0X_DESCRIPTION": "Follow one of our \"Getting started\" guides to learn more about building ontop of 0x." diff --git a/packages/website/translations/english.json b/packages/website/translations/english.json index 465bd49b4..02c7f2e8a 100644 --- a/packages/website/translations/english.json +++ b/packages/website/translations/english.json @@ -99,6 +99,12 @@ "LIBRARIES_AND_TOOLS_DESCRIPTION": "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", + "LAUNCH_KIT": "0x launch kit", + "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "GET_STARTED": "get started", + "GET_IN_TOUCH": "get in touch", + "EXPLORE_THE_DOCS": "explore the docs", + "LEARN_MORE": "learn more", "OUR_MISSION_AND_VALUES": "our mission & values", "GAMING_AND_COLLECTABLES": "gaming & collectables", "GAMING_AND_COLLECTABLES_DESCRIPTION": diff --git a/packages/website/translations/korean.json b/packages/website/translations/korean.json index 5485e5583..aa2a24c5b 100644 --- a/packages/website/translations/korean.json +++ b/packages/website/translations/korean.json @@ -95,6 +95,12 @@ "LIBRARIES_AND_TOOLS_DESCRIPTION": "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", + "LAUNCH_KIT": "0x launch kit", + "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "GET_STARTED": "get started", + "GET_IN_TOUCH": "get in touch", + "EXPLORE_THE_DOCS": "explore the docs", + "LEARN_MORE": "learn more", "START_BUILDING_ON_0X": "Start building on 0x", "START_BUILDING_ON_0X_DESCRIPTION": "Follow one of our \"Getting started\" guides to learn more about building ontop of 0x." diff --git a/packages/website/translations/russian.json b/packages/website/translations/russian.json index a2e2a8cef..6d35452ca 100644 --- a/packages/website/translations/russian.json +++ b/packages/website/translations/russian.json @@ -95,6 +95,12 @@ "LIBRARIES_AND_TOOLS_DESCRIPTION": "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", + "LAUNCH_KIT": "0x launch kit", + "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "GET_STARTED": "get started", + "GET_IN_TOUCH": "get in touch", + "EXPLORE_THE_DOCS": "explore the docs", + "LEARN_MORE": "learn more", "START_BUILDING_ON_0X": "Start building on 0x", "START_BUILDING_ON_0X_DESCRIPTION": "Follow one of our \"Getting started\" guides to learn more about building ontop of 0x." diff --git a/packages/website/translations/spanish.json b/packages/website/translations/spanish.json index acbc59c3d..31b9e1a7a 100644 --- a/packages/website/translations/spanish.json +++ b/packages/website/translations/spanish.json @@ -96,6 +96,12 @@ "LIBRARIES_AND_TOOLS_DESCRIPTION": "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", + "LAUNCH_KIT": "0x launch kit", + "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "GET_STARTED": "get started", + "GET_IN_TOUCH": "get in touch", + "EXPLORE_THE_DOCS": "explore the docs", + "LEARN_MORE": "learn more", "START_BUILDING_ON_0X": "Start building on 0x", "START_BUILDING_ON_0X_DESCRIPTION": "Follow one of our \"Getting started\" guides to learn more about building ontop of 0x." diff --git a/packages/website/ts/components/footer.tsx b/packages/website/ts/components/footer.tsx index dfedcba55..e10005a0a 100644 --- a/packages/website/ts/components/footer.tsx +++ b/packages/website/ts/components/footer.tsx @@ -23,6 +23,7 @@ const languageToMenuTitle = { export interface FooterProps { translate: Translate; dispatcher: Dispatcher; + backgroundColor?: string; } interface FooterState { @@ -30,6 +31,9 @@ interface FooterState { } export class Footer extends React.Component { + public static defaultProps = { + backgroundColor: colors.darkerGrey, + }; constructor(props: FooterProps) { super(props); this.state = { @@ -112,7 +116,7 @@ export class Footer extends React.Component { return ; }); return ( -
+
diff --git a/packages/website/ts/components/ui/container.tsx b/packages/website/ts/components/ui/container.tsx index ece077563..7eab2a50f 100644 --- a/packages/website/ts/components/ui/container.tsx +++ b/packages/website/ts/components/ui/container.tsx @@ -1,3 +1,4 @@ +import { TextAlignProperty } from 'csstype'; import * as React from 'react'; type StringOrNum = string | number; @@ -26,6 +27,7 @@ export interface ContainerProps { height?: StringOrNum; minWidth?: StringOrNum; minHeight?: StringOrNum; + textAlign?: TextAlignProperty; isHidden?: boolean; className?: string; position?: 'absolute' | 'fixed' | 'relative' | 'unset'; diff --git a/packages/website/ts/containers/launch_kit.ts b/packages/website/ts/containers/launch_kit.ts new file mode 100644 index 000000000..2557f38a5 --- /dev/null +++ b/packages/website/ts/containers/launch_kit.ts @@ -0,0 +1,27 @@ +import * as React from 'react'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; +import { LaunchKit as LaunchKitComponent, LaunchKitProps } from 'ts/pages/launch_kit/launch_kit'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { State } from 'ts/redux/reducer'; +import { Translate } from 'ts/utils/translate'; + +interface ConnectedState { + translate: Translate; +} + +interface ConnectedDispatch { + dispatcher: Dispatcher; +} + +const mapStateToProps = (state: State, _ownProps: LaunchKitProps): ConnectedState => ({ + translate: state.translate, +}); + +const mapDispatchToProps = (dispatch: Dispatch): ConnectedDispatch => ({ + dispatcher: new Dispatcher(dispatch), +}); + +export const LaunchKit: React.ComponentClass = connect(mapStateToProps, mapDispatchToProps)( + LaunchKitComponent, +); diff --git a/packages/website/ts/index.tsx b/packages/website/ts/index.tsx index 21157e427..96e7184f8 100644 --- a/packages/website/ts/index.tsx +++ b/packages/website/ts/index.tsx @@ -9,6 +9,7 @@ import { DocsHome } from 'ts/containers/docs_home'; import { FAQ } from 'ts/containers/faq'; import { Jobs } from 'ts/containers/jobs'; import { Landing } from 'ts/containers/landing'; +import { LaunchKit } from 'ts/containers/launch_kit'; import { NotFound } from 'ts/containers/not_found'; import { Wiki } from 'ts/containers/wiki'; import { createLazyComponent } from 'ts/lazy_component'; @@ -87,6 +88,7 @@ render( + diff --git a/packages/website/ts/pages/launch_kit/launch_kit.tsx b/packages/website/ts/pages/launch_kit/launch_kit.tsx new file mode 100644 index 000000000..7c3cc1c99 --- /dev/null +++ b/packages/website/ts/pages/launch_kit/launch_kit.tsx @@ -0,0 +1,297 @@ +import { colors, Link } from '@0x/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; +import DocumentTitle from 'react-document-title'; +import { Footer } from 'ts/components/footer'; +import { TopBar } from 'ts/components/top_bar/top_bar'; +import { Button } from 'ts/components/ui/button'; +import { Container } from 'ts/components/ui/container'; +import { Image } from 'ts/components/ui/image'; +import { Text } from 'ts/components/ui/text'; +import { Dispatcher } from 'ts/redux/dispatcher'; +import { Deco, Key, ScreenWidths, WebsitePaths } from 'ts/types'; +import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; +import { utils } from 'ts/utils/utils'; + +export interface LaunchKitProps { + location: Location; + translate: Translate; + dispatcher: Dispatcher; +} + +interface LaunchKitState { + screenWidth: ScreenWidths; +} + +const THROTTLE_TIMEOUT = 100; +const lighterBackgroundColor = '#222222'; +const darkerBackgroundColor = '#1B1B1B'; + +interface Benefit { + icon: string; + description: string; +} +const BENEFITS_1: Benefit[] = [ + { + icon: '/images/launch_kit/shared_liquidity.svg', + description: 'Tap into and share liquidity with other relayers', + }, + { + icon: '/images/launch_kit/fork.svg', + description: 'Fork and extend to support new modes of exchange', + }, + { + icon: '/images/launch_kit/enable_trading.svg', + description: 'Enable trading for any ERC-20 or ERC-721 asset', + }, +]; +const BENEFITS_2: Benefit[] = [ + { + icon: '/images/launch_kit/secondary_market.svg', + description: 'Quickly form a secondary market for your own token', + }, + { + icon: '/images/launch_kit/in_game_marketplace.svg', + description: 'Seamlessly create an in-game marketplace for digital items and collectables', + }, + { + icon: '/images/launch_kit/local_market.svg', + description: 'Easily build a 0x relayer for your local market', + }, +]; + +export class LaunchKit extends React.Component { + private readonly _throttledScreenWidthUpdate: () => void; + constructor(props: LaunchKitProps) { + super(props); + this.state = { + screenWidth: utils.getScreenWidth(), + }; + this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT); + } + public componentDidMount(): void { + window.addEventListener('resize', this._throttledScreenWidthUpdate); + window.scrollTo(0, 0); + } + public componentWillUnmount(): void { + window.removeEventListener('resize', this._throttledScreenWidthUpdate); + } + public render(): React.ReactNode { + return ( +
+ + + {this._renderHero()} + {this._renderSection()} + {this._renderCallToAction()} +
+
+ ); + } + private _renderHero(): React.ReactNode { + const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; + const smallButtonPadding = '12px 30px 12px 30px'; + const largeButtonPadding = '14px 60px 14px 60px'; + const left = 'col lg-col-6 md-col-6 col-12 lg-pl2 md-pl2 sm-pl0 sm-px3 sm-center'; + const flexClassName = isSmallScreen + ? 'flex items-center flex-column justify-center' + : 'flex items-center justify-center'; + return ( +
+
+
+
+
+ + {this.props.translate.get(Key.LaunchKit, Deco.CapWords)} + + + + {this.props.translate.get(Key.LaunchKitPitch, Deco.Cap)} + + + + + + + + +
+ + + +
+
+
+
+ + + +
+
; + {this._renderBenefits(BENEFITS_1)} +
+ ); + } + private _renderSection(): React.ReactNode { + return ( +
+ + + Perfect for developers who need simple exchange functionality + + + {this._renderBenefits(BENEFITS_2)} +
+ ); + } + private _renderCallToAction(): React.ReactNode { + const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; + const smallButtonPadding = '8px 14px 8px 14px'; + const largeButtonPadding = '8px 14px 8px 14px'; + return ( + + + + + View our comprehensive documentation to start building today. + + + + + + + + +
+ + + +
+
+
+
+ ); + } + private _renderBenefits(benefits: Benefit[]): React.ReactNode { + return ( + + {_.map(benefits, benefit => { + return ( + + + + + + + {benefit.description} + + + + ); + })} + + ); + } + private _updateScreenWidth(): void { + const newScreenWidth = utils.getScreenWidth(); + if (newScreenWidth !== this.state.screenWidth) { + this.setState({ + screenWidth: newScreenWidth, + }); + } + } +} diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index ce4b50a58..7065097d9 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -352,6 +352,7 @@ export enum WebsitePaths { Home = '/', FAQ = '/faq', About = '/about', + LaunchKit = '/launch-kit', Whitepaper = '/pdfs/0x_white_paper.pdf', SmartContracts = '/docs/contracts', Connect = '/docs/connect', @@ -479,6 +480,12 @@ export enum Key { More = 'MORE', StartBuildOn0x = 'START_BUILDING_ON_0X', StartBuildOn0xDescription = 'START_BUILDING_ON_0X_DESCRIPTION', + LaunchKit = 'LAUNCH_KIT', + LaunchKitPitch = 'LAUNCH_KIT_PITCH', + ExploreTheDocs = 'EXPLORE_THE_DOCS', + GetInTouch = 'GET_IN_TOUCH', + LearnMore = 'LEARN_MORE', + GetStarted = 'GET_STARTED', } export enum SmartContractDocSections { -- cgit v1.2.3 From 954fe3f549fcb171d7d16b5c048983ad524cd2fa Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 13 Nov 2018 17:14:21 +0100 Subject: update yarn.lock --- yarn.lock | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/yarn.lock b/yarn.lock index b23ec92d6..f33adb227 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1906,10 +1906,6 @@ aes-js@^0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-0.2.4.tgz#94b881ab717286d015fa219e08fb66709dda5a3d" -aes-js@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.1.tgz#89fd1f94ae51b4c72d62466adc1a7323ff52f072" - agent-base@4, agent-base@^4.1.0, agent-base@~4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" @@ -3347,7 +3343,7 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "^2.0.0" -bs58@=4.0.1, bs58@^4.0.0: +bs58@=4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" dependencies: @@ -3370,14 +3366,6 @@ bs58check@^1.0.8: bs58 "^3.1.0" create-hash "^1.1.0" -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - bser@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" @@ -5965,19 +5953,6 @@ ethereumjs-wallet@0.6.0: utf8 "^2.1.1" uuid "^2.0.1" -ethereumjs-wallet@~0.6.0: - version "0.6.2" - resolved "https://registry.yarnpkg.com/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz#67244b6af3e8113b53d709124b25477b64aeccda" - dependencies: - aes-js "^3.1.1" - bs58check "^2.1.2" - ethereumjs-util "^5.2.0" - hdkey "^1.0.0" - safe-buffer "^5.1.2" - scrypt.js "^0.2.0" - utf8 "^3.0.0" - uuid "^3.3.2" - ethers@~4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.4.tgz#d3f85e8b27f4b59537e06526439b0fb15b44dc65" @@ -7511,14 +7486,6 @@ hdkey@^0.7.0, hdkey@^0.7.1: coinstring "^2.0.0" secp256k1 "^3.0.1" -hdkey@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hdkey/-/hdkey-1.1.0.tgz#e74e7b01d2c47f797fa65d1d839adb7a44639f29" - dependencies: - coinstring "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" - he@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" @@ -15605,10 +15572,6 @@ utf8@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" -utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -- cgit v1.2.3 From 9b1ec5baaa6011d8d0034cb823aebd7ddfc80eb3 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 13 Nov 2018 21:00:37 +0100 Subject: Move benefits to language files and fix copy --- packages/website/translations/chinese.json | 9 +++- packages/website/translations/english.json | 9 +++- packages/website/translations/korean.json | 9 +++- packages/website/translations/russian.json | 9 +++- packages/website/translations/spanish.json | 9 +++- .../website/ts/pages/launch_kit/launch_kit.tsx | 60 +++++++++++----------- packages/website/ts/types.ts | 7 +++ 7 files changed, 78 insertions(+), 34 deletions(-) diff --git a/packages/website/translations/chinese.json b/packages/website/translations/chinese.json index 489b6b5ae..83ecef40e 100644 --- a/packages/website/translations/chinese.json +++ b/packages/website/translations/chinese.json @@ -96,10 +96,17 @@ "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", "LAUNCH_KIT": "0x launch kit", - "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "LAUNCH_KIT_PITCH": "launch a relayer in under a minute.", "GET_STARTED": "get started", "GET_IN_TOUCH": "get in touch", "EXPLORE_THE_DOCS": "explore the docs", + "LOCAL_MARKET": "Easily build a 0x relayer for your local market", + "SEEMLESSLY_CREATE": "Seamlessly create an in-game marketplace for digital items and collectables", + "QUICKLY_LAUNCH": "Quickly launch a market for your community token", + "ENABLE_TRADING": "Enable trading for any ERC-20 or ERC-721 asset", + "FORK_AND_EXTEND": "Fork and extend to support new modes of exchange", + "TAP_INTO_AND_SHARE": "Tap into and share liquidity with other relayers", + "PERFECT_FOR_DEVELOPERS": "Perfect for developers who need a simple drop-in marketplace", "LEARN_MORE": "learn more", "START_BUILDING_ON_0X": "Start building on 0x", "START_BUILDING_ON_0X_DESCRIPTION": diff --git a/packages/website/translations/english.json b/packages/website/translations/english.json index 02c7f2e8a..663587e6a 100644 --- a/packages/website/translations/english.json +++ b/packages/website/translations/english.json @@ -100,10 +100,17 @@ "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", "LAUNCH_KIT": "0x launch kit", - "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "LAUNCH_KIT_PITCH": "launch a relayer in under a minute.", "GET_STARTED": "get started", "GET_IN_TOUCH": "get in touch", "EXPLORE_THE_DOCS": "explore the docs", + "LOCAL_MARKET": "Easily build a 0x relayer for your local market", + "SEEMLESSLY_CREATE": "Seamlessly create an in-game marketplace for digital items and collectables", + "QUICKLY_LAUNCH": "Quickly launch a market for your community token", + "ENABLE_TRADING": "Enable trading for any ERC-20 or ERC-721 asset", + "FORK_AND_EXTEND": "Fork and extend to support new modes of exchange", + "TAP_INTO_AND_SHARE": "Tap into and share liquidity with other relayers", + "PERFECT_FOR_DEVELOPERS": "Perfect for developers who need a simple drop-in marketplace", "LEARN_MORE": "learn more", "OUR_MISSION_AND_VALUES": "our mission & values", "GAMING_AND_COLLECTABLES": "gaming & collectables", diff --git a/packages/website/translations/korean.json b/packages/website/translations/korean.json index aa2a24c5b..2ce7e52c4 100644 --- a/packages/website/translations/korean.json +++ b/packages/website/translations/korean.json @@ -96,10 +96,17 @@ "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", "LAUNCH_KIT": "0x launch kit", - "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "LAUNCH_KIT_PITCH": "launch a relayer in under a minute.", "GET_STARTED": "get started", "GET_IN_TOUCH": "get in touch", "EXPLORE_THE_DOCS": "explore the docs", + "LOCAL_MARKET": "Easily build a 0x relayer for your local market", + "SEEMLESSLY_CREATE": "Seamlessly create an in-game marketplace for digital items and collectables", + "QUICKLY_LAUNCH": "Quickly launch a market for your community token", + "ENABLE_TRADING": "Enable trading for any ERC-20 or ERC-721 asset", + "FORK_AND_EXTEND": "Fork and extend to support new modes of exchange", + "TAP_INTO_AND_SHARE": "Tap into and share liquidity with other relayers", + "PERFECT_FOR_DEVELOPERS": "Perfect for developers who need a simple drop-in marketplace", "LEARN_MORE": "learn more", "START_BUILDING_ON_0X": "Start building on 0x", "START_BUILDING_ON_0X_DESCRIPTION": diff --git a/packages/website/translations/russian.json b/packages/website/translations/russian.json index 6d35452ca..2bb047510 100644 --- a/packages/website/translations/russian.json +++ b/packages/website/translations/russian.json @@ -96,10 +96,17 @@ "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", "LAUNCH_KIT": "0x launch kit", - "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "LAUNCH_KIT_PITCH": "launch a relayer in under a minute.", "GET_STARTED": "get started", "GET_IN_TOUCH": "get in touch", "EXPLORE_THE_DOCS": "explore the docs", + "LOCAL_MARKET": "Easily build a 0x relayer for your local market", + "SEEMLESSLY_CREATE": "Seamlessly create an in-game marketplace for digital items and collectables", + "QUICKLY_LAUNCH": "Quickly launch a market for your community token", + "ENABLE_TRADING": "Enable trading for any ERC-20 or ERC-721 asset", + "FORK_AND_EXTEND": "Fork and extend to support new modes of exchange", + "TAP_INTO_AND_SHARE": "Tap into and share liquidity with other relayers", + "PERFECT_FOR_DEVELOPERS": "Perfect for developers who need a simple drop-in marketplace", "LEARN_MORE": "learn more", "START_BUILDING_ON_0X": "Start building on 0x", "START_BUILDING_ON_0X_DESCRIPTION": diff --git a/packages/website/translations/spanish.json b/packages/website/translations/spanish.json index 31b9e1a7a..88ea54c40 100644 --- a/packages/website/translations/spanish.json +++ b/packages/website/translations/spanish.json @@ -97,10 +97,17 @@ "A list of available tools maintained by the 0x core developers and wider community for building on top of 0x Protocol and Ethereum", "MORE": "more", "LAUNCH_KIT": "0x launch kit", - "LAUNCH_KIT_PITCH": "Launch an exchange in under a minute.", + "LAUNCH_KIT_PITCH": "launch a relayer in under a minute.", "GET_STARTED": "get started", "GET_IN_TOUCH": "get in touch", "EXPLORE_THE_DOCS": "explore the docs", + "LOCAL_MARKET": "Easily build a 0x relayer for your local market", + "SEEMLESSLY_CREATE": "Seamlessly create an in-game marketplace for digital items and collectables", + "QUICKLY_LAUNCH": "Quickly launch a market for your community token", + "ENABLE_TRADING": "Enable trading for any ERC-20 or ERC-721 asset", + "FORK_AND_EXTEND": "Fork and extend to support new modes of exchange", + "TAP_INTO_AND_SHARE": "Tap into and share liquidity with other relayers", + "PERFECT_FOR_DEVELOPERS": "Perfect for developers who need a simple drop-in marketplace", "LEARN_MORE": "learn more", "START_BUILDING_ON_0X": "Start building on 0x", "START_BUILDING_ON_0X_DESCRIPTION": diff --git a/packages/website/ts/pages/launch_kit/launch_kit.tsx b/packages/website/ts/pages/launch_kit/launch_kit.tsx index 7c3cc1c99..208e84b12 100644 --- a/packages/website/ts/pages/launch_kit/launch_kit.tsx +++ b/packages/website/ts/pages/launch_kit/launch_kit.tsx @@ -32,34 +32,6 @@ interface Benefit { icon: string; description: string; } -const BENEFITS_1: Benefit[] = [ - { - icon: '/images/launch_kit/shared_liquidity.svg', - description: 'Tap into and share liquidity with other relayers', - }, - { - icon: '/images/launch_kit/fork.svg', - description: 'Fork and extend to support new modes of exchange', - }, - { - icon: '/images/launch_kit/enable_trading.svg', - description: 'Enable trading for any ERC-20 or ERC-721 asset', - }, -]; -const BENEFITS_2: Benefit[] = [ - { - icon: '/images/launch_kit/secondary_market.svg', - description: 'Quickly form a secondary market for your own token', - }, - { - icon: '/images/launch_kit/in_game_marketplace.svg', - description: 'Seamlessly create an in-game marketplace for digital items and collectables', - }, - { - icon: '/images/launch_kit/local_market.svg', - description: 'Easily build a 0x relayer for your local market', - }, -]; export class LaunchKit extends React.Component { private readonly _throttledScreenWidthUpdate: () => void; @@ -100,6 +72,20 @@ export class LaunchKit extends React.Component { ); } private _renderHero(): React.ReactNode { + const BENEFITS_1: Benefit[] = [ + { + icon: '/images/launch_kit/shared_liquidity.svg', + description: this.props.translate.get(Key.TapIntoAndShare, Deco.Cap), + }, + { + icon: '/images/launch_kit/fork.svg', + description: this.props.translate.get(Key.ForkAndExtend, Deco.Cap), + }, + { + icon: '/images/launch_kit/enable_trading.svg', + description: this.props.translate.get(Key.EnableTrading, Deco.Cap), + }, + ]; const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm; const smallButtonPadding = '12px 30px 12px 30px'; const largeButtonPadding = '14px 60px 14px 60px'; @@ -190,6 +176,20 @@ export class LaunchKit extends React.Component { ); } private _renderSection(): React.ReactNode { + const BENEFITS_2: Benefit[] = [ + { + icon: '/images/launch_kit/secondary_market.svg', + description: this.props.translate.get(Key.QuicklyLaunch, Deco.Cap), + }, + { + icon: '/images/launch_kit/in_game_marketplace.svg', + description: this.props.translate.get(Key.SeemlesslyCreate, Deco.Cap), + }, + { + icon: '/images/launch_kit/local_market.svg', + description: this.props.translate.get(Key.LocalMarket, Deco.Cap), + }, + ]; return (
{ paddingTop="89px" paddingBottom="89px" maxWidth="421px" + paddingLeft="10px" + paddingRight="10px" > - Perfect for developers who need simple exchange functionality + {this.props.translate.get(Key.PerfectForDevelopers, Deco.CapWords)} {this._renderBenefits(BENEFITS_2)} diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 7065097d9..444a8348d 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -483,6 +483,13 @@ export enum Key { LaunchKit = 'LAUNCH_KIT', LaunchKitPitch = 'LAUNCH_KIT_PITCH', ExploreTheDocs = 'EXPLORE_THE_DOCS', + EnableTrading = 'ENABLE_TRADING', + ForkAndExtend = 'FORK_AND_EXTEND', + LocalMarket = 'LOCAL_MARKET', + SeemlesslyCreate = 'SEEMLESSLY_CREATE', + QuicklyLaunch = 'QUICKLY_LAUNCH', + TapIntoAndShare = 'TAP_INTO_AND_SHARE', + PerfectForDevelopers = 'PERFECT_FOR_DEVELOPERS', GetInTouch = 'GET_IN_TOUCH', LearnMore = 'LEARN_MORE', GetStarted = 'GET_STARTED', -- cgit v1.2.3 From 20ed4fbbd46f359ca1436b2d3b9d17527c01df54 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 15 Nov 2018 08:19:58 -0800 Subject: First pass on widget version of heap --- packages/instant/src/constants.ts | 1 + packages/instant/src/util/heap.ts | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 packages/instant/src/util/heap.ts diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 5bd2349b3..994be9788 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -16,6 +16,7 @@ export const BUY_QUOTE_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 15; export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.mul(6); export const DEFAULT_ESTIMATED_TRANSACTION_TIME_MS = ONE_MINUTE_MS * 2; export const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info'; +export const HEAP_ANALYTICS_DEVELOPMENT_APP_ID = '507265531'; export const COINBASE_API_BASE_URL = 'https://api.coinbase.com/v2'; export const PROGRESS_STALL_AT_WIDTH = '95%'; export const PROGRESS_FINISH_ANIMATION_TIME_MS = 200; diff --git a/packages/instant/src/util/heap.ts b/packages/instant/src/util/heap.ts new file mode 100644 index 000000000..399ac3f6f --- /dev/null +++ b/packages/instant/src/util/heap.ts @@ -0,0 +1,87 @@ +import { ObjectMap } from '@0x/types'; +import { logUtils } from '@0x/utils'; + +import { HEAP_ANALYTICS_DEVELOPMENT_APP_ID } from '../constants'; + +export interface HeapAnalytics { + loaded: boolean; + identify(id: string, idType: string): void; + track(eventName: string, eventProperties?: ObjectMap): void; + resetIdentity(): void; + addUserProperties(properties: ObjectMap): void; + addEventProperties(properties: ObjectMap): void; + removeEventProperty(property: string): void; + clearEventProperties(): void; +} +interface ModifiedWindow { + heap?: HeapAnalytics; + zeroExInstantLoadedHeap?: boolean; +} +const getWindow = (): ModifiedWindow => { + return window as ModifiedWindow; +}; +// Typescript-compatible version of https://docs.heapanalytics.com/docs/installation +const setupZeroExInstantHeap = () => { + /* tslint:disable */ + ((window as any).heap = (window as any).heap || []), + ((window as any).heap.load = function(e: any, t: any) { + ((window as any).heap.appid = e), ((window as any).heap.config = t = t || {}); + var r = t.forceSSL || 'https:' === (document.location as Location).protocol, + a = document.createElement('script'); + (a.type = 'text/javascript'), + (a.async = !0), + (a.src = (r ? 'https:' : 'http:') + '//cdn.heapanalytics.com/js/heap-' + e + '.js'); + var n = document.getElementsByTagName('script')[0]; + (n.parentNode as Node).insertBefore(a, n); + for ( + var o = function(e: any) { + return function() { + (window as any).heap.push([e].concat(Array.prototype.slice.call(arguments, 0))); + }; + }, + p = [ + 'addEventProperties', + 'addUserProperties', + 'clearEventProperties', + 'identify', + 'resetIdentity', + 'removeEventProperty', + 'setEventProperties', + 'track', + 'unsetEventProperty', + ], + c = 0; + c < p.length; + c++ + ) + (window as any).heap[p[c]] = o(p[c]); + }); + // TODO: use production heap id once environment utils merged + (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; +}; + +export const heapUtil = { + getHeap: (): HeapAnalytics | null => { + 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(); + }, +}; -- cgit v1.2.3 From 61f227e123218ba76a7fdf7fc2ee89171c2bf16c Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 15 Nov 2018 10:43:42 -0800 Subject: feat(instant): Heap middleware and first tracking events --- .../src/components/zero_ex_instant_container.tsx | 5 +++ packages/instant/src/redux/analytics_middleware.ts | 38 ++++++++++++++++++++++ packages/instant/src/redux/store.ts | 7 ++-- packages/instant/src/util/analytics.ts | 35 ++++++++++++++++++++ packages/instant/src/util/heap.ts | 13 ++++---- 5 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 packages/instant/src/redux/analytics_middleware.ts create mode 100644 packages/instant/src/util/analytics.ts diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 698bfef17..d977b0690 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -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 ); } + // tslint:disable-next-line:prefer-function-over-method + public componentDidMount(): void { + analytics.track('Widget - Opened'); + } private readonly _handleSymbolClick = (): void => { this.setState({ tokenSelectionPanelAnimationState: 'slidIn', diff --git a/packages/instant/src/redux/analytics_middleware.ts b/packages/instant/src/redux/analytics_middleware.ts new file mode 100644 index 000000000..8dd674e94 --- /dev/null +++ b/packages/instant/src/redux/analytics_middleware.ts @@ -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; +}; diff --git a/packages/instant/src/redux/store.ts b/packages/instant/src/redux/store.ts index 20710765d..54dfe58c4 100644 --- a/packages/instant/src/redux/store.ts +++ b/packages/instant/src/redux/store.ts @@ -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; @@ -9,6 +10,6 @@ export type Store = ReduxStore; export const store = { create: (initialState: State): Store => { const reducer = createReducer(initialState); - return createStore(reducer, initialState, devToolsEnhancer({})); + return createStore(reducer, initialState, composeWithDevTools(applyMiddleware(analyticsMiddleware))); }, }; diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts new file mode 100644 index 000000000..4de3e5eff --- /dev/null +++ b/packages/instant/src/util/analytics.ts @@ -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): void { + console.log('HEAP: tracking', eventName, eventProperties); + this._evaluteHeapCall(heap => heap.track(eventName, eventProperties)); + } + public addUserProperties(properties: ObjectMap): void { + console.log('HEAP: adding user properties', properties); + this._evaluteHeapCall(heap => heap.addUserProperties(properties)); + } + public addEventProperties(properties: ObjectMap): 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(); diff --git a/packages/instant/src/util/heap.ts b/packages/instant/src/util/heap.ts index 399ac3f6f..2f2c221b1 100644 --- a/packages/instant/src/util/heap.ts +++ b/packages/instant/src/util/heap.ts @@ -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(); }, }; -- cgit v1.2.3 From 2e61050a223a52b4b984034463887b0d579ce9b8 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 15 Nov 2018 10:48:20 -0800 Subject: Use pure functions instead of class --- packages/instant/src/util/analytics.ts | 51 ++++++++++++++++------------------ 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 4de3e5eff..3e2a996cf 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -3,33 +3,30 @@ 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): void { - console.log('HEAP: tracking', eventName, eventProperties); - this._evaluteHeapCall(heap => heap.track(eventName, eventProperties)); - } - public addUserProperties(properties: ObjectMap): void { - console.log('HEAP: adding user properties', properties); - this._evaluteHeapCall(heap => heap.addUserProperties(properties)); - } - public addEventProperties(properties: ObjectMap): 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); - } +const 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(); +export const analytics = { + addUserProperties: (properties: ObjectMap): void => { + console.log('HEAP: adding user properties', properties); + evaluteHeapCall(heap => heap.addUserProperties(properties)); + }, + addEventProperties: (properties: ObjectMap): void => { + console.log('HEAP: adding user properties', properties); + evaluteHeapCall(heap => heap.addEventProperties(properties)); + }, + track: (eventName: string, eventProperties?: ObjectMap): void => { + console.log('HEAP: tracking', eventName, eventProperties); + evaluteHeapCall(heap => heap.track(eventName, eventProperties)); + }, +}; -- cgit v1.2.3 From 0a38bf8fd6d2b98a84671a152cc380458d2e5e7e Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 15 Nov 2018 11:24:48 -0800 Subject: Report ETH in units --- packages/instant/src/redux/analytics_middleware.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/instant/src/redux/analytics_middleware.ts b/packages/instant/src/redux/analytics_middleware.ts index 8dd674e94..01be9b988 100644 --- a/packages/instant/src/redux/analytics_middleware.ts +++ b/packages/instant/src/redux/analytics_middleware.ts @@ -1,11 +1,14 @@ import { ObjectMap } from '@0x/types'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import { Middleware } from 'redux'; +import { ETH_DECIMALS } from '../constants'; +import { AccountState } from '../types'; 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 => { @@ -29,8 +32,11 @@ export const analyticsMiddleware: Middleware = store => next => middlewareAction curAccount.ethBalanceInWei && !_.isEqual(curAccount, prevAccount) ) { - const ethBalanceInWei = curAccount.ethBalanceInWei.toString(); - analytics.addUserProperties({ ethBalanceInWei }); + const ethBalanceInUnitAmount = Web3Wrapper.toUnitAmount( + curAccount.ethBalanceInWei, + ETH_DECIMALS, + ).toString(); + analytics.addUserProperties({ ethBalanceInUnitAmount }); } } -- cgit v1.2.3 From 450814ad80bb22332579e8ba54b58e1c06f34f71 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 15 Nov 2018 11:28:44 -0800 Subject: Introduce ANALYTICS_ENABLED constant --- packages/instant/src/constants.ts | 1 + packages/instant/src/util/analytics.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 994be9788..f46b0ca21 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -16,6 +16,7 @@ export const BUY_QUOTE_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 15; export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.mul(6); export const DEFAULT_ESTIMATED_TRANSACTION_TIME_MS = ONE_MINUTE_MS * 2; export const ETH_GAS_STATION_API_BASE_URL = 'https://ethgasstation.info'; +export const ANALYTICS_ENABLED = true; // TODO: change when we can switch on dev export const HEAP_ANALYTICS_DEVELOPMENT_APP_ID = '507265531'; export const COINBASE_API_BASE_URL = 'https://api.coinbase.com/v2'; export const PROGRESS_STALL_AT_WIDTH = '95%'; diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 3e2a996cf..6b6115abe 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -1,9 +1,15 @@ import { ObjectMap } from '@0x/types'; import { logUtils } from '@0x/utils'; +import { ANALYTICS_ENABLED } from '../constants'; + import { HeapAnalytics, heapUtil } from './heap'; const evaluteHeapCall = (heapFunctionCall: (heap: HeapAnalytics) => void): void => { + if (!ANALYTICS_ENABLED) { + return; + } + const curHeap = heapUtil.getHeap(); if (curHeap) { try { -- cgit v1.2.3 From ca9bb45327d2c5a8a83f2d261b134bf8489b3395 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 15 Nov 2018 11:29:11 -0800 Subject: Move where we track widget opened, and report on networkId and providerName --- packages/instant/src/components/zero_ex_instant_container.tsx | 4 ---- packages/instant/src/components/zero_ex_instant_provider.tsx | 10 ++++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index d977b0690..8c3bdc6b6 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -69,10 +69,6 @@ export class ZeroExInstantContainer extends React.Component<{}, ZeroExInstantCon ); } - // tslint:disable-next-line:prefer-function-over-method - public componentDidMount(): void { - analytics.track('Widget - Opened'); - } private readonly _handleSymbolClick = (): void => { this.setState({ tokenSelectionPanelAnimationState: 'slidIn', diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index 18e71edb6..c187f98ee 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -13,6 +13,7 @@ import { store, Store } from '../redux/store'; import { fonts } from '../style/fonts'; import { AccountState, AffiliateInfo, AssetMetaData, Network, OrderSource } from '../types'; import { assetUtils } from '../util/asset'; +import { analytics } from '../util/analytics'; import { errorFlasher } from '../util/error_flasher'; import { gasPriceEstimator } from '../util/gas_price_estimator'; import { Heartbeater } from '../util/heartbeater'; @@ -120,6 +121,15 @@ export class ZeroExInstantProvider extends React.Component Date: Thu, 15 Nov 2018 11:33:04 -0800 Subject: Take out console.logs --- packages/instant/src/util/analytics.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 6b6115abe..dd595529d 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -24,15 +24,12 @@ const evaluteHeapCall = (heapFunctionCall: (heap: HeapAnalytics) => void): void export const analytics = { addUserProperties: (properties: ObjectMap): void => { - console.log('HEAP: adding user properties', properties); evaluteHeapCall(heap => heap.addUserProperties(properties)); }, addEventProperties: (properties: ObjectMap): void => { - console.log('HEAP: adding user properties', properties); evaluteHeapCall(heap => heap.addEventProperties(properties)); }, track: (eventName: string, eventProperties?: ObjectMap): void => { - console.log('HEAP: tracking', eventName, eventProperties); evaluteHeapCall(heap => heap.track(eventName, eventProperties)); }, }; -- cgit v1.2.3 From 71aeb7cddcd2a1faf7a4dc46d828ad8471019f37 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 15 Nov 2018 11:35:47 -0800 Subject: Linting --- packages/instant/src/components/zero_ex_instant_container.tsx | 1 - packages/instant/src/components/zero_ex_instant_provider.tsx | 2 +- packages/instant/src/redux/analytics_middleware.ts | 1 - packages/instant/src/redux/store.ts | 2 +- packages/instant/src/util/heap.ts | 1 - 5 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 8c3bdc6b6..698bfef17 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -10,7 +10,6 @@ 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'; diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index c187f98ee..cfc542a59 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -12,8 +12,8 @@ import { DEFAULT_STATE, DefaultState, State } from '../redux/reducer'; import { store, Store } from '../redux/store'; import { fonts } from '../style/fonts'; import { AccountState, AffiliateInfo, AssetMetaData, Network, OrderSource } from '../types'; -import { assetUtils } from '../util/asset'; import { analytics } from '../util/analytics'; +import { assetUtils } from '../util/asset'; import { errorFlasher } from '../util/error_flasher'; import { gasPriceEstimator } from '../util/gas_price_estimator'; import { Heartbeater } from '../util/heartbeater'; diff --git a/packages/instant/src/redux/analytics_middleware.ts b/packages/instant/src/redux/analytics_middleware.ts index 01be9b988..2b3ebf529 100644 --- a/packages/instant/src/redux/analytics_middleware.ts +++ b/packages/instant/src/redux/analytics_middleware.ts @@ -1,4 +1,3 @@ -import { ObjectMap } from '@0x/types'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import { Middleware } from 'redux'; diff --git a/packages/instant/src/redux/store.ts b/packages/instant/src/redux/store.ts index 54dfe58c4..11bba3876 100644 --- a/packages/instant/src/redux/store.ts +++ b/packages/instant/src/redux/store.ts @@ -1,6 +1,6 @@ import * as _ from 'lodash'; import { applyMiddleware, createStore, Store as ReduxStore } from 'redux'; -import { composeWithDevTools, devToolsEnhancer } from 'redux-devtools-extension/developmentOnly'; +import { composeWithDevTools } from 'redux-devtools-extension/developmentOnly'; import { analyticsMiddleware } from './analytics_middleware'; import { createReducer, State } from './reducer'; diff --git a/packages/instant/src/util/heap.ts b/packages/instant/src/util/heap.ts index 2f2c221b1..6d3c75ea7 100644 --- a/packages/instant/src/util/heap.ts +++ b/packages/instant/src/util/heap.ts @@ -1,5 +1,4 @@ import { ObjectMap } from '@0x/types'; -import { logUtils } from '@0x/utils'; import { HEAP_ANALYTICS_DEVELOPMENT_APP_ID } from '../constants'; -- cgit v1.2.3 From fd4a782bdd5e3e87e731d5288eb1bafa402295bc Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Thu, 15 Nov 2018 20:47:11 +0000 Subject: Update call-to-action links --- packages/website/ts/pages/launch_kit/launch_kit.tsx | 8 ++++---- packages/website/ts/utils/constants.ts | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/website/ts/pages/launch_kit/launch_kit.tsx b/packages/website/ts/pages/launch_kit/launch_kit.tsx index 208e84b12..1e798f093 100644 --- a/packages/website/ts/pages/launch_kit/launch_kit.tsx +++ b/packages/website/ts/pages/launch_kit/launch_kit.tsx @@ -127,7 +127,7 @@ export class LaunchKit extends React.Component { className={`flex clearfix sm-mx-auto ${isSmallScreen ? 'justify-center' : ''}`} > - +