aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant
diff options
context:
space:
mode:
Diffstat (limited to 'packages/instant')
-rw-r--r--packages/instant/src/components/instant_heading.tsx22
-rw-r--r--packages/instant/src/containers/selected_asset_amount_input.ts24
-rw-r--r--packages/instant/src/containers/selected_asset_instant_heading.ts3
-rw-r--r--packages/instant/src/redux/actions.ts4
-rw-r--r--packages/instant/src/redux/reducer.ts17
-rw-r--r--packages/instant/src/types.ts8
6 files changed, 60 insertions, 18 deletions
diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx
index 492c1b2c0..848056800 100644
--- a/packages/instant/src/components/instant_heading.tsx
+++ b/packages/instant/src/components/instant_heading.tsx
@@ -4,6 +4,7 @@ import * as React from 'react';
import { SelectedAssetAmountInput } from '../containers/selected_asset_amount_input';
import { ColorOption } from '../style/theme';
+import { AsyncProcessState } from '../types';
import { format } from '../util/format';
import { Container, Flex, Text } from './ui';
@@ -12,20 +13,33 @@ export interface InstantHeadingProps {
selectedAssetAmount?: BigNumber;
totalEthBaseAmount?: BigNumber;
ethUsdPrice?: BigNumber;
+ quoteState: AsyncProcessState;
}
const displaytotalEthBaseAmount = ({ selectedAssetAmount, totalEthBaseAmount }: InstantHeadingProps): string => {
if (_.isUndefined(selectedAssetAmount)) {
return '0 ETH';
}
- return format.ethBaseAmount(totalEthBaseAmount, 4, '...loading');
+ return format.ethBaseAmount(totalEthBaseAmount, 4, '-');
};
const displayUsdAmount = ({ totalEthBaseAmount, selectedAssetAmount, ethUsdPrice }: InstantHeadingProps): string => {
if (_.isUndefined(selectedAssetAmount)) {
return '$0.00';
}
- return format.ethBaseAmountInUsd(totalEthBaseAmount, ethUsdPrice, 2, '...loading');
+ return format.ethBaseAmountInUsd(totalEthBaseAmount, ethUsdPrice, 2, '-');
+};
+
+const loadingOrAmount = (quoteState: AsyncProcessState, amount: string): React.ReactNode => {
+ if (quoteState === AsyncProcessState.PENDING) {
+ return (
+ <Text fontWeight="bold" fontColor={ColorOption.white}>
+ &hellip;loading
+ </Text>
+ );
+ } else {
+ return amount;
+ }
};
export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = props => (
@@ -47,11 +61,11 @@ export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = pro
<Flex direction="column" justify="space-between">
<Container marginBottom="5px">
<Text fontSize="16px" fontColor={ColorOption.white} fontWeight={500}>
- {displaytotalEthBaseAmount(props)}
+ {loadingOrAmount(props.quoteState, displaytotalEthBaseAmount(props))}
</Text>
</Container>
<Text fontSize="16px" fontColor={ColorOption.white} opacity={0.7}>
- {displayUsdAmount(props)}
+ {loadingOrAmount(props.quoteState, displayUsdAmount(props))}
</Text>
</Flex>
</Flex>
diff --git a/packages/instant/src/containers/selected_asset_amount_input.ts b/packages/instant/src/containers/selected_asset_amount_input.ts
index 0d2c6dd7b..87bb0e335 100644
--- a/packages/instant/src/containers/selected_asset_amount_input.ts
+++ b/packages/instant/src/containers/selected_asset_amount_input.ts
@@ -37,24 +37,25 @@ const mapStateToProps = (state: State, _ownProps: SelectedAssetAmountInputProps)
const updateBuyQuoteAsync = async (
dispatch: Dispatch<Action>,
- assetData?: string,
- assetAmount?: BigNumber,
+ assetData: string,
+ assetAmount: BigNumber,
): Promise<void> => {
- if (_.isUndefined(assetAmount) || _.isUndefined(assetData)) {
- return;
- }
// get a new buy quote.
const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, zrxDecimals);
+ // mark quote as pending
+ dispatch(actions.updateBuyQuoteStatePending());
+
let newBuyQuote: BuyQuote | undefined;
try {
newBuyQuote = await assetBuyer.getBuyQuoteAsync(assetData, baseUnitValue);
- errorUtil.errorFlasher.clearError(dispatch);
} catch (error) {
+ dispatch(actions.updateBuyQuoteStateFailure());
errorUtil.errorFlasher.flashNewError(dispatch, error);
return;
}
-
+ // We have a successful new buy quote
+ errorUtil.errorFlasher.clearError(dispatch);
// invalidate the last buy quote.
dispatch(actions.updateLatestBuyQuote(newBuyQuote));
};
@@ -72,8 +73,13 @@ const mapDispatchToProps = (
dispatch(actions.updateLatestBuyQuote(undefined));
// reset our buy state
dispatch(actions.updateSelectedAssetBuyState(AsyncProcessState.NONE));
- // tslint:disable-next-line:no-floating-promises
- debouncedUpdateBuyQuoteAsync(dispatch, assetData, value);
+
+ if (!_.isUndefined(value) && !_.isUndefined(assetData)) {
+ // even if it's debounced, give them the illusion it's loading
+ dispatch(actions.updateBuyQuoteStatePending());
+ // tslint:disable-next-line:no-floating-promises
+ debouncedUpdateBuyQuoteAsync(dispatch, assetData, value);
+ }
},
});
diff --git a/packages/instant/src/containers/selected_asset_instant_heading.ts b/packages/instant/src/containers/selected_asset_instant_heading.ts
index c97cfe11a..be31527f1 100644
--- a/packages/instant/src/containers/selected_asset_instant_heading.ts
+++ b/packages/instant/src/containers/selected_asset_instant_heading.ts
@@ -5,6 +5,7 @@ import { connect } from 'react-redux';
import { oc } from 'ts-optchain';
import { State } from '../redux/reducer';
+import { AsyncProcessState } from '../types';
import { InstantHeading } from '../components/instant_heading';
@@ -14,12 +15,14 @@ interface ConnectedState {
selectedAssetAmount?: BigNumber;
totalEthBaseAmount?: BigNumber;
ethUsdPrice?: BigNumber;
+ quoteState: AsyncProcessState;
}
const mapStateToProps = (state: State, _ownProps: InstantHeadingProps): ConnectedState => ({
selectedAssetAmount: state.selectedAssetAmount,
totalEthBaseAmount: oc(state).latestBuyQuote.worstCaseQuoteInfo.totalEthAmount(),
ethUsdPrice: state.ethUsdPrice,
+ quoteState: state.quoteState,
});
export const SelectedAssetInstantHeading: React.ComponentClass<InstantHeadingProps> = connect(mapStateToProps)(
diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts
index cf5b39790..e12c728bb 100644
--- a/packages/instant/src/redux/actions.ts
+++ b/packages/instant/src/redux/actions.ts
@@ -25,6 +25,8 @@ export enum ActionTypes {
UPDATE_SELECTED_ASSET_AMOUNT = 'UPDATE_SELECTED_ASSET_AMOUNT',
UPDATE_SELECTED_ASSET_BUY_STATE = 'UPDATE_SELECTED_ASSET_BUY_STATE',
UPDATE_LATEST_BUY_QUOTE = 'UPDATE_LATEST_BUY_QUOTE',
+ UPDATE_BUY_QUOTE_STATE_PENDING = 'UPDATE_BUY_QUOTE_STATE_PENDING',
+ UPDATE_BUY_QUOTE_STATE_FAILURE = 'UPDATE_BUY_QUOTE_STATE_FAILURE',
SET_ERROR = 'SET_ERROR',
HIDE_ERROR = 'HIDE_ERROR',
CLEAR_ERROR = 'CLEAR_ERROR',
@@ -36,6 +38,8 @@ export const actions = {
updateSelectedAssetBuyState: (buyState: AsyncProcessState) =>
createAction(ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, buyState),
updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UPDATE_LATEST_BUY_QUOTE, buyQuote),
+ updateBuyQuoteStatePending: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING),
+ updateBuyQuoteStateFailure: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE),
setError: (error?: any) => createAction(ActionTypes.SET_ERROR, error),
hideError: () => createAction(ActionTypes.HIDE_ERROR),
clearError: () => createAction(ActionTypes.CLEAR_ERROR),
diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts
index d23064db7..ed8d0f6cf 100644
--- a/packages/instant/src/redux/reducer.ts
+++ b/packages/instant/src/redux/reducer.ts
@@ -14,9 +14,10 @@ export enum LatestErrorDisplay {
export interface State {
selectedAssetData?: string;
selectedAssetAmount?: BigNumber;
- selectedAssetBuyState: AsyncProcessState;
+ selectedAssetBuyState: AsyncProcessState; // TODO: rename buyOrderState
ethUsdPrice?: BigNumber;
latestBuyQuote?: BuyQuote;
+ quoteState: AsyncProcessState;
latestError?: any;
latestErrorDisplay: LatestErrorDisplay;
}
@@ -30,6 +31,7 @@ export const INITIAL_STATE: State = {
latestBuyQuote: undefined,
latestError: undefined,
latestErrorDisplay: LatestErrorDisplay.Hidden,
+ quoteState: AsyncProcessState.NONE,
};
export const reducer = (state: State = INITIAL_STATE, action: Action): State => {
@@ -48,6 +50,19 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State =>
return {
...state,
latestBuyQuote: action.data,
+ quoteState: AsyncProcessState.SUCCESS,
+ };
+ case ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING:
+ return {
+ ...state,
+ latestBuyQuote: undefined,
+ quoteState: AsyncProcessState.PENDING,
+ };
+ case ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE:
+ return {
+ ...state,
+ latestBuyQuote: undefined,
+ quoteState: AsyncProcessState.FAILURE,
};
case ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE:
return {
diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts
index bf3ee392f..f0ffb893b 100644
--- a/packages/instant/src/types.ts
+++ b/packages/instant/src/types.ts
@@ -2,10 +2,10 @@ import { AssetProxyId, ObjectMap } from '@0xproject/types';
// Reusable
export enum AsyncProcessState {
- NONE,
- PENDING,
- SUCCESS,
- FAILURE,
+ NONE = 'None',
+ PENDING = 'Pending',
+ SUCCESS = 'Success',
+ FAILURE = 'Failure',
}
export type FunctionType = (...args: any[]) => any;