From f8b925c9adcc9fecf237d29e002fe993ca4f41a8 Mon Sep 17 00:00:00 2001 From: fragosti Date: Thu, 29 Nov 2018 14:10:12 -0800 Subject: feat: move instant base config to types file --- .../src/components/zero_ex_instant_provider.tsx | 21 ++------------------- packages/instant/src/types.ts | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index dae9124c6..780190257 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -11,7 +11,7 @@ import { asyncData } from '../redux/async_data'; 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, QuoteFetchOrigin } from '../types'; +import { AccountState, AffiliateInfo, AssetMetaData, Network, ZeroExInstantBaseConfig } from '../types'; import { analytics, disableAnalytics } from '../util/analytics'; import { assetUtils } from '../util/asset'; import { errorFlasher } from '../util/error_flasher'; @@ -21,24 +21,7 @@ import { Heartbeater } from '../util/heartbeater'; import { generateAccountHeartbeater, generateBuyQuoteHeartbeater } from '../util/heartbeater_factory'; import { providerStateFactory } from '../util/provider_state_factory'; -export type ZeroExInstantProviderProps = ZeroExInstantProviderRequiredProps & - Partial; - -export interface ZeroExInstantProviderRequiredProps { - orderSource: OrderSource; -} - -export interface ZeroExInstantProviderOptionalProps { - provider: Provider; - walletDisplayName: string; - availableAssetDatas: string[]; - defaultAssetBuyAmount: number; - defaultSelectedAssetData: string; - additionalAssetMetaDataMap: ObjectMap; - networkId: Network; - affiliateInfo: AffiliateInfo; - shouldDisableAnalyticsTracking: boolean; -} +export type ZeroExInstantProviderProps = ZeroExInstantBaseConfig; export class ZeroExInstantProvider extends React.Component { private readonly _store: Store; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 2d73ba29e..b11d02e15 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -177,3 +177,20 @@ export enum ProviderType { Cipher = 'CIPHER', Fallback = 'FALLBACK', } + +export interface ZeroExInstantRequiredBaseConfig { + orderSource: OrderSource; +} + +export interface ZeroExInstantOptionalBaseConfig { + provider: Provider; + availableAssetDatas: string[]; + defaultAssetBuyAmount: number; + defaultSelectedAssetData: string; + additionalAssetMetaDataMap: ObjectMap; + networkId: Network; + affiliateInfo: AffiliateInfo; + shouldDisableAnalyticsTracking: boolean; +} + +export type ZeroExInstantBaseConfig = ZeroExInstantRequiredBaseConfig & Partial; -- cgit From 7b81bd831fb4b43380ba4bc256d154ab0b5f8fca Mon Sep 17 00:00:00 2001 From: fragosti Date: Tue, 4 Dec 2018 14:11:28 -0800 Subject: fix: instant linting issues --- packages/instant/src/components/zero_ex_instant_provider.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index 780190257..8b75cdfc4 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -1,6 +1,4 @@ -import { ObjectMap } from '@0x/types'; import { BigNumber } from '@0x/utils'; -import { Provider } from 'ethereum-types'; import * as _ from 'lodash'; import * as React from 'react'; import { Provider as ReduxProvider } from 'react-redux'; @@ -11,7 +9,12 @@ import { asyncData } from '../redux/async_data'; import { DEFAULT_STATE, DefaultState, State } from '../redux/reducer'; import { store, Store } from '../redux/store'; import { fonts } from '../style/fonts'; -import { AccountState, AffiliateInfo, AssetMetaData, Network, ZeroExInstantBaseConfig } from '../types'; +import { + AccountState, + Network, + QuoteFetchOrigin, + ZeroExInstantBaseConfig, +} from '../types'; import { analytics, disableAnalytics } from '../util/analytics'; import { assetUtils } from '../util/asset'; import { errorFlasher } from '../util/error_flasher'; -- cgit From 5acf053f8b8831f466c4605f7814cddd9dc3ec6b Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 5 Dec 2018 09:45:23 -0800 Subject: Use dotenv in development --- packages/instant/package.json | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/package.json b/packages/instant/package.json index 7d0bf6bec..9303276b4 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -10,7 +10,7 @@ "scripts": { "build": "webpack --mode production", "build:ci": "yarn build", - "dev": "webpack-dev-server --mode development", + "dev": "dotenv webpack-dev-server -- --mode development", "lint": "tslint --format stylish --project .", "test": "jest", "test:coverage": "jest --coverage", @@ -24,10 +24,7 @@ }, "config": { "postpublish": { - "assets": [ - "packages/instant/umd/instant.js", - "packages/instant/umd/instant.js.map" - ] + "assets": ["packages/instant/umd/instant.js", "packages/instant/umd/instant.js.map"] } }, "repository": { -- cgit From 37e3f481dd8b2ca68c031ac3e9ad5cae90595466 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 5 Dec 2018 09:45:34 -0800 Subject: Only include localhost in host domains if in development mode --- packages/instant/src/constants.ts | 7 +++---- packages/instant/src/util/analytics.ts | 4 ++-- packages/instant/src/util/error_reporter.ts | 24 +++++++++++++++++++++--- 3 files changed, 26 insertions(+), 9 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 506348092..f83eb4ac7 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -15,6 +15,7 @@ export const GWEI_IN_WEI = new BigNumber(1000000000); export const ONE_SECOND_MS = 1000; export const ONE_MINUTE_MS = ONE_SECOND_MS * 60; export const GIT_SHA = process.env.GIT_SHA; +export const NODE_ENV = process.env.NODE_ENV; export const NPM_PACKAGE_VERSION = process.env.NPM_PACKAGE_VERSION; export const ACCOUNT_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 5; export const BUY_QUOTE_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 15; @@ -28,14 +29,12 @@ export const HEAP_ENABLED = process.env.HEAP_ENABLED; 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; -export const HOST_DOMAINS = [ +export const HOST_DOMAINS_EXTERNAL = [ '0x-instant-staging.s3-website-us-east-1.amazonaws.com', '0x-instant-dogfood.s3-website-us-east-1.amazonaws.com', - 'localhost', - '127.0.0.1', - '0.0.0.0', 'instant.0xproject.com', ]; +export const HOST_DOMAINS_LOCAL = ['localhost', '127.0.0.1', '0.0.0.0']; export const ROLLBAR_CLIENT_TOKEN = process.env.ROLLBAR_CLIENT_TOKEN; export const ROLLBAR_ENABLED = process.env.ROLLBAR_ENABLED; export const INSTANT_DISCHARGE_TARGET = process.env.INSTANT_DISCHARGE_TARGET as diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index 6da37bedb..6da52db16 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -2,7 +2,7 @@ import { BuyQuote } from '@0x/asset-buyer'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; -import { GIT_SHA, HEAP_ENABLED, INSTANT_DISCHARGE_TARGET, NPM_PACKAGE_VERSION } from '../constants'; +import { GIT_SHA, HEAP_ENABLED, INSTANT_DISCHARGE_TARGET, NODE_ENV, NPM_PACKAGE_VERSION } from '../constants'; import { AffiliateInfo, Asset, @@ -156,7 +156,7 @@ export const analytics = { affiliateFeePercent, selectedAssetName: selectedAsset ? selectedAsset.metaData.name : 'none', selectedAssetData: selectedAsset ? selectedAsset.assetData : 'none', - instantEnvironment: INSTANT_DISCHARGE_TARGET || `Local ${process.env.NODE_ENV}`, + instantEnvironment: INSTANT_DISCHARGE_TARGET || `Local ${NODE_ENV}`, }; return eventOptions; }, diff --git a/packages/instant/src/util/error_reporter.ts b/packages/instant/src/util/error_reporter.ts index b1824eaf9..ec074c440 100644 --- a/packages/instant/src/util/error_reporter.ts +++ b/packages/instant/src/util/error_reporter.ts @@ -1,17 +1,35 @@ import { logUtils } from '@0x/utils'; import * as _ from 'lodash'; -import { GIT_SHA, HOST_DOMAINS, INSTANT_DISCHARGE_TARGET, ROLLBAR_CLIENT_TOKEN, ROLLBAR_ENABLED } from '../constants'; +import { + GIT_SHA, + HOST_DOMAINS_EXTERNAL, + HOST_DOMAINS_LOCAL, + INSTANT_DISCHARGE_TARGET, + NODE_ENV, + ROLLBAR_CLIENT_TOKEN, + ROLLBAR_ENABLED, +} from '../constants'; // Import version of Rollbar designed for embedded components // See https://docs.rollbar.com/docs/using-rollbarjs-inside-an-embedded-component // tslint:disable-next-line:no-var-requires const Rollbar = require('rollbar/dist/rollbar.noconflict.umd'); +const getRollbarHostDomains = (): string[] => { + if (NODE_ENV === 'development') { + return HOST_DOMAINS_EXTERNAL.concat(HOST_DOMAINS_LOCAL); + } else { + return HOST_DOMAINS_EXTERNAL; + } +}; + let rollbar: any; // Configures rollbar and sets up error catching export const setupRollbar = (): any => { if (_.isUndefined(rollbar) && ROLLBAR_CLIENT_TOKEN && ROLLBAR_ENABLED) { + const hostDomains = getRollbarHostDomains(); + console.log('hostDomains', hostDomains); rollbar = new Rollbar({ accessToken: ROLLBAR_CLIENT_TOKEN, captureUncaught: true, @@ -20,7 +38,7 @@ export const setupRollbar = (): any => { itemsPerMinute: 10, maxItems: 500, payload: { - environment: INSTANT_DISCHARGE_TARGET || `Local ${process.env.NODE_ENV}`, + environment: INSTANT_DISCHARGE_TARGET || `Local ${NODE_ENV}`, client: { javascript: { source_map_enabled: true, @@ -29,7 +47,7 @@ export const setupRollbar = (): any => { }, }, }, - hostWhiteList: HOST_DOMAINS, + hostWhiteList: hostDomains, uncaughtErrorLevel: 'error', ignoredMessages: [ // Errors from the third-party scripts -- cgit From 43d1f61d283f318eb20fb92f3a8f5c0c4cdc1a94 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 5 Dec 2018 10:17:18 -0800 Subject: Takeout console.log --- packages/instant/src/util/error_reporter.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/util/error_reporter.ts b/packages/instant/src/util/error_reporter.ts index ec074c440..8d7481684 100644 --- a/packages/instant/src/util/error_reporter.ts +++ b/packages/instant/src/util/error_reporter.ts @@ -29,7 +29,6 @@ let rollbar: any; export const setupRollbar = (): any => { if (_.isUndefined(rollbar) && ROLLBAR_CLIENT_TOKEN && ROLLBAR_ENABLED) { const hostDomains = getRollbarHostDomains(); - console.log('hostDomains', hostDomains); rollbar = new Rollbar({ accessToken: ROLLBAR_CLIENT_TOKEN, captureUncaught: true, -- cgit From b39f51175572fc78d718af8bfdc4a30e183fdcde Mon Sep 17 00:00:00 2001 From: fragosti Date: Wed, 5 Dec 2018 11:39:10 -0800 Subject: fix: input placeholder css specificity increase --- packages/instant/src/components/ui/input.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/ui/input.tsx b/packages/instant/src/components/ui/input.tsx index 863c970ef..62c70f9e1 100644 --- a/packages/instant/src/components/ui/input.tsx +++ b/packages/instant/src/components/ui/input.tsx @@ -29,8 +29,8 @@ export const Input = outline: none; border: none; &::placeholder { - color: ${props => props.theme[props.fontColor || 'white']}; - opacity: 0.5; + color: ${props => props.theme[props.fontColor || 'white']} !important; + opacity: 0.5 !important; } } `; -- cgit From b6e79fd9e038a77f614979bfa7ee20174ad638d7 Mon Sep 17 00:00:00 2001 From: fragosti Date: Wed, 5 Dec 2018 11:52:27 -0800 Subject: fix: call toLowerCase in asset creation logic --- packages/instant/src/util/asset.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts index 08f3642e3..13f84ef74 100644 --- a/packages/instant/src/util/asset.ts +++ b/packages/instant/src/util/asset.ts @@ -26,7 +26,7 @@ export const assetUtils = { return; } return { - assetData, + assetData: assetData.toLowerCase(), metaData, }; }, @@ -36,7 +36,7 @@ export const assetUtils = { network: Network, ): Asset => { return { - assetData, + assetData: assetData.toLowerCase(), metaData: assetUtils.getMetaDataOrThrow(assetData, assetMetaDataMap, network), }; }, -- cgit From f8f3a3b3cc1dd92b5ba28ae46d10f61d9e589eb5 Mon Sep 17 00:00:00 2001 From: fragosti Date: Wed, 5 Dec 2018 11:56:54 -0800 Subject: chore: add coingecko css example to externall.css --- packages/instant/public/external.css | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'packages/instant') diff --git a/packages/instant/public/external.css b/packages/instant/public/external.css index cab11112a..21278577e 100644 --- a/packages/instant/public/external.css +++ b/packages/instant/public/external.css @@ -15,6 +15,10 @@ input { height: 100px; } +input::-webkit-input-placeholder { + color: #b4b4b4 !important; +} + div { padding: 3px; } -- cgit From 7ba47c47bb33f9b7569a744600169d0cec2fee18 Mon Sep 17 00:00:00 2001 From: fragosti Date: Wed, 5 Dec 2018 12:16:55 -0800 Subject: feat: lowercase keys in additionalAssetMetaDataMap --- packages/instant/src/components/zero_ex_instant_provider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index 8b75cdfc4..e899b82fe 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -46,7 +46,8 @@ export class ZeroExInstantProvider extends React.Component key.toLowerCase()), ...defaultState.assetMetaDataMap, }; // construct the final state -- cgit From b586ecdf92ae3823ebf07338bab80eb3e734db47 Mon Sep 17 00:00:00 2001 From: fragosti Date: Wed, 5 Dec 2018 13:04:42 -0800 Subject: chore: run prettier --- packages/instant/src/components/zero_ex_instant_provider.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index e899b82fe..7ae27de23 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -9,12 +9,7 @@ import { asyncData } from '../redux/async_data'; import { DEFAULT_STATE, DefaultState, State } from '../redux/reducer'; import { store, Store } from '../redux/store'; import { fonts } from '../style/fonts'; -import { - AccountState, - Network, - QuoteFetchOrigin, - ZeroExInstantBaseConfig, -} from '../types'; +import { AccountState, Network, QuoteFetchOrigin, ZeroExInstantBaseConfig } from '../types'; import { analytics, disableAnalytics } from '../util/analytics'; import { assetUtils } from '../util/asset'; import { errorFlasher } from '../util/error_flasher'; -- cgit From 506c736d4fffef0109c693c36922c573a59ccc78 Mon Sep 17 00:00:00 2001 From: fragosti Date: Wed, 5 Dec 2018 16:18:34 -0800 Subject: fix: remove target=_blank from instant link --- packages/instant/.DS_Store | Bin 8196 -> 8196 bytes 1 file changed, 0 insertions(+), 0 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/.DS_Store b/packages/instant/.DS_Store index 9a0cceca6..c86c5cbcd 100644 Binary files a/packages/instant/.DS_Store and b/packages/instant/.DS_Store differ -- cgit From ae6f7cc4544eaa8c3bbc384d75eec0ba30a2377d Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 5 Dec 2018 17:47:25 -0800 Subject: feat(instant): More aggressive error reporting --- packages/instant/src/util/buy_quote_updater.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts index 4229f2735..6191c92e3 100644 --- a/packages/instant/src/util/buy_quote_updater.ts +++ b/packages/instant/src/util/buy_quote_updater.ts @@ -38,14 +38,11 @@ export const buyQuoteUpdater = { } catch (error) { const errorMessage = assetUtils.assetBuyerErrorMessage(asset, error); - if (_.isUndefined(errorMessage)) { - // This is an unknown error, report it to rollbar - errorReporter.report(error); - } + errorReporter.report(error); + analytics.trackQuoteError(error.message ? error.message : 'other', baseUnitValue, fetchOrigin); if (options.dispatchErrors) { dispatch(actions.setQuoteRequestStateFailure()); - analytics.trackQuoteError(error.message ? error.message : 'other', baseUnitValue, fetchOrigin); errorFlasher.flashNewErrorMessage(dispatch, errorMessage || 'Error fetching price, please try again'); } return; -- cgit From 5cbe04acab982ead39f7794547de0f045952a1b7 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 7 Dec 2018 11:14:55 -0800 Subject: feat(instant): ETH/USD toggle --- packages/instant/src/components/order_details.tsx | 196 +++++++++++++++++---- .../containers/latest_buy_quote_order_details.ts | 33 ++-- packages/instant/src/redux/actions.ts | 4 +- packages/instant/src/redux/reducer.ts | 8 + packages/instant/src/types.ts | 5 + packages/instant/src/util/buy_quote.ts | 71 ++++++++ 6 files changed, 269 insertions(+), 48 deletions(-) create mode 100644 packages/instant/src/util/buy_quote.ts (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index a8e0e2513..85761a5b9 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -6,63 +6,92 @@ import { oc } from 'ts-optchain'; import { BIG_NUMBER_ZERO } from '../constants'; import { ColorOption } from '../style/theme'; +import { BaseCurrency } from '../types'; +import { buyQuoteUtil } from '../util/buy_quote'; import { format } from '../util/format'; import { AmountPlaceholder } from './amount_placeholder'; import { Container } from './ui/container'; import { Flex } from './ui/flex'; -import { Text } from './ui/text'; +import { Text, TextProps } from './ui/text'; + +interface BaseCurrenySwitchProps { + currencyName: string; + onClick: () => void; + isSelected: boolean; +} +const BaseCurrencySelector: React.StatelessComponent = props => { + const textStyle: TextProps = { onClick: props.onClick, fontSize: '12px' }; + if (props.isSelected) { + textStyle.fontColor = ColorOption.primaryColor; + textStyle.fontWeight = 700; + } + return {props.currencyName}; +}; export interface OrderDetailsProps { buyQuoteInfo?: BuyQuoteInfo; selectedAssetUnitAmount?: BigNumber; ethUsdPrice?: BigNumber; isLoading: boolean; + assetName?: string; + baseCurrency: BaseCurrency; + onBaseCurrencySwitchEth: () => void; + onBaseCurrencySwitchUsd: () => void; } export class OrderDetails extends React.Component { public render(): React.ReactNode { const { buyQuoteInfo, ethUsdPrice, selectedAssetUnitAmount } = this.props; - const buyQuoteAccessor = oc(buyQuoteInfo); - const assetEthBaseUnitAmount = buyQuoteAccessor.assetEthAmount(); - const feeEthBaseUnitAmount = buyQuoteAccessor.feeEthAmount(); - const totalEthBaseUnitAmount = buyQuoteAccessor.totalEthAmount(); - const pricePerTokenEth = - !_.isUndefined(assetEthBaseUnitAmount) && - !_.isUndefined(selectedAssetUnitAmount) && - !selectedAssetUnitAmount.eq(BIG_NUMBER_ZERO) - ? assetEthBaseUnitAmount.div(selectedAssetUnitAmount).ceil() - : undefined; + const weiAmounts = buyQuoteUtil.getWeiAmounts(selectedAssetUnitAmount, buyQuoteInfo); + + const displayAmounts = + this.props.baseCurrency === BaseCurrency.USD + ? buyQuoteUtil.displayAmountsUsd(weiAmounts, ethUsdPrice) + : buyQuoteUtil.displayAmountsEth(weiAmounts, ethUsdPrice); + return ( - - Order Details - + + + Order Details + + + + + + / + + + + - - - + @@ -79,6 +108,103 @@ export interface EthAmountRowProps { isLoading: boolean; } +export interface OrderDetailsRowProps { + labelText: string; + isLabelBold?: boolean; + isLoading: boolean; + value?: React.ReactNode; +} +export class OrderDetailsRow extends React.Component { + public render(): React.ReactNode { + const { labelText, value, isLabelBold, isLoading } = this.props; + return ( + + + + {labelText} + + + {value || ( + + + + )} + + + + ); + } +} +export interface TotalCostRowProps { + displayPrimaryTotalCost?: React.ReactNode; + displaySecondaryTotalCost?: React.ReactNode; + isLoading: boolean; +} +export class TotalCostRow extends React.Component { + public render(): React.ReactNode { + let value: React.ReactNode; + if (this.props.displayPrimaryTotalCost) { + const secondaryText = this.props.displaySecondaryTotalCost && ( + + ({this.props.displaySecondaryTotalCost}) + + ); + value = ( + + {secondaryText} + + {this.props.displayPrimaryTotalCost} + + + ); + } + + return ( + + ); + } +} + +export interface TokenAmountRowProps { + assetName?: string; + displayPricePerToken?: React.ReactNode; + displayTotalPrice?: React.ReactNode; + isLoading: boolean; + numTokens?: BigNumber; +} +export class TokenAmountRow extends React.Component { + public static DEFAULT_TEXT: string = 'Token Price'; + public render(): React.ReactNode { + return ( + + ); + } + private _labelText(): string { + if (this.props.isLoading) { + return TokenAmountRow.DEFAULT_TEXT; + } + const { numTokens, displayPricePerToken, assetName } = this.props; + if (numTokens) { + let numTokensWithSymbol = numTokens.toString(); + + if (assetName) { + numTokensWithSymbol += ` ${assetName}`; + } + + if (displayPricePerToken) { + numTokensWithSymbol += ` @ ${displayPricePerToken}`; + } + return numTokensWithSymbol; + } + + return TokenAmountRow.DEFAULT_TEXT; + } +} + export class EthAmountRow extends React.Component { public static defaultProps = { shouldEmphasize: false, diff --git a/packages/instant/src/containers/latest_buy_quote_order_details.ts b/packages/instant/src/containers/latest_buy_quote_order_details.ts index 5dfe535e7..148735c47 100644 --- a/packages/instant/src/containers/latest_buy_quote_order_details.ts +++ b/packages/instant/src/containers/latest_buy_quote_order_details.ts @@ -1,32 +1,41 @@ -import { BuyQuoteInfo } from '@0x/asset-buyer'; -import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; import { oc } from 'ts-optchain'; +import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; -import { OrderDetails } from '../components/order_details'; -import { AsyncProcessState } from '../types'; +import { OrderDetails, OrderDetailsProps } from '../components/order_details'; +import { AsyncProcessState, BaseCurrency, Omit } from '../types'; +import { assetUtils } from '../util/asset'; -export interface LatestBuyQuoteOrderDetailsProps {} - -interface ConnectedState { - buyQuoteInfo?: BuyQuoteInfo; - selectedAssetUnitAmount?: BigNumber; - ethUsdPrice?: BigNumber; - isLoading: boolean; -} +type DispatchProperties = 'onBaseCurrencySwitchEth' | 'onBaseCurrencySwitchUsd'; +interface ConnectedState extends Omit {} const mapStateToProps = (state: State, _ownProps: LatestBuyQuoteOrderDetailsProps): ConnectedState => ({ // use the worst case quote info buyQuoteInfo: oc(state).latestBuyQuote.worstCaseQuoteInfo(), selectedAssetUnitAmount: state.selectedAssetUnitAmount, ethUsdPrice: state.ethUsdPrice, isLoading: state.quoteRequestState === AsyncProcessState.Pending, + assetName: assetUtils.bestNameForAsset(state.selectedAsset), + baseCurrency: state.baseCurrency, }); +interface ConnectedDispatch extends Pick {} +const mapDispatchToProps = (dispatch: Dispatch): ConnectedDispatch => ({ + onBaseCurrencySwitchEth: () => { + dispatch(actions.updateBaseCurrency(BaseCurrency.ETH)); + }, + onBaseCurrencySwitchUsd: () => { + dispatch(actions.updateBaseCurrency(BaseCurrency.USD)); + }, +}); + +export interface LatestBuyQuoteOrderDetailsProps {} export const LatestBuyQuoteOrderDetails: React.ComponentClass = connect( mapStateToProps, + mapDispatchToProps, )(OrderDetails); diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts index 77e3dec12..9d7a61fc7 100644 --- a/packages/instant/src/redux/actions.ts +++ b/packages/instant/src/redux/actions.ts @@ -2,7 +2,7 @@ import { BuyQuote } from '@0x/asset-buyer'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; -import { ActionsUnion, AddressAndEthBalanceInWei, Asset, StandardSlidingPanelContent } from '../types'; +import { ActionsUnion, AddressAndEthBalanceInWei, Asset, BaseCurrency, StandardSlidingPanelContent } from '../types'; export interface PlainAction { type: T; @@ -43,6 +43,7 @@ export enum ActionTypes { RESET_AMOUNT = 'RESET_AMOUNT', OPEN_STANDARD_SLIDING_PANEL = 'OPEN_STANDARD_SLIDING_PANEL', CLOSE_STANDARD_SLIDING_PANEL = 'CLOSE_STANDARD_SLIDING_PANEL', + UPDATE_BASE_CURRENCY = 'UPDATE_BASE_CURRENCY', } export const actions = { @@ -72,4 +73,5 @@ export const actions = { openStandardSlidingPanel: (content: StandardSlidingPanelContent) => createAction(ActionTypes.OPEN_STANDARD_SLIDING_PANEL, content), closeStandardSlidingPanel: () => createAction(ActionTypes.CLOSE_STANDARD_SLIDING_PANEL), + updateBaseCurrency: (baseCurrency: BaseCurrency) => createAction(ActionTypes.UPDATE_BASE_CURRENCY, baseCurrency), }; diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index a9a407b7d..4e734041f 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -14,6 +14,7 @@ import { Asset, AssetMetaData, AsyncProcessState, + BaseCurrency, DisplayStatus, Network, OrderProcessState, @@ -33,6 +34,7 @@ export interface DefaultState { latestErrorDisplayStatus: DisplayStatus; quoteRequestState: AsyncProcessState; standardSlidingPanelSettings: StandardSlidingPanelSettings; + baseCurrency: BaseCurrency; } // State that is required but needs to be derived from the props @@ -64,6 +66,7 @@ export const DEFAULT_STATE: DefaultState = { animationState: 'none', content: StandardSlidingPanelContent.None, }, + baseCurrency: BaseCurrency.ETH, }; export const createReducer = (initialState: State) => { @@ -243,6 +246,11 @@ export const createReducer = (initialState: State) => { animationState: 'slidOut', }, }; + case ActionTypes.UPDATE_BASE_CURRENCY: + return { + ...state, + baseCurrency: action.data, + }; default: return state; } diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 1c7490e63..e7c920f36 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -26,6 +26,11 @@ export enum QuoteFetchOrigin { Heartbeat = 'Heartbeat', } +export enum BaseCurrency { + USD = 'USD', + ETH = 'ETH', +} + export interface SimulatedProgress { startTimeUnix: number; expectedEndTimeUnix: number; diff --git a/packages/instant/src/util/buy_quote.ts b/packages/instant/src/util/buy_quote.ts new file mode 100644 index 000000000..acd4d389c --- /dev/null +++ b/packages/instant/src/util/buy_quote.ts @@ -0,0 +1,71 @@ +import { BuyQuoteInfo } from '@0x/asset-buyer'; +import { BigNumber } from '@0x/utils'; +import * as _ from 'lodash'; +import { oc } from 'ts-optchain'; + +import { format } from '../util/format'; + +import { BIG_NUMBER_ZERO } from '../constants'; + +export interface DisplayAmounts { + pricePerToken: React.ReactNode; + assetTotal: React.ReactNode; + feeTotal: React.ReactNode; + primaryGrandTotal: React.ReactNode; + secondaryGrandTotal?: React.ReactNode; +} + +export interface BuyQuoteWeiAmounts { + assetTotalInWei: BigNumber | undefined; + feeTotalInWei: BigNumber | undefined; + grandTotalInWei: BigNumber | undefined; + pricePerTokenInWei: BigNumber | undefined; +} + +const ethDisplayFormat = (amountInWei?: BigNumber) => { + return format.ethBaseUnitAmount(amountInWei, 4, ''); +}; +const usdDisplayFormat = (amountInWei?: BigNumber, ethUsdPrice?: BigNumber) => { + return format.ethBaseUnitAmountInUsd(amountInWei, ethUsdPrice, 2, ''); +}; + +export const buyQuoteUtil = { + getWeiAmounts: ( + selectedAssetUnitAmount: BigNumber | undefined, + buyQuoteInfo: BuyQuoteInfo | undefined, + ): BuyQuoteWeiAmounts => { + const buyQuoteAccessor = oc(buyQuoteInfo); + const assetTotalInWei = buyQuoteAccessor.assetEthAmount(); + const pricePerTokenInWei = + !_.isUndefined(assetTotalInWei) && + !_.isUndefined(selectedAssetUnitAmount) && + !selectedAssetUnitAmount.eq(BIG_NUMBER_ZERO) + ? assetTotalInWei.div(selectedAssetUnitAmount).ceil() + : undefined; + + return { + assetTotalInWei, + feeTotalInWei: buyQuoteAccessor.feeEthAmount(), + grandTotalInWei: buyQuoteAccessor.totalEthAmount(), + pricePerTokenInWei, + }; + }, + displayAmountsEth: (weiAmounts: BuyQuoteWeiAmounts, ethUsdPrice?: BigNumber): DisplayAmounts => { + return { + pricePerToken: ethDisplayFormat(weiAmounts.pricePerTokenInWei), + assetTotal: ethDisplayFormat(weiAmounts.assetTotalInWei), + feeTotal: ethDisplayFormat(weiAmounts.feeTotalInWei), + primaryGrandTotal: ethDisplayFormat(weiAmounts.grandTotalInWei), + secondaryGrandTotal: usdDisplayFormat(weiAmounts.grandTotalInWei, ethUsdPrice), + }; + }, + displayAmountsUsd: (weiAmounts: BuyQuoteWeiAmounts, ethUsdPrice?: BigNumber): DisplayAmounts => { + return { + pricePerToken: usdDisplayFormat(weiAmounts.pricePerTokenInWei, ethUsdPrice), + assetTotal: usdDisplayFormat(weiAmounts.assetTotalInWei, ethUsdPrice), + feeTotal: usdDisplayFormat(weiAmounts.feeTotalInWei, ethUsdPrice), + primaryGrandTotal: usdDisplayFormat(weiAmounts.grandTotalInWei, ethUsdPrice), + secondaryGrandTotal: ethDisplayFormat(weiAmounts.grandTotalInWei), + }; + }, +}; -- cgit From 286474ca767e955b4f7fca985d3864511fa4dfbb Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 11 Dec 2018 14:43:07 -0800 Subject: Remove unused component --- packages/instant/src/components/order_details.tsx | 49 ----------------------- 1 file changed, 49 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 85761a5b9..2fcde5aa4 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -2,9 +2,7 @@ import { BuyQuoteInfo } from '@0x/asset-buyer'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import * as React from 'react'; -import { oc } from 'ts-optchain'; -import { BIG_NUMBER_ZERO } from '../constants'; import { ColorOption } from '../style/theme'; import { BaseCurrency } from '../types'; import { buyQuoteUtil } from '../util/buy_quote'; @@ -204,50 +202,3 @@ export class TokenAmountRow extends React.Component { return TokenAmountRow.DEFAULT_TEXT; } } - -export class EthAmountRow extends React.Component { - public static defaultProps = { - shouldEmphasize: false, - isEthAmountInBaseUnits: true, - }; - public render(): React.ReactNode { - const { rowLabel, ethAmount, isEthAmountInBaseUnits, shouldEmphasize, isLoading } = this.props; - - const fontWeight = shouldEmphasize ? 700 : 400; - const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseUnitAmount : format.ethUnitAmount; - return ( - - - - {rowLabel} - - - {this._renderUsdSection()} - - {ethFormatter( - ethAmount, - 4, - - - , - )} - - - - - ); - } - private _renderUsdSection(): React.ReactNode { - const usdFormatter = this.props.isEthAmountInBaseUnits - ? format.ethBaseUnitAmountInUsd - : format.ethUnitAmountInUsd; - const shouldHideUsdPriceSection = _.isUndefined(this.props.ethUsdPrice) || _.isUndefined(this.props.ethAmount); - return shouldHideUsdPriceSection ? null : ( - - - ({usdFormatter(this.props.ethAmount, this.props.ethUsdPrice)}) - - - ); - } -} -- cgit From ee7d6fb3afad313fa699018c727c24db4f2024bd Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 11 Dec 2018 14:55:32 -0800 Subject: Show as 0 when selected --- packages/instant/src/components/order_details.tsx | 18 +++++++++++------- packages/instant/src/constants.ts | 1 + packages/instant/src/util/asset.ts | 3 ++- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 2fcde5aa4..67090898e 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -3,10 +3,10 @@ import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import * as React from 'react'; +import { DEFAULT_UNKOWN_ASSET_NAME } from '../constants'; import { ColorOption } from '../style/theme'; import { BaseCurrency } from '../types'; import { buyQuoteUtil } from '../util/buy_quote'; -import { format } from '../util/format'; import { AmountPlaceholder } from './amount_placeholder'; @@ -171,7 +171,7 @@ export interface TokenAmountRowProps { numTokens?: BigNumber; } export class TokenAmountRow extends React.Component { - public static DEFAULT_TEXT: string = 'Token Price'; + public static DEFAULT_TEXT: string = 'Token Amount'; public render(): React.ReactNode { return ( { ); } private _labelText(): string { - if (this.props.isLoading) { - return TokenAmountRow.DEFAULT_TEXT; - } - const { numTokens, displayPricePerToken, assetName } = this.props; - if (numTokens) { + const { displayPricePerToken, assetName } = this.props; + + // Display as 0 if we have a selected asset + const numTokens = + assetName && assetName !== DEFAULT_UNKOWN_ASSET_NAME && _.isUndefined(this.props.numTokens) + ? 0 + : this.props.numTokens; + + if (!_.isUndefined(numTokens)) { let numTokensWithSymbol = numTokens.toString(); if (assetName) { diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index f83eb4ac7..975dfcbea 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -17,6 +17,7 @@ export const ONE_MINUTE_MS = ONE_SECOND_MS * 60; export const GIT_SHA = process.env.GIT_SHA; export const NODE_ENV = process.env.NODE_ENV; export const NPM_PACKAGE_VERSION = process.env.NPM_PACKAGE_VERSION; +export const DEFAULT_UNKOWN_ASSET_NAME = '???'; export const ACCOUNT_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 5; export const BUY_QUOTE_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 15; export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.mul(6); diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts index 13f84ef74..faaeb7c22 100644 --- a/packages/instant/src/util/asset.ts +++ b/packages/instant/src/util/asset.ts @@ -2,6 +2,7 @@ import { AssetBuyerError } from '@0x/asset-buyer'; import { AssetProxyId, ObjectMap } from '@0x/types'; import * as _ from 'lodash'; +import { DEFAULT_UNKOWN_ASSET_NAME } from '../constants'; import { assetDataNetworkMapping } from '../data/asset_data_network_mapping'; import { Asset, AssetMetaData, ERC20Asset, Network, ZeroExInstantError } from '../types'; @@ -71,7 +72,7 @@ export const assetUtils = { } return metaData; }, - bestNameForAsset: (asset?: Asset, defaultName: string = '???'): string => { + bestNameForAsset: (asset?: Asset, defaultName: string = DEFAULT_UNKOWN_ASSET_NAME): string => { if (_.isUndefined(asset)) { return defaultName; } -- cgit From b1a73f5c742b96906e832e532dbdc3e4e9583c6d Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 11 Dec 2018 17:03:07 -0800 Subject: Refactor out custom components --- packages/instant/src/components/order_details.tsx | 137 +++++++++------------- 1 file changed, 55 insertions(+), 82 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 67090898e..9eaf2fb2e 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -28,6 +28,49 @@ const BaseCurrencySelector: React.StatelessComponent = p return {props.currencyName}; }; +const grandTotalDisplayValue = ( + displayPrimaryTotalCost?: React.ReactNode, + displaySecondaryTotalCost?: React.ReactNode, +): React.ReactNode => { + if (!displayPrimaryTotalCost) { + return undefined; + } + const secondaryText = displaySecondaryTotalCost && ( + + ({displaySecondaryTotalCost}) + + ); + return ( + + {secondaryText} + + {displayPrimaryTotalCost} + + + ); +}; + +const tokenAmountLabel = (displayPricePerToken?: React.ReactNode, assetName?: string, numTokens?: BigNumber) => { + // Display as 0 if we have a selected asset + const displayNumTokens = + assetName && assetName !== DEFAULT_UNKOWN_ASSET_NAME && _.isUndefined(numTokens) ? new BigNumber(0) : numTokens; + + if (!_.isUndefined(displayNumTokens)) { + let numTokensWithSymbol = displayNumTokens.toString(); + + if (assetName) { + numTokensWithSymbol += ` ${assetName}`; + } + + if (displayPricePerToken) { + numTokensWithSymbol += ` @ ${displayPricePerToken}`; + } + return numTokensWithSymbol; + } + + return 'Token Amount'; +}; + export interface OrderDetailsProps { buyQuoteInfo?: BuyQuoteInfo; selectedAssetUnitAmount?: BigNumber; @@ -79,18 +122,21 @@ export class OrderDetails extends React.Component { - - - + ); @@ -133,76 +179,3 @@ export class OrderDetailsRow extends React.Component { ); } } -export interface TotalCostRowProps { - displayPrimaryTotalCost?: React.ReactNode; - displaySecondaryTotalCost?: React.ReactNode; - isLoading: boolean; -} -export class TotalCostRow extends React.Component { - public render(): React.ReactNode { - let value: React.ReactNode; - if (this.props.displayPrimaryTotalCost) { - const secondaryText = this.props.displaySecondaryTotalCost && ( - - ({this.props.displaySecondaryTotalCost}) - - ); - value = ( - - {secondaryText} - - {this.props.displayPrimaryTotalCost} - - - ); - } - - return ( - - ); - } -} - -export interface TokenAmountRowProps { - assetName?: string; - displayPricePerToken?: React.ReactNode; - displayTotalPrice?: React.ReactNode; - isLoading: boolean; - numTokens?: BigNumber; -} -export class TokenAmountRow extends React.Component { - public static DEFAULT_TEXT: string = 'Token Amount'; - public render(): React.ReactNode { - return ( - - ); - } - private _labelText(): string { - const { displayPricePerToken, assetName } = this.props; - - // Display as 0 if we have a selected asset - const numTokens = - assetName && assetName !== DEFAULT_UNKOWN_ASSET_NAME && _.isUndefined(this.props.numTokens) - ? 0 - : this.props.numTokens; - - if (!_.isUndefined(numTokens)) { - let numTokensWithSymbol = numTokens.toString(); - - if (assetName) { - numTokensWithSymbol += ` ${assetName}`; - } - - if (displayPricePerToken) { - numTokensWithSymbol += ` @ ${displayPricePerToken}`; - } - return numTokensWithSymbol; - } - - return TokenAmountRow.DEFAULT_TEXT; - } -} -- cgit From 5f7ed71937c8319bb5613dc57f005848b1fa336c Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Tue, 11 Dec 2018 17:06:27 -0800 Subject: Delete old interface and rename BaseCurrencyChoice --- packages/instant/src/components/order_details.tsx | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 9eaf2fb2e..8bff0af14 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -14,12 +14,12 @@ import { Container } from './ui/container'; import { Flex } from './ui/flex'; import { Text, TextProps } from './ui/text'; -interface BaseCurrenySwitchProps { +interface BaseCurryChoiceProps { currencyName: string; onClick: () => void; isSelected: boolean; } -const BaseCurrencySelector: React.StatelessComponent = props => { +const BaseCurrencyChoice: React.StatelessComponent = props => { const textStyle: TextProps = { onClick: props.onClick, fontSize: '12px' }; if (props.isSelected) { textStyle.fontColor = ColorOption.primaryColor; @@ -106,7 +106,7 @@ export class OrderDetails extends React.Component { - { / - { } } -export interface EthAmountRowProps { - rowLabel: string; - ethAmount?: BigNumber; - isEthAmountInBaseUnits?: boolean; - ethUsdPrice?: BigNumber; - shouldEmphasize?: boolean; - isLoading: boolean; -} - export interface OrderDetailsRowProps { labelText: string; isLabelBold?: boolean; -- cgit From 7aacf1f5a457e1166f5188836d30a8c38f3f2c68 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 08:23:40 -0800 Subject: Render OrderDetailsRow directly --- packages/instant/src/components/order_details.tsx | 39 +++++++++++++++++------ packages/instant/src/util/buy_quote.ts | 35 -------------------- 2 files changed, 29 insertions(+), 45 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 8bff0af14..f553351ff 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -7,6 +7,7 @@ import { DEFAULT_UNKOWN_ASSET_NAME } from '../constants'; import { ColorOption } from '../style/theme'; import { BaseCurrency } from '../types'; import { buyQuoteUtil } from '../util/buy_quote'; +import { format } from '../util/format'; import { AmountPlaceholder } from './amount_placeholder'; @@ -71,6 +72,19 @@ const tokenAmountLabel = (displayPricePerToken?: React.ReactNode, assetName?: st return 'Token Amount'; }; +const getDisplayAmount = ( + baseCurrency: BaseCurrency, + weiAmount?: BigNumber, + ethUsdPrice?: BigNumber, +): React.ReactNode => { + switch (baseCurrency) { + case BaseCurrency.USD: + return format.ethBaseUnitAmountInUsd(weiAmount, ethUsdPrice, 2, ''); + case BaseCurrency.ETH: + return format.ethBaseUnitAmount(weiAmount, 4, ''); + } +}; + export interface OrderDetailsProps { buyQuoteInfo?: BuyQuoteInfo; selectedAssetUnitAmount?: BigNumber; @@ -83,13 +97,14 @@ export interface OrderDetailsProps { } export class OrderDetails extends React.Component { public render(): React.ReactNode { - const { buyQuoteInfo, ethUsdPrice, selectedAssetUnitAmount } = this.props; - const weiAmounts = buyQuoteUtil.getWeiAmounts(selectedAssetUnitAmount, buyQuoteInfo); + const { baseCurrency, buyQuoteInfo, ethUsdPrice, selectedAssetUnitAmount } = this.props; - const displayAmounts = - this.props.baseCurrency === BaseCurrency.USD - ? buyQuoteUtil.displayAmountsUsd(weiAmounts, ethUsdPrice) - : buyQuoteUtil.displayAmountsEth(weiAmounts, ethUsdPrice); + const weiAmounts = buyQuoteUtil.getWeiAmounts(selectedAssetUnitAmount, buyQuoteInfo); + const secondaryCurrency = baseCurrency === BaseCurrency.USD ? BaseCurrency.ETH : BaseCurrency.USD; + const grandTotalValue = grandTotalDisplayValue( + getDisplayAmount(baseCurrency, weiAmounts.grandTotalInWei, ethUsdPrice), + getDisplayAmount(secondaryCurrency, weiAmounts.grandTotalInWei, ethUsdPrice), + ); return ( @@ -125,18 +140,22 @@ export class OrderDetails extends React.Component { + - ); diff --git a/packages/instant/src/util/buy_quote.ts b/packages/instant/src/util/buy_quote.ts index acd4d389c..0e880f51c 100644 --- a/packages/instant/src/util/buy_quote.ts +++ b/packages/instant/src/util/buy_quote.ts @@ -3,18 +3,8 @@ import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import { oc } from 'ts-optchain'; -import { format } from '../util/format'; - import { BIG_NUMBER_ZERO } from '../constants'; -export interface DisplayAmounts { - pricePerToken: React.ReactNode; - assetTotal: React.ReactNode; - feeTotal: React.ReactNode; - primaryGrandTotal: React.ReactNode; - secondaryGrandTotal?: React.ReactNode; -} - export interface BuyQuoteWeiAmounts { assetTotalInWei: BigNumber | undefined; feeTotalInWei: BigNumber | undefined; @@ -22,13 +12,6 @@ export interface BuyQuoteWeiAmounts { pricePerTokenInWei: BigNumber | undefined; } -const ethDisplayFormat = (amountInWei?: BigNumber) => { - return format.ethBaseUnitAmount(amountInWei, 4, ''); -}; -const usdDisplayFormat = (amountInWei?: BigNumber, ethUsdPrice?: BigNumber) => { - return format.ethBaseUnitAmountInUsd(amountInWei, ethUsdPrice, 2, ''); -}; - export const buyQuoteUtil = { getWeiAmounts: ( selectedAssetUnitAmount: BigNumber | undefined, @@ -50,22 +33,4 @@ export const buyQuoteUtil = { pricePerTokenInWei, }; }, - displayAmountsEth: (weiAmounts: BuyQuoteWeiAmounts, ethUsdPrice?: BigNumber): DisplayAmounts => { - return { - pricePerToken: ethDisplayFormat(weiAmounts.pricePerTokenInWei), - assetTotal: ethDisplayFormat(weiAmounts.assetTotalInWei), - feeTotal: ethDisplayFormat(weiAmounts.feeTotalInWei), - primaryGrandTotal: ethDisplayFormat(weiAmounts.grandTotalInWei), - secondaryGrandTotal: usdDisplayFormat(weiAmounts.grandTotalInWei, ethUsdPrice), - }; - }, - displayAmountsUsd: (weiAmounts: BuyQuoteWeiAmounts, ethUsdPrice?: BigNumber): DisplayAmounts => { - return { - pricePerToken: usdDisplayFormat(weiAmounts.pricePerTokenInWei, ethUsdPrice), - assetTotal: usdDisplayFormat(weiAmounts.assetTotalInWei, ethUsdPrice), - feeTotal: usdDisplayFormat(weiAmounts.feeTotalInWei, ethUsdPrice), - primaryGrandTotal: usdDisplayFormat(weiAmounts.grandTotalInWei, ethUsdPrice), - secondaryGrandTotal: ethDisplayFormat(weiAmounts.grandTotalInWei), - }; - }, }; -- cgit From 8923817b2ff6c8d3cffe6914634e75cdf06db4a9 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 08:25:20 -0800 Subject: Move header to helper --- packages/instant/src/components/order_details.tsx | 62 ++++++++++++----------- 1 file changed, 33 insertions(+), 29 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index f553351ff..5d306f43e 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -108,35 +108,7 @@ export class OrderDetails extends React.Component { return ( - - - - Order Details - - - - - - / - - - - - + {this._renderHeader()} { ); } + + private _renderHeader(): React.ReactNode { + return ( + + + Order Details + + + + + + / + + + + + ); + } } export interface OrderDetailsRowProps { -- cgit From 3b9e8e669f179aeda7a3aa3f91c78477fa7f08cd Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 09:14:25 -0800 Subject: Refactor OrderDetails to use private instance methods --- packages/instant/src/components/order_details.tsx | 206 ++++++++++++---------- 1 file changed, 115 insertions(+), 91 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 5d306f43e..7e33e06ac 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -2,11 +2,11 @@ import { BuyQuoteInfo } from '@0x/asset-buyer'; import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import * as React from 'react'; +import { oc } from 'ts-optchain'; -import { DEFAULT_UNKOWN_ASSET_NAME } from '../constants'; +import { BIG_NUMBER_ZERO, DEFAULT_UNKOWN_ASSET_NAME } from '../constants'; import { ColorOption } from '../style/theme'; import { BaseCurrency } from '../types'; -import { buyQuoteUtil } from '../util/buy_quote'; import { format } from '../util/format'; import { AmountPlaceholder } from './amount_placeholder'; @@ -29,62 +29,6 @@ const BaseCurrencyChoice: React.StatelessComponent = props return {props.currencyName}; }; -const grandTotalDisplayValue = ( - displayPrimaryTotalCost?: React.ReactNode, - displaySecondaryTotalCost?: React.ReactNode, -): React.ReactNode => { - if (!displayPrimaryTotalCost) { - return undefined; - } - const secondaryText = displaySecondaryTotalCost && ( - - ({displaySecondaryTotalCost}) - - ); - return ( - - {secondaryText} - - {displayPrimaryTotalCost} - - - ); -}; - -const tokenAmountLabel = (displayPricePerToken?: React.ReactNode, assetName?: string, numTokens?: BigNumber) => { - // Display as 0 if we have a selected asset - const displayNumTokens = - assetName && assetName !== DEFAULT_UNKOWN_ASSET_NAME && _.isUndefined(numTokens) ? new BigNumber(0) : numTokens; - - if (!_.isUndefined(displayNumTokens)) { - let numTokensWithSymbol = displayNumTokens.toString(); - - if (assetName) { - numTokensWithSymbol += ` ${assetName}`; - } - - if (displayPricePerToken) { - numTokensWithSymbol += ` @ ${displayPricePerToken}`; - } - return numTokensWithSymbol; - } - - return 'Token Amount'; -}; - -const getDisplayAmount = ( - baseCurrency: BaseCurrency, - weiAmount?: BigNumber, - ethUsdPrice?: BigNumber, -): React.ReactNode => { - switch (baseCurrency) { - case BaseCurrency.USD: - return format.ethBaseUnitAmountInUsd(weiAmount, ethUsdPrice, 2, ''); - case BaseCurrency.ETH: - return format.ethBaseUnitAmount(weiAmount, 4, ''); - } -}; - export interface OrderDetailsProps { buyQuoteInfo?: BuyQuoteInfo; selectedAssetUnitAmount?: BigNumber; @@ -97,42 +41,107 @@ export interface OrderDetailsProps { } export class OrderDetails extends React.Component { public render(): React.ReactNode { - const { baseCurrency, buyQuoteInfo, ethUsdPrice, selectedAssetUnitAmount } = this.props; - - const weiAmounts = buyQuoteUtil.getWeiAmounts(selectedAssetUnitAmount, buyQuoteInfo); - const secondaryCurrency = baseCurrency === BaseCurrency.USD ? BaseCurrency.ETH : BaseCurrency.USD; - const grandTotalValue = grandTotalDisplayValue( - getDisplayAmount(baseCurrency, weiAmounts.grandTotalInWei, ethUsdPrice), - getDisplayAmount(secondaryCurrency, weiAmounts.grandTotalInWei, ethUsdPrice), - ); + const { baseCurrency, buyQuoteInfo } = this.props; return ( {this._renderHeader()} + ); } + private _totalCostSecondaryValue(): React.ReactNode { + const secondaryCurrency = this.props.baseCurrency === BaseCurrency.USD ? BaseCurrency.ETH : BaseCurrency.USD; + + const canDisplayCurrency = + secondaryCurrency === BaseCurrency.ETH || + (secondaryCurrency === BaseCurrency.USD && + this.props.ethUsdPrice && + this.props.ethUsdPrice.greaterThan(BIG_NUMBER_ZERO)); + + if (this.props.buyQuoteInfo && canDisplayCurrency) { + return this._displayAmount(secondaryCurrency, this.props.buyQuoteInfo.totalEthAmount); + } else { + return undefined; + } + } + + private _displayAmountOrPlaceholder(weiAmount?: BigNumber): React.ReactNode { + const { baseCurrency, ethUsdPrice, isLoading } = this.props; + + if (_.isUndefined(weiAmount)) { + return ( + + + + ); + } + + return this._displayAmount(baseCurrency, weiAmount); + } + + private _displayAmount(currency: BaseCurrency, weiAmount: BigNumber): React.ReactNode { + switch (currency) { + case BaseCurrency.USD: + return format.ethBaseUnitAmountInUsd(weiAmount, this.props.ethUsdPrice, 2, ''); + case BaseCurrency.ETH: + return format.ethBaseUnitAmount(weiAmount, 4, ''); + } + } + + private _assetLabelText(): string { + const { assetName, baseCurrency, ethUsdPrice } = this.props; + const numTokens = this.props.selectedAssetUnitAmount; + + // Display as 0 if we have a selected asset + const displayNumTokens = + assetName && assetName !== DEFAULT_UNKOWN_ASSET_NAME && _.isUndefined(numTokens) + ? new BigNumber(0) + : numTokens; + + if (!_.isUndefined(displayNumTokens)) { + let numTokensWithSymbol = displayNumTokens.toString(); + + if (assetName) { + numTokensWithSymbol += ` ${assetName}`; + } + + const pricePerTokenWei = this._pricePerTokenWei(); + if (pricePerTokenWei) { + numTokensWithSymbol += ` @ ${this._displayAmount(baseCurrency, pricePerTokenWei)}`; + } + return numTokensWithSymbol; + } + + return 'Token Amount'; + } + + private _pricePerTokenWei(): BigNumber | undefined { + const buyQuoteAccessor = oc(this.props.buyQuoteInfo); + const assetTotalInWei = buyQuoteAccessor.assetEthAmount(); + const selectedAssetUnitAmount = this.props.selectedAssetUnitAmount; + return !_.isUndefined(assetTotalInWei) && + !_.isUndefined(selectedAssetUnitAmount) && + !selectedAssetUnitAmount.eq(BIG_NUMBER_ZERO) + ? assetTotalInWei.div(selectedAssetUnitAmount).ceil() + : undefined; + } + private _renderHeader(): React.ReactNode { return ( @@ -169,27 +178,42 @@ export class OrderDetails extends React.Component { export interface OrderDetailsRowProps { labelText: string; isLabelBold?: boolean; - isLoading: boolean; - value?: React.ReactNode; + isPrimaryValueBold?: boolean; + primaryValue: React.ReactNode; + secondaryValue?: React.ReactNode; } export class OrderDetailsRow extends React.Component { public render(): React.ReactNode { - const { labelText, value, isLabelBold, isLoading } = this.props; return ( - - {labelText} - - - {value || ( - - - - )} - + {this._renderLabel()} + {this._renderValues()} ); } + + private _renderLabel(): React.ReactNode { + return ( + + {this.props.labelText} + + ); + } + + private _renderValues(): React.ReactNode { + const secondaryValueNode: React.ReactNode = this.props.secondaryValue && ( + + ({this.props.secondaryValue}) + + ); + + return ( + + {secondaryValueNode} + {this.props.primaryValue} + + ); + } } -- cgit From ad3d20b34267eda1a9b1d397fb15f2bce0eb221f Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 09:15:18 -0800 Subject: Default to USD --- packages/instant/src/redux/reducer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index 4e734041f..8c13c9c72 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -66,7 +66,7 @@ export const DEFAULT_STATE: DefaultState = { animationState: 'none', content: StandardSlidingPanelContent.None, }, - baseCurrency: BaseCurrency.ETH, + baseCurrency: BaseCurrency.USD, }; export const createReducer = (initialState: State) => { -- cgit From b59f20482ee7c4e6b5fef530957442ca54c6c6dd Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 7 Dec 2018 11:14:01 -0800 Subject: feat: log walletDisplayName to Heap --- packages/instant/src/components/zero_ex_instant_provider.tsx | 1 + packages/instant/src/util/analytics.ts | 3 +++ 2 files changed, 4 insertions(+) (limited to 'packages/instant') diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index 7ae27de23..4012af646 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -119,6 +119,7 @@ export class ZeroExInstantProvider extends React.Component { @@ -149,6 +151,7 @@ export const analytics = { embeddedUrl: window.location.href, networkId: network, providerName: providerState.name, + walletDisplayName, gitSha: GIT_SHA, npmVersion: NPM_PACKAGE_VERSION, orderSource: orderSourceName, -- cgit From 7dd0b3a5daf2794a7714d95f8b0ff691bb6bfb13 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 7 Dec 2018 11:29:37 -0800 Subject: feat: refactor provider name and displayName logic --- .../src/components/zero_ex_instant_provider.tsx | 2 +- packages/instant/src/types.ts | 1 + packages/instant/src/util/analytics.ts | 5 ++-- packages/instant/src/util/env.ts | 7 +++++ .../instant/src/util/provider_state_factory.ts | 33 ++++++++++++++++++---- 5 files changed, 39 insertions(+), 9 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index 4012af646..204115fa9 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -38,6 +38,7 @@ export class ZeroExInstantProvider extends React.Component { @@ -151,7 +150,7 @@ export const analytics = { embeddedUrl: window.location.href, networkId: network, providerName: providerState.name, - walletDisplayName, + providerDisplayName: providerState.displayName, gitSha: GIT_SHA, npmVersion: NPM_PACKAGE_VERSION, orderSource: orderSourceName, diff --git a/packages/instant/src/util/env.ts b/packages/instant/src/util/env.ts index 4a32f9cb1..0fda0cc0e 100644 --- a/packages/instant/src/util/env.ts +++ b/packages/instant/src/util/env.ts @@ -62,4 +62,11 @@ export const envUtil = { } return PROVIDER_TYPE_TO_NAME[providerTypeIfExists]; }, + getProviderDisplayName(provider: Provider): string { + const providerTypeIfExists = envUtil.getProviderType(provider); + if (_.isUndefined(providerTypeIfExists)) { + return 'Wallet'; + } + return PROVIDER_TYPE_TO_NAME[providerTypeIfExists]; + }, }; diff --git a/packages/instant/src/util/provider_state_factory.ts b/packages/instant/src/util/provider_state_factory.ts index 7c788dff2..bd2d6dad5 100644 --- a/packages/instant/src/util/provider_state_factory.ts +++ b/packages/instant/src/util/provider_state_factory.ts @@ -10,27 +10,40 @@ import { assetBuyerFactory } from './asset_buyer_factory'; import { providerFactory } from './provider_factory'; export const providerStateFactory = { - getInitialProviderState: (orderSource: OrderSource, network: Network, provider?: Provider): ProviderState => { + getInitialProviderState: ( + orderSource: OrderSource, + network: Network, + provider?: Provider, + walletDisplayName?: string, + ): ProviderState => { if (!_.isUndefined(provider)) { - return providerStateFactory.getInitialProviderStateFromProvider(orderSource, network, provider); + return providerStateFactory.getInitialProviderStateFromProvider( + orderSource, + network, + provider, + walletDisplayName, + ); } const providerStateFromWindowIfExits = providerStateFactory.getInitialProviderStateFromWindowIfExists( orderSource, network, + walletDisplayName, ); if (providerStateFromWindowIfExits) { return providerStateFromWindowIfExits; } else { - return providerStateFactory.getInitialProviderStateFallback(orderSource, network); + return providerStateFactory.getInitialProviderStateFallback(orderSource, network, walletDisplayName); } }, getInitialProviderStateFromProvider: ( orderSource: OrderSource, network: Network, provider: Provider, + walletDisplayName?: string, ): ProviderState => { const providerState: ProviderState = { name: envUtil.getProviderName(provider), + displayName: walletDisplayName || envUtil.getProviderDisplayName(provider), provider, web3Wrapper: new Web3Wrapper(provider), assetBuyer: assetBuyerFactory.getAssetBuyer(provider, orderSource, network), @@ -38,11 +51,16 @@ export const providerStateFactory = { }; return providerState; }, - getInitialProviderStateFromWindowIfExists: (orderSource: OrderSource, network: Network): Maybe => { + getInitialProviderStateFromWindowIfExists: ( + orderSource: OrderSource, + network: Network, + walletDisplayName?: string, + ): Maybe => { const injectedProviderIfExists = providerFactory.getInjectedProviderIfExists(); if (!_.isUndefined(injectedProviderIfExists)) { const providerState: ProviderState = { name: envUtil.getProviderName(injectedProviderIfExists), + displayName: walletDisplayName || envUtil.getProviderDisplayName(injectedProviderIfExists), provider: injectedProviderIfExists, web3Wrapper: new Web3Wrapper(injectedProviderIfExists), assetBuyer: assetBuyerFactory.getAssetBuyer(injectedProviderIfExists, orderSource, network), @@ -53,10 +71,15 @@ export const providerStateFactory = { return undefined; } }, - getInitialProviderStateFallback: (orderSource: OrderSource, network: Network): ProviderState => { + getInitialProviderStateFallback: ( + orderSource: OrderSource, + network: Network, + walletDisplayName?: string, + ): ProviderState => { const provider = providerFactory.getFallbackNoSigningProvider(network); const providerState: ProviderState = { name: 'Fallback', + displayName: walletDisplayName || envUtil.getProviderDisplayName(provider), provider, web3Wrapper: new Web3Wrapper(provider), assetBuyer: assetBuyerFactory.getAssetBuyer(provider, orderSource, network), -- cgit From 74e07b63de9688aa0dca2ce69863203766db6008 Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 7 Dec 2018 12:21:06 -0800 Subject: feat: only use display name from provider in ui --- packages/instant/src/containers/connected_account_payment_method.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/containers/connected_account_payment_method.ts b/packages/instant/src/containers/connected_account_payment_method.ts index bb68fdd57..f648f0b54 100644 --- a/packages/instant/src/containers/connected_account_payment_method.ts +++ b/packages/instant/src/containers/connected_account_payment_method.ts @@ -58,7 +58,7 @@ const mergeProps = ( ...ownProps, network: connectedState.network, account: connectedState.providerState.account, - walletDisplayName: connectedState.walletDisplayName || connectedState.providerState.name, + walletDisplayName: connectedState.providerState.displayName, onUnlockWalletClick: () => connectedDispatch.unlockWalletAndDispatchToStore(connectedState.providerState), onInstallWalletClick: () => { const isMobile = envUtil.isMobileOperatingSystem(); -- cgit From 8e071db074d3ad88a37d2cfc85780c995bc2cd17 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Mon, 10 Dec 2018 09:00:05 -0800 Subject: Don't throw error if can't find icon for token --- packages/instant/src/components/erc20_token_selector.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/erc20_token_selector.tsx b/packages/instant/src/components/erc20_token_selector.tsx index f7d5a4fe4..cb8a8c797 100644 --- a/packages/instant/src/components/erc20_token_selector.tsx +++ b/packages/instant/src/components/erc20_token_selector.tsx @@ -7,7 +7,6 @@ import { analytics } from '../util/analytics'; import { assetUtils } from '../util/asset'; import { SearchInput } from './search_input'; - import { Circle } from './ui/circle'; import { Container } from './ui/container'; import { Flex } from './ui/flex'; @@ -123,10 +122,20 @@ interface TokenSelectorRowIconProps { token: ERC20Asset; } +const getTokenIcon = (symbol: string): React.StatelessComponent | undefined => { + try { + return require(`../assets/icons/${symbol}.svg`) as React.StatelessComponent; + } catch (e) { + // Can't find icon + return undefined; + } +}; + const TokenSelectorRowIcon: React.StatelessComponent = props => { const { token } = props; const iconUrlIfExists = token.metaData.iconUrl; - const TokenIcon = require(`../assets/icons/${token.metaData.symbol}.svg`); + + const TokenIcon = getTokenIcon(token.metaData.symbol); const displaySymbol = assetUtils.bestNameForAsset(token); if (!_.isUndefined(iconUrlIfExists)) { return ; -- cgit From 2b7dabeb6e6c0baca8bc36fe19e39dd4000801b2 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Sat, 8 Dec 2018 09:48:17 -0800 Subject: fix(instant): hide loaders when no token or buy amount is chosen --- packages/instant/src/components/instant_heading.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 117f9dd5f..816cc5c33 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -61,12 +61,19 @@ export class InstantHeading extends React.Component { } private _renderAmountsSection(): React.ReactNode { - return ( - - {this._renderPlaceholderOrAmount(this._renderEthAmount)} - {this._renderPlaceholderOrAmount(this._renderDollarAmount)} - - ); + if ( + _.isUndefined(this.props.totalEthBaseUnitAmount) && + this.props.quoteRequestState !== AsyncProcessState.Pending + ) { + return null; + } else { + return ( + + {this._renderPlaceholderOrAmount(this._renderEthAmount)} + {this._renderPlaceholderOrAmount(this._renderDollarAmount)} + + ); + } } private _renderIcon(): React.ReactNode { -- cgit From 6e023e6ea3a872d49bbad7e01bdb731656d657ce Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 10 Dec 2018 15:36:04 -0800 Subject: Update instant README --- packages/instant/README.md | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'packages/instant') diff --git a/packages/instant/README.md b/packages/instant/README.md index 2092b45d9..549bebb88 100644 --- a/packages/instant/README.md +++ b/packages/instant/README.md @@ -1,5 +1,10 @@ ## @0x/instant +## Integration + +Looking to integrate 0x Instant into your web application or site? Check out the dedicated [instant documentation](https://0xproject.com/wiki#Get-Started-With-Instant) to get started. + + ## Installation The package is available as a UMD module named `zeroExInstant` at https://instant.0xproject.com/instant.js. -- cgit From c9af7dc9e5925c0f6fb368846f6ffc2d4a216ece Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Mon, 10 Dec 2018 15:47:13 -0800 Subject: Revert access changes --- packages/instant/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/package.json b/packages/instant/package.json index 9303276b4..e3452e3b8 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -96,6 +96,6 @@ "webpack-dev-server": "^3.1.9" }, "publishConfig": { - "access": "private" + "access": "public" } } -- cgit From 0f1197c14bb2ef15bf46dbe75f0b9977c547fd11 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 10 Dec 2018 16:06:26 -0800 Subject: Update instant README with more integration links --- packages/instant/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/README.md b/packages/instant/README.md index 549bebb88..3c72d06ff 100644 --- a/packages/instant/README.md +++ b/packages/instant/README.md @@ -2,7 +2,7 @@ ## Integration -Looking to integrate 0x Instant into your web application or site? Check out the dedicated [instant documentation](https://0xproject.com/wiki#Get-Started-With-Instant) to get started. +Looking to integrate 0x Instant into your web application or site? Check out the dedicated [instant documentation](https://0xproject.com/wiki#Get-Started-With-Instant) to get started. The documentation covers instant and related topics in depth. For a more "drag and drop" experience, check out our [configurator tool](https://0xproject.com/instant#configure). For on demand developer support, join our (Discord)[https://discordapp.com/invite/d3FTX3M]. ## Installation -- cgit From 7c33c91d598d68188abde77ae87b3d376c7ea41a Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 10 Dec 2018 16:07:16 -0800 Subject: chore: remove extra newline --- packages/instant/README.md | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/README.md b/packages/instant/README.md index 3c72d06ff..ac8f0293a 100644 --- a/packages/instant/README.md +++ b/packages/instant/README.md @@ -4,7 +4,6 @@ Looking to integrate 0x Instant into your web application or site? Check out the dedicated [instant documentation](https://0xproject.com/wiki#Get-Started-With-Instant) to get started. The documentation covers instant and related topics in depth. For a more "drag and drop" experience, check out our [configurator tool](https://0xproject.com/instant#configure). For on demand developer support, join our (Discord)[https://discordapp.com/invite/d3FTX3M]. - ## Installation The package is available as a UMD module named `zeroExInstant` at https://instant.0xproject.com/instant.js. -- cgit From 72e94b3307c9117a5782e95e31407b998c1bfbe6 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 10 Dec 2018 16:08:23 -0800 Subject: chore: fix typo in instant README --- packages/instant/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/README.md b/packages/instant/README.md index ac8f0293a..7f6ee7c46 100644 --- a/packages/instant/README.md +++ b/packages/instant/README.md @@ -2,7 +2,7 @@ ## Integration -Looking to integrate 0x Instant into your web application or site? Check out the dedicated [instant documentation](https://0xproject.com/wiki#Get-Started-With-Instant) to get started. The documentation covers instant and related topics in depth. For a more "drag and drop" experience, check out our [configurator tool](https://0xproject.com/instant#configure). For on demand developer support, join our (Discord)[https://discordapp.com/invite/d3FTX3M]. +Looking to integrate 0x Instant into your web application or site? Check out the dedicated [instant documentation](https://0xproject.com/wiki#Get-Started-With-Instant) to get started. The documentation covers instant and related topics in depth. For a more "drag and drop" experience, check out our [configurator tool](https://0xproject.com/instant#configure). For on demand developer support, join our [Discord](https://discordapp.com/invite/d3FTX3M). ## Installation -- cgit From ca86f18e7df7126fb77ae6fc0509b1b38048dd88 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 10 Dec 2018 16:11:08 -0800 Subject: Add link to rexrelay integration example in instant README --- packages/instant/README.md | 2 ++ 1 file changed, 2 insertions(+) (limited to 'packages/instant') diff --git a/packages/instant/README.md b/packages/instant/README.md index 7f6ee7c46..32abf76e0 100644 --- a/packages/instant/README.md +++ b/packages/instant/README.md @@ -4,6 +4,8 @@ Looking to integrate 0x Instant into your web application or site? Check out the dedicated [instant documentation](https://0xproject.com/wiki#Get-Started-With-Instant) to get started. The documentation covers instant and related topics in depth. For a more "drag and drop" experience, check out our [configurator tool](https://0xproject.com/instant#configure). For on demand developer support, join our [Discord](https://discordapp.com/invite/d3FTX3M). +Check out a live sample integration [here](https://www.rexrelay.com/instant). + ## Installation The package is available as a UMD module named `zeroExInstant` at https://instant.0xproject.com/instant.js. -- cgit From 50e03360188ec4fe99a15a8e931c771da1d232cd Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Tue, 11 Dec 2018 09:32:44 -0800 Subject: Revert accidental change --- packages/instant/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/package.json b/packages/instant/package.json index e3452e3b8..9303276b4 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -96,6 +96,6 @@ "webpack-dev-server": "^3.1.9" }, "publishConfig": { - "access": "public" + "access": "private" } } -- cgit From 87ab8f036c9fac10464165662a29a1dab47d9b46 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Tue, 11 Dec 2018 15:38:43 -0800 Subject: Publish - 0x.js@2.0.7 - @0x/abi-gen@1.0.18 - @0x/abi-gen-wrappers@2.0.1 - @0x/assert@1.0.19 - @0x/asset-buyer@3.0.3 - @0x/base-contract@3.0.9 - @0x/connect@3.0.9 - @0x/contract-wrappers@4.1.2 - @0x/dev-tools-pages@0.0.9 - @0x/dev-utils@1.0.20 - ethereum-types@1.1.3 - @0x/fill-scenarios@1.0.15 - @0x/instant@1.0.3 - @0x/json-schemas@2.1.3 - @0x/metacoin@0.0.31 - @0x/migrations@2.2.1 - @0x/monorepo-scripts@1.0.15 - @0x/order-utils@3.0.6 - @0x/order-watcher@2.2.7 - @0x/pipeline@1.0.1 - @0x/react-docs@1.0.21 - @0x/react-shared@1.0.24 - @0x/sol-compiler@1.1.15 - @0x/sol-cov@2.1.15 - @0x/sol-doc@1.0.10 - @0x/sol-resolver@1.1.0 - @0x/sra-spec@1.0.12 - @0x/subproviders@2.1.7 - @0x/testnet-faucets@1.0.59 - @0x/types@1.4.0 - @0x/typescript-typings@3.0.5 - @0x/utils@2.0.7 - @0x/web3-wrapper@3.2.0 - @0x/website@0.0.62 - @0x/contracts-examples@1.0.1 - @0x/contracts-extensions@1.0.1 - @0x/contracts-interfaces@1.0.1 - @0x/contracts-libs@1.0.1 - @0x/contracts-multisig@1.0.1 - @0x/contracts-protocol@2.1.57 - @0x/contracts-test-utils@1.0.1 - @0x/contracts-tokens@1.0.1 - @0x/contracts-utils@1.0.1 --- packages/instant/package.json | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/package.json b/packages/instant/package.json index 9303276b4..7a519f460 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -1,6 +1,6 @@ { "name": "@0x/instant", - "version": "1.0.2", + "version": "1.0.3", "engines": { "node": ">=6.12" }, @@ -24,7 +24,10 @@ }, "config": { "postpublish": { - "assets": ["packages/instant/umd/instant.js", "packages/instant/umd/instant.js.map"] + "assets": [ + "packages/instant/umd/instant.js", + "packages/instant/umd/instant.js.map" + ] } }, "repository": { @@ -38,18 +41,18 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md", "dependencies": { - "@0x/assert": "^1.0.18", - "@0x/asset-buyer": "^3.0.2", - "@0x/json-schemas": "^2.1.2", - "@0x/order-utils": "^3.0.4", - "@0x/subproviders": "^2.1.6", - "@0x/types": "^1.3.0", - "@0x/typescript-typings": "^3.0.4", - "@0x/utils": "^2.0.6", - "@0x/web3-wrapper": "^3.1.6", + "@0x/assert": "^1.0.19", + "@0x/asset-buyer": "^3.0.3", + "@0x/json-schemas": "^2.1.3", + "@0x/order-utils": "^3.0.6", + "@0x/subproviders": "^2.1.7", + "@0x/types": "^1.4.0", + "@0x/typescript-typings": "^3.0.5", + "@0x/utils": "^2.0.7", + "@0x/web3-wrapper": "^3.2.0", "bowser": "^1.9.4", "copy-to-clipboard": "^3.0.8", - "ethereum-types": "^1.1.2", + "ethereum-types": "^1.1.3", "lodash": "^4.17.5", "polished": "^2.2.0", "react": "^16.5.2", -- cgit From aeefdeaef78fad38b84e728cceff2141eb302ab5 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 09:25:48 -0800 Subject: Remove unused util --- packages/instant/src/util/buy_quote.ts | 36 ---------------------------------- 1 file changed, 36 deletions(-) delete mode 100644 packages/instant/src/util/buy_quote.ts (limited to 'packages/instant') diff --git a/packages/instant/src/util/buy_quote.ts b/packages/instant/src/util/buy_quote.ts deleted file mode 100644 index 0e880f51c..000000000 --- a/packages/instant/src/util/buy_quote.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { BuyQuoteInfo } from '@0x/asset-buyer'; -import { BigNumber } from '@0x/utils'; -import * as _ from 'lodash'; -import { oc } from 'ts-optchain'; - -import { BIG_NUMBER_ZERO } from '../constants'; - -export interface BuyQuoteWeiAmounts { - assetTotalInWei: BigNumber | undefined; - feeTotalInWei: BigNumber | undefined; - grandTotalInWei: BigNumber | undefined; - pricePerTokenInWei: BigNumber | undefined; -} - -export const buyQuoteUtil = { - getWeiAmounts: ( - selectedAssetUnitAmount: BigNumber | undefined, - buyQuoteInfo: BuyQuoteInfo | undefined, - ): BuyQuoteWeiAmounts => { - const buyQuoteAccessor = oc(buyQuoteInfo); - const assetTotalInWei = buyQuoteAccessor.assetEthAmount(); - const pricePerTokenInWei = - !_.isUndefined(assetTotalInWei) && - !_.isUndefined(selectedAssetUnitAmount) && - !selectedAssetUnitAmount.eq(BIG_NUMBER_ZERO) - ? assetTotalInWei.div(selectedAssetUnitAmount).ceil() - : undefined; - - return { - assetTotalInWei, - feeTotalInWei: buyQuoteAccessor.feeEthAmount(), - grandTotalInWei: buyQuoteAccessor.totalEthAmount(), - pricePerTokenInWei, - }; - }, -}; -- cgit From 8a5609718aa6e31e30915300e38e47d30d528896 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 09:26:00 -0800 Subject: Refactor BaseCurrencyChoice to be done in helper function --- packages/instant/src/components/order_details.tsx | 46 ++++++++++------------- 1 file changed, 19 insertions(+), 27 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 7e33e06ac..298bd86c9 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -15,20 +15,6 @@ import { Container } from './ui/container'; import { Flex } from './ui/flex'; import { Text, TextProps } from './ui/text'; -interface BaseCurryChoiceProps { - currencyName: string; - onClick: () => void; - isSelected: boolean; -} -const BaseCurrencyChoice: React.StatelessComponent = props => { - const textStyle: TextProps = { onClick: props.onClick, fontSize: '12px' }; - if (props.isSelected) { - textStyle.fontColor = ColorOption.primaryColor; - textStyle.fontWeight = 700; - } - return {props.currencyName}; -}; - export interface OrderDetailsProps { buyQuoteInfo?: BuyQuoteInfo; selectedAssetUnitAmount?: BigNumber; @@ -41,7 +27,7 @@ export interface OrderDetailsProps { } export class OrderDetails extends React.Component { public render(): React.ReactNode { - const { baseCurrency, buyQuoteInfo } = this.props; + const { buyQuoteInfo } = this.props; return ( @@ -82,7 +68,7 @@ export class OrderDetails extends React.Component { } private _displayAmountOrPlaceholder(weiAmount?: BigNumber): React.ReactNode { - const { baseCurrency, ethUsdPrice, isLoading } = this.props; + const { baseCurrency, isLoading } = this.props; if (_.isUndefined(weiAmount)) { return ( @@ -105,7 +91,7 @@ export class OrderDetails extends React.Component { } private _assetLabelText(): string { - const { assetName, baseCurrency, ethUsdPrice } = this.props; + const { assetName, baseCurrency } = this.props; const numTokens = this.props.selectedAssetUnitAmount; // Display as 0 if we have a selected asset @@ -142,6 +128,20 @@ export class OrderDetails extends React.Component { : undefined; } + private _baseCurrencyChoice(choice: BaseCurrency): React.ReactNode { + const onClick = + choice === BaseCurrency.ETH ? this.props.onBaseCurrencySwitchEth : this.props.onBaseCurrencySwitchUsd; + const isSelected = this.props.baseCurrency === choice; + + const textStyle: TextProps = { onClick, fontSize: '12px ' }; + if (isSelected) { + textStyle.fontColor = ColorOption.primaryColor; + textStyle.fontWeight = 700; + } + + return {choice}; + } + private _renderHeader(): React.ReactNode { return ( @@ -156,19 +156,11 @@ export class OrderDetails extends React.Component { - + {this._baseCurrencyChoice(BaseCurrency.ETH)} / - + {this._baseCurrencyChoice(BaseCurrency.USD)} ); -- cgit From 99941972a3965f27b3607a382a476b79722151fc Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 09:29:23 -0800 Subject: Small clean up --- packages/instant/src/components/order_details.tsx | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 298bd86c9..cbe36be64 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -34,7 +34,7 @@ export class OrderDetails extends React.Component { {this._renderHeader()} { } } - private _assetLabelText(): string { + private _assetAmountLabel(): string { const { assetName, baseCurrency } = this.props; const numTokens = this.props.selectedAssetUnitAmount; @@ -99,21 +99,17 @@ export class OrderDetails extends React.Component { assetName && assetName !== DEFAULT_UNKOWN_ASSET_NAME && _.isUndefined(numTokens) ? new BigNumber(0) : numTokens; - if (!_.isUndefined(displayNumTokens)) { let numTokensWithSymbol = displayNumTokens.toString(); - if (assetName) { numTokensWithSymbol += ` ${assetName}`; } - const pricePerTokenWei = this._pricePerTokenWei(); if (pricePerTokenWei) { numTokensWithSymbol += ` @ ${this._displayAmount(baseCurrency, pricePerTokenWei)}`; } return numTokensWithSymbol; } - return 'Token Amount'; } @@ -138,7 +134,6 @@ export class OrderDetails extends React.Component { textStyle.fontColor = ColorOption.primaryColor; textStyle.fontWeight = 700; } - return {choice}; } @@ -154,7 +149,6 @@ export class OrderDetails extends React.Component { > Order Details - {this._baseCurrencyChoice(BaseCurrency.ETH)} @@ -179,28 +173,21 @@ export class OrderDetailsRow extends React.Component { return ( - {this._renderLabel()} + + {this.props.labelText} + {this._renderValues()} ); } - private _renderLabel(): React.ReactNode { - return ( - - {this.props.labelText} - - ); - } - private _renderValues(): React.ReactNode { const secondaryValueNode: React.ReactNode = this.props.secondaryValue && ( ({this.props.secondaryValue}) ); - return ( {secondaryValueNode} -- cgit From aa8dfa88e113ca7a98887ed77dc8eb3ad39e5f41 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 09:37:39 -0800 Subject: Make primary value in total cost bold --- packages/instant/src/components/order_details.tsx | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index cbe36be64..537b9ee4e 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -45,6 +45,7 @@ export class OrderDetails extends React.Component { labelText="Total Cost" isLabelBold={true} primaryValue={this._displayAmountOrPlaceholder(buyQuoteInfo && buyQuoteInfo.totalEthAmount)} + isPrimaryValueBold={true} secondaryValue={this._totalCostSecondaryValue()} /> -- cgit From fb99b5ce9d3639e1584214828216879f99dfa020 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 09:51:15 -0800 Subject: Show error when fetching usd prices --- packages/instant/src/components/order_details.tsx | 36 ++++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 537b9ee4e..ea975a5f7 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -27,12 +27,19 @@ export interface OrderDetailsProps { } export class OrderDetails extends React.Component { public render(): React.ReactNode { - const { buyQuoteInfo } = this.props; - + const showUsdError = this.props.baseCurrency === BaseCurrency.USD && this._hadErrorFetchingUsdPrice(); return ( {this._renderHeader()} + {showUsdError ? this._renderErrorFetchingUsdPrice() : this._renderRows()} + + ); + } + private _renderRows(): React.ReactNode { + const { buyQuoteInfo } = this.props; + return ( + { isPrimaryValueBold={true} secondaryValue={this._totalCostSecondaryValue()} /> - + ); } + private _renderErrorFetchingUsdPrice(): React.ReactNode { + return ( + + There was an error fetching the USD price. + + Click here + + {' to view ETH prices'} + + ); + } + + private _hadErrorFetchingUsdPrice(): boolean { + return this.props.ethUsdPrice === BIG_NUMBER_ZERO; + } + private _totalCostSecondaryValue(): React.ReactNode { const secondaryCurrency = this.props.baseCurrency === BaseCurrency.USD ? BaseCurrency.ETH : BaseCurrency.USD; @@ -92,7 +119,8 @@ export class OrderDetails extends React.Component { } private _assetAmountLabel(): string { - const { assetName, baseCurrency } = this.props; + const { assetName, baseCurrency, ethUsdPrice } = this.props; + const numTokens = this.props.selectedAssetUnitAmount; // Display as 0 if we have a selected asset -- cgit From 0690e68a833e0ca75d31614621aa0278009cc10c Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 09:54:06 -0800 Subject: Change base currency to ETH if we can't get USD price --- packages/instant/src/redux/async_data.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/redux/async_data.ts b/packages/instant/src/redux/async_data.ts index c67b222d1..8ef95add4 100644 --- a/packages/instant/src/redux/async_data.ts +++ b/packages/instant/src/redux/async_data.ts @@ -4,7 +4,7 @@ import * as _ from 'lodash'; import { Dispatch } from 'redux'; import { BIG_NUMBER_ZERO } from '../constants'; -import { AccountState, ERC20Asset, OrderProcessState, ProviderState, QuoteFetchOrigin } from '../types'; +import { AccountState, BaseCurrency, ERC20Asset, OrderProcessState, ProviderState, QuoteFetchOrigin } from '../types'; import { analytics } from '../util/analytics'; import { assetUtils } from '../util/asset'; import { buyQuoteUpdater } from '../util/buy_quote_updater'; @@ -24,6 +24,7 @@ export const asyncData = { const errorMessage = 'Error fetching ETH/USD price'; errorFlasher.flashNewErrorMessage(dispatch, errorMessage); dispatch(actions.updateEthUsdPrice(BIG_NUMBER_ZERO)); + dispatch(actions.updateBaseCurrency(BaseCurrency.ETH)); errorReporter.report(e); } }, -- cgit From 68faaaba5f4278d7a1bd5d02f97921fa3c4238f4 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 10:04:23 -0800 Subject: Analytics events for ETH/USD toggle and failure to fetch eth usd price --- packages/instant/src/components/zero_ex_instant_provider.tsx | 1 + packages/instant/src/redux/analytics_middleware.ts | 3 +++ packages/instant/src/redux/async_data.ts | 1 + packages/instant/src/util/analytics.ts | 9 +++++++++ 4 files changed, 14 insertions(+) (limited to 'packages/instant') diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index 204115fa9..2de327cd7 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -122,6 +122,7 @@ export class ZeroExInstantProvider extends React.Component next => middlewareAction analytics.trackInstallWalletModalClosed(); } break; + case ActionTypes.UPDATE_BASE_CURRENCY: + analytics.trackBaseCurrencyChanged(curState.baseCurrency); + analytics.addEventProperties({ baseCurrency: curState.baseCurrency }); } return nextAction; diff --git a/packages/instant/src/redux/async_data.ts b/packages/instant/src/redux/async_data.ts index 8ef95add4..3961d8821 100644 --- a/packages/instant/src/redux/async_data.ts +++ b/packages/instant/src/redux/async_data.ts @@ -26,6 +26,7 @@ export const asyncData = { dispatch(actions.updateEthUsdPrice(BIG_NUMBER_ZERO)); dispatch(actions.updateBaseCurrency(BaseCurrency.ETH)); errorReporter.report(e); + analytics.trackUsdPriceFailed(); } }, fetchAvailableAssetDatasAndDispatchToStore: async (state: State, dispatch: Dispatch) => { diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index e6128f857..6c63907dc 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -6,6 +6,7 @@ import { GIT_SHA, HEAP_ENABLED, INSTANT_DISCHARGE_TARGET, NODE_ENV, NPM_PACKAGE_ import { AffiliateInfo, Asset, + BaseCurrency, Network, OrderProcessState, OrderSource, @@ -37,6 +38,7 @@ enum EventNames { ACCOUNT_UNLOCK_REQUESTED = 'Account - Unlock Requested', ACCOUNT_UNLOCK_DENIED = 'Account - Unlock Denied', ACCOUNT_ADDRESS_CHANGED = 'Account - Address Changed', + BASE_CURRENCY_CHANGED = 'Base Currency - Changed', PAYMENT_METHOD_DROPDOWN_OPENED = 'Payment Method - Dropdown Opened', PAYMENT_METHOD_OPENED_ETHERSCAN = 'Payment Method - Opened Etherscan', PAYMENT_METHOD_COPIED_ADDRESS = 'Payment Method - Copied Address', @@ -47,6 +49,7 @@ enum EventNames { BUY_TX_SUBMITTED = 'Buy - Tx Submitted', BUY_TX_SUCCEEDED = 'Buy - Tx Succeeded', BUY_TX_FAILED = 'Buy - Tx Failed', + USD_PRICE_FETCH_FAILED = 'USD Price - Fetch Failed', INSTALL_WALLET_CLICKED = 'Install Wallet - Clicked', INSTALL_WALLET_MODAL_OPENED = 'Install Wallet - Modal - Opened', INSTALL_WALLET_MODAL_CLICKED_EXPLANATION = 'Install Wallet - Modal - Clicked Explanation', @@ -118,6 +121,7 @@ export interface AnalyticsEventOptions { selectedAssetSymbol?: string; selectedAssetData?: string; selectedAssetDecimals?: number; + baseCurrency?: string; } export enum TokenSelectorClosedVia { ClickedX = 'Clicked X', @@ -141,6 +145,7 @@ export const analytics = { window: Window, selectedAsset?: Asset, affiliateInfo?: AffiliateInfo, + baseCurrency?: BaseCurrency, ): AnalyticsEventOptions => { const affiliateAddress = affiliateInfo ? affiliateInfo.feeRecipient : 'none'; const affiliateFeePercent = affiliateInfo ? parseFloat(affiliateInfo.feePercentage.toFixed(4)) : 0; @@ -159,6 +164,7 @@ export const analytics = { selectedAssetName: selectedAsset ? selectedAsset.metaData.name : 'none', selectedAssetData: selectedAsset ? selectedAsset.assetData : 'none', instantEnvironment: INSTANT_DISCHARGE_TARGET || `Local ${NODE_ENV}`, + baseCurrency, }; return eventOptions; }, @@ -170,6 +176,8 @@ export const analytics = { trackAccountUnlockDenied: trackingEventFnWithoutPayload(EventNames.ACCOUNT_UNLOCK_DENIED), trackAccountAddressChanged: (address: string) => trackingEventFnWithPayload(EventNames.ACCOUNT_ADDRESS_CHANGED)({ address }), + trackBaseCurrencyChanged: (currencyChangedTo: BaseCurrency) => + trackingEventFnWithPayload(EventNames.BASE_CURRENCY_CHANGED)({ currencyChangedTo }), trackPaymentMethodDropdownOpened: trackingEventFnWithoutPayload(EventNames.PAYMENT_METHOD_DROPDOWN_OPENED), trackPaymentMethodOpenedEtherscan: trackingEventFnWithoutPayload(EventNames.PAYMENT_METHOD_OPENED_ETHERSCAN), trackPaymentMethodCopiedAddress: trackingEventFnWithoutPayload(EventNames.PAYMENT_METHOD_COPIED_ADDRESS), @@ -230,4 +238,5 @@ export const analytics = { fetchOrigin, }); }, + trackUsdPriceFailed: trackingEventFnWithoutPayload(EventNames.USD_PRICE_FETCH_FAILED), }; -- cgit From 756dc1e95ebbb8ef73ff8f712062997ea3d8c45e Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 10:07:45 -0800 Subject: Linting --- packages/instant/src/components/order_details.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index ea975a5f7..c069a8bcc 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -27,11 +27,11 @@ export interface OrderDetailsProps { } export class OrderDetails extends React.Component { public render(): React.ReactNode { - const showUsdError = this.props.baseCurrency === BaseCurrency.USD && this._hadErrorFetchingUsdPrice(); + const shouldShowUsdError = this.props.baseCurrency === BaseCurrency.USD && this._hadErrorFetchingUsdPrice(); return ( {this._renderHeader()} - {showUsdError ? this._renderErrorFetchingUsdPrice() : this._renderRows()} + {shouldShowUsdError ? this._renderErrorFetchingUsdPrice() : this._renderRows()} ); } @@ -119,8 +119,7 @@ export class OrderDetails extends React.Component { } private _assetAmountLabel(): string { - const { assetName, baseCurrency, ethUsdPrice } = this.props; - + const { assetName, baseCurrency } = this.props; const numTokens = this.props.selectedAssetUnitAmount; // Display as 0 if we have a selected asset -- cgit From 65579c023670c09f39b4f7a733d7b703888d9d99 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 13:43:08 -0800 Subject: Abstract SectionHeader and make 12px per Chris's comment and figma design --- packages/instant/src/components/order_details.tsx | 21 +++++++++------------ packages/instant/src/components/payment_method.tsx | 11 ++--------- packages/instant/src/components/section_header.tsx | 22 ++++++++++++++++++++++ 3 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 packages/instant/src/components/section_header.tsx (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index c069a8bcc..4aa375017 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -10,6 +10,7 @@ import { BaseCurrency } from '../types'; import { format } from '../util/format'; import { AmountPlaceholder } from './amount_placeholder'; +import { SectionHeader } from './section_header'; import { Container } from './ui/container'; import { Flex } from './ui/flex'; @@ -157,10 +158,12 @@ export class OrderDetails extends React.Component { choice === BaseCurrency.ETH ? this.props.onBaseCurrencySwitchEth : this.props.onBaseCurrencySwitchUsd; const isSelected = this.props.baseCurrency === choice; - const textStyle: TextProps = { onClick, fontSize: '12px ' }; + const textStyle: TextProps = { onClick, fontSize: '12px' }; if (isSelected) { textStyle.fontColor = ColorOption.primaryColor; textStyle.fontWeight = 700; + } else { + textStyle.fontColor = ColorOption.lightGrey; } return {choice}; } @@ -168,19 +171,13 @@ export class OrderDetails extends React.Component { private _renderHeader(): React.ReactNode { return ( - - Order Details - + Order Details {this._baseCurrencyChoice(BaseCurrency.ETH)} - - / + + + / + {this._baseCurrencyChoice(BaseCurrency.USD)} diff --git a/packages/instant/src/components/payment_method.tsx b/packages/instant/src/components/payment_method.tsx index 7c93f1d1c..abadf4bd6 100644 --- a/packages/instant/src/components/payment_method.tsx +++ b/packages/instant/src/components/payment_method.tsx @@ -8,6 +8,7 @@ import { envUtil } from '../util/env'; import { CoinbaseWalletLogo } from './coinbase_wallet_logo'; import { MetaMaskLogo } from './meta_mask_logo'; import { PaymentMethodDropdown } from './payment_method_dropdown'; +import { SectionHeader } from './section_header'; import { Circle } from './ui/circle'; import { Container } from './ui/container'; import { Flex } from './ui/flex'; @@ -29,15 +30,7 @@ export class PaymentMethod extends React.Component { - - {this._renderTitleText()} - + {this._renderTitleText()} {this._renderTitleLabel()} diff --git a/packages/instant/src/components/section_header.tsx b/packages/instant/src/components/section_header.tsx new file mode 100644 index 000000000..a6be3d8af --- /dev/null +++ b/packages/instant/src/components/section_header.tsx @@ -0,0 +1,22 @@ +import * as React from 'react'; + +import { ColorOption } from '../style/theme'; + +import { Text } from './ui/text'; + +export interface SectionHeaderProps { + children?: React.ReactNode; +} +export const SectionHeader: React.StatelessComponent<{}> = props => { + return ( + + {props.children} + + ); +}; -- cgit From 9e5e1f568ba71927cec2255bf779322edb6f7d07 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 14:25:56 -0800 Subject: show as <$0.01 when less than a cent in USD, and also show 1 significant digit if rounded amount is 0 --- packages/instant/src/util/format.ts | 15 ++++++++++++--- packages/instant/test/util/format.test.ts | 10 ++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/util/format.ts b/packages/instant/src/util/format.ts index e9c432b2f..3aaf9a3a7 100644 --- a/packages/instant/src/util/format.ts +++ b/packages/instant/src/util/format.ts @@ -2,7 +2,7 @@ import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; -import { ETH_DECIMALS } from '../constants'; +import { BIG_NUMBER_ZERO, ETH_DECIMALS } from '../constants'; export const format = { ethBaseUnitAmount: ( @@ -25,7 +25,10 @@ export const format = { return defaultText; } const roundedAmount = ethUnitAmount.round(decimalPlaces).toDigits(decimalPlaces); - return `${roundedAmount} ETH`; + // Sometimes for small ETH amounts (i.e. 0.000045) the amount rounded to 4 decimalPlaces is 0 + // If that is the case, show to 1 significant digit + const displayAmount = roundedAmount.eq(BIG_NUMBER_ZERO) ? ethUnitAmount.toPrecision(1) : roundedAmount; + return `${displayAmount} ETH`; }, ethBaseUnitAmountInUsd: ( ethBaseUnitAmount?: BigNumber, @@ -48,7 +51,13 @@ export const format = { if (_.isUndefined(ethUnitAmount) || _.isUndefined(ethUsdPrice)) { return defaultText; } - return `$${ethUnitAmount.mul(ethUsdPrice).toFixed(decimalPlaces)}`; + const rawUsdPrice = ethUnitAmount.mul(ethUsdPrice); + const roundedUsdPrice = rawUsdPrice.toFixed(decimalPlaces); + if (roundedUsdPrice === '0.00' && rawUsdPrice.gt(BIG_NUMBER_ZERO)) { + return '<$0.01'; + } else { + return `$${roundedUsdPrice}`; + } }, ethAddress: (address: string): string => { return `0x${address.slice(2, 7)}…${address.slice(-5)}`; diff --git a/packages/instant/test/util/format.test.ts b/packages/instant/test/util/format.test.ts index fe0a63e6e..b74d6cdaa 100644 --- a/packages/instant/test/util/format.test.ts +++ b/packages/instant/test/util/format.test.ts @@ -41,6 +41,10 @@ describe('format', () => { it('converts BigNumber(5.3014059295032) to the string `5.301 ETH`', () => { expect(format.ethUnitAmount(BIG_NUMBER_IRRATIONAL)).toBe('5.301 ETH'); }); + it('shows 1 significant digit when rounded amount would be 0', () => { + expect(format.ethUnitAmount(new BigNumber(0.00000045))).toBe('0.0000005 ETH'); + expect(format.ethUnitAmount(new BigNumber(0.00000044))).toBe('0.0000004 ETH'); + }); it('returns defaultText param when ethUnitAmount is not defined', () => { const defaultText = 'defaultText'; expect(format.ethUnitAmount(undefined, 4, defaultText)).toBe(defaultText); @@ -86,6 +90,12 @@ describe('format', () => { it('correctly formats 5.3014059295032 ETH to usd according to some price', () => { expect(format.ethUnitAmountInUsd(BIG_NUMBER_IRRATIONAL, BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe('$13.43'); }); + it('correctly formats amount that is less than 1 cent', () => { + expect(format.ethUnitAmountInUsd(new BigNumber(0.000001), BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe('<$0.01'); + }); + it('correctly formats exactly 1 cent', () => { + expect(format.ethUnitAmountInUsd(new BigNumber(0.0039), BIG_NUMBER_FAKE_ETH_USD_PRICE)).toBe('$0.01'); + }); it('returns defaultText param when ethUnitAmountInUsd or ethUsdPrice is not defined', () => { const defaultText = 'defaultText'; expect(format.ethUnitAmountInUsd(undefined, undefined, 2, defaultText)).toBe(defaultText); -- cgit From 2e7d363f2cf76e383bb8723cfb0f2e3c1e4783d8 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 15:46:46 -0800 Subject: Use helper function to check for error --- packages/instant/src/components/order_details.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 4aa375017..6ce19742f 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -85,9 +85,7 @@ export class OrderDetails extends React.Component { const canDisplayCurrency = secondaryCurrency === BaseCurrency.ETH || - (secondaryCurrency === BaseCurrency.USD && - this.props.ethUsdPrice && - this.props.ethUsdPrice.greaterThan(BIG_NUMBER_ZERO)); + (secondaryCurrency === BaseCurrency.USD && this.props.ethUsdPrice && !this._hadErrorFetchingUsdPrice); if (this.props.buyQuoteInfo && canDisplayCurrency) { return this._displayAmount(secondaryCurrency, this.props.buyQuoteInfo.totalEthAmount); -- cgit From 167a3fbc112120b6a583f3ec3c8fdd70d39df078 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 15:57:28 -0800 Subject: Use BN equals and call function --- packages/instant/src/components/order_details.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 6ce19742f..96bdb7150 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -77,7 +77,7 @@ export class OrderDetails extends React.Component { } private _hadErrorFetchingUsdPrice(): boolean { - return this.props.ethUsdPrice === BIG_NUMBER_ZERO; + return this.props.ethUsdPrice ? this.props.ethUsdPrice.equals(BIG_NUMBER_ZERO) : false; } private _totalCostSecondaryValue(): React.ReactNode { @@ -85,7 +85,7 @@ export class OrderDetails extends React.Component { const canDisplayCurrency = secondaryCurrency === BaseCurrency.ETH || - (secondaryCurrency === BaseCurrency.USD && this.props.ethUsdPrice && !this._hadErrorFetchingUsdPrice); + (secondaryCurrency === BaseCurrency.USD && this.props.ethUsdPrice && !this._hadErrorFetchingUsdPrice()); if (this.props.buyQuoteInfo && canDisplayCurrency) { return this._displayAmount(secondaryCurrency, this.props.buyQuoteInfo.totalEthAmount); -- cgit From 8d54772389b28dec021aa81423ac84795e132581 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 17:34:14 -0800 Subject: show < 0.00001 ETH when amount gets really small --- packages/instant/src/util/format.ts | 21 ++++++++++++++++----- packages/instant/test/util/format.test.ts | 12 ++++++++++-- 2 files changed, 26 insertions(+), 7 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/util/format.ts b/packages/instant/src/util/format.ts index 3aaf9a3a7..4adb63e21 100644 --- a/packages/instant/src/util/format.ts +++ b/packages/instant/src/util/format.ts @@ -20,14 +20,24 @@ export const format = { ethUnitAmount?: BigNumber, decimalPlaces: number = 4, defaultText: React.ReactNode = '0 ETH', + minUnitAmountToDisplay: BigNumber = new BigNumber('0.00001'), ): React.ReactNode => { if (_.isUndefined(ethUnitAmount)) { return defaultText; } - const roundedAmount = ethUnitAmount.round(decimalPlaces).toDigits(decimalPlaces); - // Sometimes for small ETH amounts (i.e. 0.000045) the amount rounded to 4 decimalPlaces is 0 - // If that is the case, show to 1 significant digit - const displayAmount = roundedAmount.eq(BIG_NUMBER_ZERO) ? ethUnitAmount.toPrecision(1) : roundedAmount; + let roundedAmount = ethUnitAmount.round(decimalPlaces).toDigits(decimalPlaces); + + if (roundedAmount.eq(BIG_NUMBER_ZERO) && ethUnitAmount.greaterThan(BIG_NUMBER_ZERO)) { + // Sometimes for small ETH amounts (i.e. 0.000045) the amount rounded to 4 decimalPlaces is 0 + // If that is the case, show to 1 significant digit + roundedAmount = new BigNumber(ethUnitAmount.toPrecision(1)); + } + + const displayAmount = + roundedAmount.greaterThan(BIG_NUMBER_ZERO) && roundedAmount.lessThan(minUnitAmountToDisplay) + ? `< ${minUnitAmountToDisplay.toString()}` + : roundedAmount.toString(); + return `${displayAmount} ETH`; }, ethBaseUnitAmountInUsd: ( @@ -35,12 +45,13 @@ export const format = { ethUsdPrice?: BigNumber, decimalPlaces: number = 2, defaultText: React.ReactNode = '$0.00', + minUnitAmountToDisplay: BigNumber = new BigNumber('0.00001'), ): React.ReactNode => { if (_.isUndefined(ethBaseUnitAmount) || _.isUndefined(ethUsdPrice)) { return defaultText; } const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseUnitAmount, ETH_DECIMALS); - return format.ethUnitAmountInUsd(ethUnitAmount, ethUsdPrice, decimalPlaces); + return format.ethUnitAmountInUsd(ethUnitAmount, ethUsdPrice, decimalPlaces, minUnitAmountToDisplay); }, ethUnitAmountInUsd: ( ethUnitAmount?: BigNumber, diff --git a/packages/instant/test/util/format.test.ts b/packages/instant/test/util/format.test.ts index b74d6cdaa..38bf356ec 100644 --- a/packages/instant/test/util/format.test.ts +++ b/packages/instant/test/util/format.test.ts @@ -42,8 +42,16 @@ describe('format', () => { expect(format.ethUnitAmount(BIG_NUMBER_IRRATIONAL)).toBe('5.301 ETH'); }); it('shows 1 significant digit when rounded amount would be 0', () => { - expect(format.ethUnitAmount(new BigNumber(0.00000045))).toBe('0.0000005 ETH'); - expect(format.ethUnitAmount(new BigNumber(0.00000044))).toBe('0.0000004 ETH'); + expect(format.ethUnitAmount(new BigNumber(0.00003))).toBe('0.00003 ETH'); + expect(format.ethUnitAmount(new BigNumber(0.000034))).toBe('0.00003 ETH'); + expect(format.ethUnitAmount(new BigNumber(0.000035))).toBe('0.00004 ETH'); + }); + it('shows < 0.00001 when hits threshold', () => { + expect(format.ethUnitAmount(new BigNumber(0.000011))).toBe('0.00001 ETH'); + expect(format.ethUnitAmount(new BigNumber(0.00001))).toBe('0.00001 ETH'); + expect(format.ethUnitAmount(new BigNumber(0.000009))).toBe('< 0.00001 ETH'); + expect(format.ethUnitAmount(new BigNumber(0.0000000009))).toBe('< 0.00001 ETH'); + expect(format.ethUnitAmount(new BigNumber(0))).toBe('0 ETH'); }); it('returns defaultText param when ethUnitAmount is not defined', () => { const defaultText = 'defaultText'; -- cgit From 193cd67d6bfffc35feccd46d5c1b5f23320dc8ce Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Wed, 12 Dec 2018 17:43:27 -0800 Subject: A little bit of scaling logic for not cutting off text --- packages/instant/src/components/instant_heading.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 816cc5c33..99e531574 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -113,20 +113,23 @@ export class InstantHeading extends React.Component { } private readonly _renderEthAmount = (): React.ReactNode => { + const ethAmount = format.ethBaseUnitAmount( + this.props.totalEthBaseUnitAmount, + 4, + , + ); + + const fontSize = typeof ethAmount === 'string' && ethAmount.length >= 13 ? '14px' : '16px'; return ( - {format.ethBaseUnitAmount( - this.props.totalEthBaseUnitAmount, - 4, - , - )} + {ethAmount} ); }; -- cgit From 9a1d2c055e176414ee1e7661d5acc764cc9a745d Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 13 Dec 2018 08:31:40 -0800 Subject: Fix SectionHeaderProps --- packages/instant/src/components/section_header.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/section_header.tsx b/packages/instant/src/components/section_header.tsx index a6be3d8af..d0974ebdc 100644 --- a/packages/instant/src/components/section_header.tsx +++ b/packages/instant/src/components/section_header.tsx @@ -4,10 +4,8 @@ import { ColorOption } from '../style/theme'; import { Text } from './ui/text'; -export interface SectionHeaderProps { - children?: React.ReactNode; -} -export const SectionHeader: React.StatelessComponent<{}> = props => { +export interface SectionHeaderProps {} +export const SectionHeader: React.StatelessComponent = props => { return ( Date: Thu, 13 Dec 2018 13:31:30 -0800 Subject: typeof -> isString --- packages/instant/src/components/instant_heading.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 99e531574..5b1f9592d 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -119,7 +119,7 @@ export class InstantHeading extends React.Component { , ); - const fontSize = typeof ethAmount === 'string' && ethAmount.length >= 13 ? '14px' : '16px'; + const fontSize = _.isString(ethAmount) && ethAmount.length >= 13 ? '14px' : '16px'; return ( Date: Thu, 13 Dec 2018 14:27:27 -0800 Subject: Show @ price in light grey --- packages/instant/src/components/order_details.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 96bdb7150..33a115044 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -117,7 +117,7 @@ export class OrderDetails extends React.Component { } } - private _assetAmountLabel(): string { + private _assetAmountLabel(): React.ReactNode { const { assetName, baseCurrency } = this.props; const numTokens = this.props.selectedAssetUnitAmount; @@ -127,13 +127,14 @@ export class OrderDetails extends React.Component { ? new BigNumber(0) : numTokens; if (!_.isUndefined(displayNumTokens)) { - let numTokensWithSymbol = displayNumTokens.toString(); + let numTokensWithSymbol: React.ReactNode = displayNumTokens.toString(); if (assetName) { numTokensWithSymbol += ` ${assetName}`; } const pricePerTokenWei = this._pricePerTokenWei(); if (pricePerTokenWei) { - numTokensWithSymbol += ` @ ${this._displayAmount(baseCurrency, pricePerTokenWei)}`; + const atPriceDisplay = @ {this._displayAmount(baseCurrency, pricePerTokenWei)}; + numTokensWithSymbol = {numTokensWithSymbol} {atPriceDisplay} } return numTokensWithSymbol; } @@ -185,7 +186,7 @@ export class OrderDetails extends React.Component { } export interface OrderDetailsRowProps { - labelText: string; + labelText: React.ReactNode; isLabelBold?: boolean; isPrimaryValueBold?: boolean; primaryValue: React.ReactNode; -- cgit From 926fcb296fb728c3520c638a43a5da950393832e Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Fri, 14 Dec 2018 14:06:24 -0800 Subject: fix(instant): treat executeBuyQuote errors as signature denials --- packages/instant/src/components/buy_button.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 1489b94d4..880303cc7 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -10,6 +10,7 @@ import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants' import { ColorOption } from '../style/theme'; import { AffiliateInfo, Asset, ZeroExInstantError } from '../types'; import { analytics } from '../util/analytics'; +import { errorReporter } from '../util/error_reporter'; import { gasPriceEstimator } from '../util/gas_price_estimator'; import { util } from '../util/util'; @@ -82,14 +83,17 @@ export class BuyButton extends React.Component { }); } catch (e) { if (e instanceof Error) { - if (e.message === AssetBuyerError.SignatureRequestDenied) { - analytics.trackBuySignatureDenied(buyQuote); - this.props.onSignatureDenied(buyQuote); - return; - } else if (e.message === AssetBuyerError.TransactionValueTooLow) { + if (e.message === AssetBuyerError.TransactionValueTooLow) { analytics.trackBuySimulationFailed(buyQuote); this.props.onValidationFail(buyQuote, AssetBuyerError.TransactionValueTooLow); return; + } else { + if (e.message !== AssetBuyerError.SignatureRequestDenied) { + errorReporter.report(e); + } + analytics.trackBuySignatureDenied(buyQuote); + this.props.onSignatureDenied(buyQuote); + return; } } throw e; -- cgit From 21a193e51650a78e59aaf6ae49b5120fb8b73e15 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Fri, 14 Dec 2018 14:10:15 -0800 Subject: feature(instant): add trust wallet detection --- packages/instant/src/constants.ts | 1 + packages/instant/src/types.ts | 1 + packages/instant/src/util/env.ts | 2 ++ 3 files changed, 4 insertions(+) (limited to 'packages/instant') diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index f83eb4ac7..6d3680dc1 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -71,5 +71,6 @@ export const PROVIDER_TYPE_TO_NAME: { [key in ProviderType]: string } = { [ProviderType.Mist]: 'Mist', [ProviderType.CoinbaseWallet]: 'Coinbase Wallet', [ProviderType.Parity]: 'Parity', + [ProviderType.TrustWallet]: 'Trust Wallet', [ProviderType.Fallback]: 'Fallback', }; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 1c7490e63..6374dda09 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -176,6 +176,7 @@ export enum ProviderType { Mist = 'MIST', CoinbaseWallet = 'COINBASE_WALLET', Cipher = 'CIPHER', + TrustWallet = 'TRUST_WALLET', Fallback = 'FALLBACK', } diff --git a/packages/instant/src/util/env.ts b/packages/instant/src/util/env.ts index 0fda0cc0e..0f0b472b2 100644 --- a/packages/instant/src/util/env.ts +++ b/packages/instant/src/util/env.ts @@ -44,6 +44,8 @@ export const envUtil = { getProviderType(provider: Provider): ProviderType | undefined { if (provider.constructor.name === 'EthereumProvider') { return ProviderType.Mist; + } else if (provider.constructor.name === 'TrustWeb3Provider') { + return ProviderType.TrustWallet; } else if ((provider as any).isParity) { return ProviderType.Parity; } else if ((provider as any).isMetaMask) { -- cgit From 67422db4bd0b194296a1a584af7ead089e281715 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 14 Dec 2018 15:58:23 -0800 Subject: fix semicolon and apply prettier --- packages/instant/src/components/order_details.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 33a115044..9c10ef9e6 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -133,8 +133,16 @@ export class OrderDetails extends React.Component { } const pricePerTokenWei = this._pricePerTokenWei(); if (pricePerTokenWei) { - const atPriceDisplay = @ {this._displayAmount(baseCurrency, pricePerTokenWei)}; - numTokensWithSymbol = {numTokensWithSymbol} {atPriceDisplay} + const atPriceDisplay = ( + + @ {this._displayAmount(baseCurrency, pricePerTokenWei)} + + ); + numTokensWithSymbol = ( + + {numTokensWithSymbol} {atPriceDisplay} + + ); } return numTokensWithSymbol; } -- cgit From 9b4d1a1e3876313bf36b692128b40647b9e491df Mon Sep 17 00:00:00 2001 From: fragosti Date: Fri, 14 Dec 2018 16:37:19 -0800 Subject: feat: update prod deploy destination --- packages/instant/.production.discharge.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/.production.discharge.json b/packages/instant/.production.discharge.json index 1ce39fdd8..c87f8b187 100644 --- a/packages/instant/.production.discharge.json +++ b/packages/instant/.production.discharge.json @@ -1,5 +1,5 @@ { - "domain": "instant.0xproject.com", + "domain": "instant.0x.org", "build_command": "dotenv yarn build -- --env.discharge_target=production", "upload_directory": "umd", "index_key": "instant.js", -- cgit From 2effc3e267f01e620c50622138d98381883d4c32 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 20 Dec 2018 14:10:29 -0800 Subject: fix(instant): use isTrust property to determine if provider is trust wallet --- packages/instant/src/util/env.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/util/env.ts b/packages/instant/src/util/env.ts index 0f0b472b2..aedf4f5d6 100644 --- a/packages/instant/src/util/env.ts +++ b/packages/instant/src/util/env.ts @@ -44,7 +44,7 @@ export const envUtil = { getProviderType(provider: Provider): ProviderType | undefined { if (provider.constructor.name === 'EthereumProvider') { return ProviderType.Mist; - } else if (provider.constructor.name === 'TrustWeb3Provider') { + } else if ((provider as any).isTrust) { return ProviderType.TrustWallet; } else if ((provider as any).isParity) { return ProviderType.Parity; -- cgit From 080c6d3146bee3691b6f3b9452be639354236e44 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 20 Dec 2018 14:32:11 -0800 Subject: fix(instant): catch unknown errors from executeBuyAsync, report them and show could not submit transaction --- packages/instant/src/components/buy_button.tsx | 9 +++++---- .../src/containers/selected_asset_buy_order_state_buttons.ts | 3 +++ packages/instant/src/types.ts | 1 + 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 880303cc7..ff1cda1e1 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -87,13 +87,14 @@ export class BuyButton extends React.Component { analytics.trackBuySimulationFailed(buyQuote); this.props.onValidationFail(buyQuote, AssetBuyerError.TransactionValueTooLow); return; - } else { - if (e.message !== AssetBuyerError.SignatureRequestDenied) { - errorReporter.report(e); - } + } else if (e.message === AssetBuyerError.SignatureRequestDenied) { analytics.trackBuySignatureDenied(buyQuote); this.props.onSignatureDenied(buyQuote); return; + } else { + errorReporter.report(e); + this.props.onValidationFail(buyQuote, ZeroExInstantError.CouldNotSubmitTransaction); + return; } } throw e; diff --git a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts index 80943a96f..4da99cf04 100644 --- a/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts +++ b/packages/instant/src/containers/selected_asset_buy_order_state_buttons.ts @@ -95,6 +95,9 @@ const mapDispatchToProps = ( if (error === ZeroExInstantError.InsufficientETH) { const errorMessage = "You don't have enough ETH"; errorFlasher.flashNewErrorMessage(dispatch, errorMessage); + } else if (error === ZeroExInstantError.CouldNotSubmitTransaction) { + const errorMessage = 'Could not submit transaction'; + errorFlasher.flashNewErrorMessage(dispatch, errorMessage); } else { errorFlasher.flashNewErrorMessage(dispatch); } diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 6374dda09..d217c1a4f 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -91,6 +91,7 @@ export enum Network { export enum ZeroExInstantError { AssetMetaDataNotAvailable = 'ASSET_META_DATA_NOT_AVAILABLE', InsufficientETH = 'INSUFFICIENT_ETH', + CouldNotSubmitTransaction = 'COULD_NOT_SUBMIT_TRANSACTION', } export type SimpleHandler = () => void; -- cgit From bbe9862aa6c0e495c58ee028d8e4964b63377d1c Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 20 Dec 2018 14:43:14 -0800 Subject: fix(instant): add analytics to unknown error on executeBuyAsync --- packages/instant/src/components/buy_button.tsx | 1 + 1 file changed, 1 insertion(+) (limited to 'packages/instant') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index ff1cda1e1..46d121611 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -93,6 +93,7 @@ export class BuyButton extends React.Component { return; } else { errorReporter.report(e); + analytics.trackBuySignatureDenied(buyQuote); this.props.onValidationFail(buyQuote, ZeroExInstantError.CouldNotSubmitTransaction); return; } -- cgit From b399aa25aa9386d388d31edb463e803c7c31a2db Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 20 Dec 2018 15:05:54 -0800 Subject: feat(instant): add new event for unknown buy errors --- packages/instant/src/components/buy_button.tsx | 2 +- packages/instant/src/util/analytics.ts | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 46d121611..5c9c28ae4 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -93,7 +93,7 @@ export class BuyButton extends React.Component { return; } else { errorReporter.report(e); - analytics.trackBuySignatureDenied(buyQuote); + analytics.trackBuyUnknownError(buyQuote, e.message); this.props.onValidationFail(buyQuote, ZeroExInstantError.CouldNotSubmitTransaction); return; } diff --git a/packages/instant/src/util/analytics.ts b/packages/instant/src/util/analytics.ts index e6128f857..21d3a4d9e 100644 --- a/packages/instant/src/util/analytics.ts +++ b/packages/instant/src/util/analytics.ts @@ -44,6 +44,7 @@ enum EventNames { BUY_STARTED = 'Buy - Started', BUY_SIGNATURE_DENIED = 'Buy - Signature Denied', BUY_SIMULATION_FAILED = 'Buy - Simulation Failed', + BUY_UNKNOWN_ERROR = 'Buy - Unknown Error', BUY_TX_SUBMITTED = 'Buy - Tx Submitted', BUY_TX_SUCCEEDED = 'Buy - Tx Succeeded', BUY_TX_FAILED = 'Buy - Tx Failed', @@ -181,6 +182,11 @@ export const analytics = { trackingEventFnWithPayload(EventNames.BUY_SIGNATURE_DENIED)(buyQuoteEventProperties(buyQuote)), trackBuySimulationFailed: (buyQuote: BuyQuote) => trackingEventFnWithPayload(EventNames.BUY_SIMULATION_FAILED)(buyQuoteEventProperties(buyQuote)), + trackBuyUnknownError: (buyQuote: BuyQuote, errorMessage: string) => + trackingEventFnWithPayload(EventNames.BUY_UNKNOWN_ERROR)({ + ...buyQuoteEventProperties(buyQuote), + errorMessage, + }), trackBuyTxSubmitted: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => trackingEventFnWithPayload(EventNames.BUY_TX_SUBMITTED)({ ...buyQuoteEventProperties(buyQuote), -- cgit