aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant/src/containers
diff options
context:
space:
mode:
Diffstat (limited to 'packages/instant/src/containers')
-rw-r--r--packages/instant/src/containers/latest_buy_quote_order_details.ts27
-rw-r--r--packages/instant/src/containers/latest_error.tsx35
-rw-r--r--packages/instant/src/containers/selected_asset_amount_input.ts89
-rw-r--r--packages/instant/src/containers/selected_asset_amount_input.tsx36
-rw-r--r--packages/instant/src/containers/selected_asset_buy_button.ts55
-rw-r--r--packages/instant/src/containers/selected_asset_instant_heading.ts30
6 files changed, 236 insertions, 36 deletions
diff --git a/packages/instant/src/containers/latest_buy_quote_order_details.ts b/packages/instant/src/containers/latest_buy_quote_order_details.ts
new file mode 100644
index 000000000..b354c78fa
--- /dev/null
+++ b/packages/instant/src/containers/latest_buy_quote_order_details.ts
@@ -0,0 +1,27 @@
+import { BuyQuoteInfo } from '@0xproject/asset-buyer';
+import { BigNumber } from '@0xproject/utils';
+import * as _ from 'lodash';
+import * as React from 'react';
+import { connect } from 'react-redux';
+import { oc } from 'ts-optchain';
+
+import { State } from '../redux/reducer';
+
+import { OrderDetails } from '../components/order_details';
+
+export interface LatestBuyQuoteOrderDetailsProps {}
+
+interface ConnectedState {
+ buyQuoteInfo?: BuyQuoteInfo;
+ ethUsdPrice?: BigNumber;
+}
+
+const mapStateToProps = (state: State, _ownProps: LatestBuyQuoteOrderDetailsProps): ConnectedState => ({
+ // use the worst case quote info
+ buyQuoteInfo: oc(state).latestBuyQuote.worstCaseQuoteInfo(),
+ ethUsdPrice: state.ethUsdPrice,
+});
+
+export const LatestBuyQuoteOrderDetails: React.ComponentClass<LatestBuyQuoteOrderDetailsProps> = connect(
+ mapStateToProps,
+)(OrderDetails);
diff --git a/packages/instant/src/containers/latest_error.tsx b/packages/instant/src/containers/latest_error.tsx
new file mode 100644
index 000000000..08ea418e7
--- /dev/null
+++ b/packages/instant/src/containers/latest_error.tsx
@@ -0,0 +1,35 @@
+import * as React from 'react';
+
+import { connect } from 'react-redux';
+
+import { SlidingError } from '../components/sliding_error';
+import { LatestErrorDisplay, State } from '../redux/reducer';
+import { errorUtil } from '../util/error';
+
+export interface LatestErrorComponentProps {
+ assetData?: string;
+ latestError?: any;
+ slidingDirection: 'down' | 'up';
+}
+
+export const LatestErrorComponent: React.StatelessComponent<LatestErrorComponentProps> = props => {
+ if (!props.latestError) {
+ return <div />;
+ }
+ const { icon, message } = errorUtil.errorDescription(props.latestError, props.assetData);
+ return <SlidingError direction={props.slidingDirection} icon={icon} message={message} />;
+};
+
+interface ConnectedState {
+ assetData?: string;
+ latestError?: any;
+ slidingDirection: 'down' | 'up';
+}
+export interface LatestErrorProps {}
+const mapStateToProps = (state: State, _ownProps: LatestErrorProps): ConnectedState => ({
+ assetData: state.selectedAssetData,
+ latestError: state.latestError,
+ slidingDirection: state.latestErrorDisplay === LatestErrorDisplay.Present ? 'up' : 'down',
+});
+
+export const LatestError = connect(mapStateToProps)(LatestErrorComponent);
diff --git a/packages/instant/src/containers/selected_asset_amount_input.ts b/packages/instant/src/containers/selected_asset_amount_input.ts
new file mode 100644
index 000000000..0873f1ab6
--- /dev/null
+++ b/packages/instant/src/containers/selected_asset_amount_input.ts
@@ -0,0 +1,89 @@
+import { BuyQuote } from '@0xproject/asset-buyer';
+import { BigNumber } from '@0xproject/utils';
+import { Web3Wrapper } from '@0xproject/web3-wrapper';
+import * as _ from 'lodash';
+import * as React from 'react';
+import { connect } from 'react-redux';
+import { Dispatch } from 'redux';
+
+import { zrxDecimals } from '../constants';
+import { Action, actions } from '../redux/actions';
+import { State } from '../redux/reducer';
+import { ColorOption } from '../style/theme';
+import { AsyncProcessState } from '../types';
+import { assetBuyer } from '../util/asset_buyer';
+import { errorUtil } from '../util/error';
+
+import { AssetAmountInput } from '../components/asset_amount_input';
+
+export interface SelectedAssetAmountInputProps {
+ fontColor?: ColorOption;
+ fontSize?: string;
+}
+
+interface ConnectedState {
+ value?: BigNumber;
+ assetData?: string;
+}
+
+interface ConnectedDispatch {
+ onChange: (value?: BigNumber, assetData?: string) => void;
+}
+
+const mapStateToProps = (state: State, _ownProps: SelectedAssetAmountInputProps): ConnectedState => ({
+ value: state.selectedAssetAmount,
+ assetData: state.selectedAssetData,
+});
+
+const updateBuyQuoteAsync = async (
+ dispatch: Dispatch<Action>,
+ assetData: string,
+ assetAmount: BigNumber,
+): Promise<void> => {
+ // 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);
+ } 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));
+};
+
+const debouncedUpdateBuyQuoteAsync = _.debounce(updateBuyQuoteAsync, 200, { trailing: true });
+
+const mapDispatchToProps = (
+ dispatch: Dispatch<Action>,
+ _ownProps: SelectedAssetAmountInputProps,
+): ConnectedDispatch => ({
+ onChange: (value, assetData) => {
+ // Update the input
+ dispatch(actions.updateSelectedAssetAmount(value));
+ // invalidate the last buy quote.
+ dispatch(actions.updateLatestBuyQuote(undefined));
+ // reset our buy state
+ dispatch(actions.updatebuyOrderState(AsyncProcessState.NONE));
+
+ 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);
+ }
+ },
+});
+
+export const SelectedAssetAmountInput: React.ComponentClass<SelectedAssetAmountInputProps> = connect(
+ mapStateToProps,
+ mapDispatchToProps,
+)(AssetAmountInput);
diff --git a/packages/instant/src/containers/selected_asset_amount_input.tsx b/packages/instant/src/containers/selected_asset_amount_input.tsx
deleted file mode 100644
index 800a4c568..000000000
--- a/packages/instant/src/containers/selected_asset_amount_input.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { BigNumber } from '@0xproject/utils';
-import * as React from 'react';
-import { connect } from 'react-redux';
-import { Dispatch } from 'redux';
-
-import { State } from '../redux/reducer';
-import { ColorOption } from '../style/theme';
-import { Action, ActionTypes } from '../types';
-
-import { AmountInput } from '../components/amount_input';
-
-export interface SelectedAssetAmountInputProps {
- fontColor?: ColorOption;
- fontSize?: string;
-}
-
-interface ConnectedState {
- value?: BigNumber;
-}
-
-interface ConnectedDispatch {
- onChange?: (value?: BigNumber) => void;
-}
-
-const mapStateToProps = (state: State, _ownProps: SelectedAssetAmountInputProps): ConnectedState => ({
- value: state.selectedAssetAmount,
-});
-
-const mapDispatchToProps = (dispatch: Dispatch<Action>): ConnectedDispatch => ({
- onChange: value => dispatch({ type: ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, data: value }),
-});
-
-export const SelectedAssetAmountInput: React.ComponentClass<SelectedAssetAmountInputProps> = connect(
- mapStateToProps,
- mapDispatchToProps,
-)(AmountInput);
diff --git a/packages/instant/src/containers/selected_asset_buy_button.ts b/packages/instant/src/containers/selected_asset_buy_button.ts
new file mode 100644
index 000000000..7d3919468
--- /dev/null
+++ b/packages/instant/src/containers/selected_asset_buy_button.ts
@@ -0,0 +1,55 @@
+import { BuyQuote } from '@0xproject/asset-buyer';
+import * as _ from 'lodash';
+import * as React from 'react';
+import { connect } from 'react-redux';
+import { Dispatch } from 'redux';
+
+import { Action, actions } from '../redux/actions';
+import { State } from '../redux/reducer';
+import { AsyncProcessState } from '../types';
+
+import { BuyButton } from '../components/buy_button';
+
+export interface SelectedAssetBuyButtonProps {}
+
+interface ConnectedState {
+ text: string;
+ buyQuote?: BuyQuote;
+}
+
+interface ConnectedDispatch {
+ onClick: (buyQuote: BuyQuote) => void;
+ onBuySuccess: (buyQuote: BuyQuote) => void;
+ onBuyFailure: (buyQuote: BuyQuote) => void;
+}
+
+const textForState = (state: AsyncProcessState): string => {
+ switch (state) {
+ case AsyncProcessState.NONE:
+ return 'Buy';
+ case AsyncProcessState.PENDING:
+ return '...Loading';
+ case AsyncProcessState.SUCCESS:
+ return 'Success!';
+ case AsyncProcessState.FAILURE:
+ return 'Failed';
+ default:
+ return 'Buy';
+ }
+};
+
+const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyButtonProps): ConnectedState => ({
+ text: textForState(state.buyOrderState),
+ buyQuote: state.latestBuyQuote,
+});
+
+const mapDispatchToProps = (dispatch: Dispatch<Action>, ownProps: SelectedAssetBuyButtonProps): ConnectedDispatch => ({
+ onClick: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.PENDING)),
+ onBuySuccess: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.SUCCESS)),
+ onBuyFailure: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.FAILURE)),
+});
+
+export const SelectedAssetBuyButton: React.ComponentClass<SelectedAssetBuyButtonProps> = connect(
+ mapStateToProps,
+ mapDispatchToProps,
+)(BuyButton);
diff --git a/packages/instant/src/containers/selected_asset_instant_heading.ts b/packages/instant/src/containers/selected_asset_instant_heading.ts
new file mode 100644
index 000000000..be31527f1
--- /dev/null
+++ b/packages/instant/src/containers/selected_asset_instant_heading.ts
@@ -0,0 +1,30 @@
+import { BigNumber } from '@0xproject/utils';
+import * as _ from 'lodash';
+import * as React from 'react';
+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';
+
+export interface InstantHeadingProps {}
+
+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)(
+ InstantHeading,
+);