diff options
7 files changed, 28 insertions, 94 deletions
diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx index 34257d25f..f5605a187 100644 --- a/packages/instant/src/components/zero_ex_instant_provider.tsx +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -99,13 +99,13 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider asyncData.fetchAvailableAssetDatasAndDispatchToStore(this._store); } // tslint:disable-next-line:no-floating-promises - // asyncData.fetchAccountInfoAndDispatchToStore(this._store); - this._accountUpdateHeartbeat = generateAccountHeartbeater(this._store); + this._accountUpdateHeartbeat = generateAccountHeartbeater(this._store, true); this._accountUpdateHeartbeat.start(ACCOUNT_UPDATE_INTERVAL_TIME_MS); - this._buyQuoteHeartbeat = generateBuyQuoteHeartbeater(this._store); + this._buyQuoteHeartbeat = generateBuyQuoteHeartbeater(this._store, false); this._buyQuoteHeartbeat.start(BUY_QUOTE_UPDATE_INTERVAL_TIME_MS); + asyncData.fetchCurrentBuyQuoteAndDispatchToStore(this._store, true); // warm up the gas price estimator cache just in case we can't // grab the gas price estimate when submitting the transaction diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index 74713327c..93ff3db70 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -11,7 +11,6 @@ import { Action, actions } from '../redux/actions'; import { State } from '../redux/reducer'; import { ColorOption } from '../style/theme'; import { AffiliateInfo, ERC20Asset, OrderProcessState } from '../types'; -import { updateBuyQuoteOrFlashErrorAsync } from '../util/buy_quote_fetcher'; import { buyQuoteUpdater } from '../util/buy_quote_updater'; export interface SelectedERC20AssetAmountInputProps { @@ -68,10 +67,9 @@ const mapStateToProps = (state: State, _ownProps: SelectedERC20AssetAmountInputP }; }; -// TODO: change to set pending to true const debouncedUpdateBuyQuoteAsync = _.debounce(buyQuoteUpdater.updateBuyQuoteAsync.bind(buyQuoteUpdater), 200, { trailing: true, -}); +}) as typeof buyQuoteUpdater.updateBuyQuoteAsync; const mapDispatchToProps = ( dispatch: Dispatch<Action>, @@ -89,7 +87,7 @@ const mapDispatchToProps = ( // even if it's debounced, give them the illusion it's loading dispatch(actions.setQuoteRequestStatePending()); // tslint:disable-next-line:no-floating-promises - debouncedUpdateBuyQuoteAsync(assetBuyer, dispatch, asset, value, affiliateInfo); + debouncedUpdateBuyQuoteAsync(assetBuyer, dispatch, asset, value, true, affiliateInfo); } }, }); diff --git a/packages/instant/src/redux/async_data.ts b/packages/instant/src/redux/async_data.ts index a50f24cba..7af6e1e56 100644 --- a/packages/instant/src/redux/async_data.ts +++ b/packages/instant/src/redux/async_data.ts @@ -74,7 +74,7 @@ export const asyncData = { return; } }, - fetchCurrentBuyQuoteAndDispatchToStore: async (store: Store) => { + fetchCurrentBuyQuoteAndDispatchToStore: async (store: Store, setPending: boolean) => { const { providerState, selectedAsset, selectedAssetAmount, affiliateInfo } = store.getState(); const assetBuyer = providerState.assetBuyer; if ( @@ -87,6 +87,7 @@ export const asyncData = { store.dispatch, selectedAsset as ERC20Asset, selectedAssetAmount, + setPending, affiliateInfo, ); } diff --git a/packages/instant/src/util/buy_quote_fetcher.ts b/packages/instant/src/util/buy_quote_fetcher.ts deleted file mode 100644 index 22ce835e8..000000000 --- a/packages/instant/src/util/buy_quote_fetcher.ts +++ /dev/null @@ -1,75 +0,0 @@ -// TODO: rename file and export object -// TODO: delete this - -import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; -import { AssetProxyId } from '@0x/types'; -import { BigNumber } from '@0x/utils'; -import { Web3Wrapper } from '@0x/web3-wrapper'; -import * as _ from 'lodash'; -import { Dispatch } from 'redux'; -import { oc } from 'ts-optchain'; - -import { Action, actions } from '../redux/actions'; -import { State } from '../redux/reducer'; -import { AffiliateInfo, ERC20Asset } from '../types'; -import { assetUtils } from '../util/asset'; - -import { errorFlasher } from './error_flasher'; - -export const updateBuyQuoteOrFlashErrorAsync = async ( - assetBuyer: AssetBuyer, - asset: ERC20Asset, - assetAmount: BigNumber, - dispatch: Dispatch<Action>, - affiliateInfo?: AffiliateInfo, -) => { - // get a new buy quote. - const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, asset.metaData.decimals); - - const feePercentage = oc(affiliateInfo).feePercentage(); - let newBuyQuote: BuyQuote | undefined; - try { - newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { feePercentage }); - } catch (error) { - dispatch(actions.setQuoteRequestStateFailure()); - let errorMessage; - if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { - const assetName = assetUtils.bestNameForAsset(asset, 'of this asset'); - errorMessage = `Not enough ${assetName} available`; - } else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) { - errorMessage = 'Not enough ZRX available'; - } else if ( - error.message === AssetBuyerError.StandardRelayerApiError || - error.message.startsWith(AssetBuyerError.AssetUnavailable) - ) { - const assetName = assetUtils.bestNameForAsset(asset, 'This asset'); - errorMessage = `${assetName} is currently unavailable`; - } - if (!_.isUndefined(errorMessage)) { - errorFlasher.flashNewErrorMessage(dispatch, errorMessage); - } else { - throw error; - } - return; - } - // We have a successful new buy quote - errorFlasher.clearError(dispatch); - // invalidate the last buy quote. - dispatch(actions.updateLatestBuyQuote(newBuyQuote)); -}; - -export const updateBuyQuoteOrFlashErrorAsyncForState = async (state: State, dispatch: Dispatch<Action>) => { - const { selectedAsset, selectedAssetAmount, affiliateInfo } = state; - const assetBuyer = state.providerState.assetBuyer; - - if (selectedAsset && selectedAssetAmount && selectedAsset.metaData.assetProxyId === AssetProxyId.ERC20) { - // TODO: maybe dont do in the case of an error showing - updateBuyQuoteOrFlashErrorAsync( - assetBuyer, - selectedAsset as ERC20Asset, // TODO: better way to do this? - selectedAssetAmount, - dispatch, - affiliateInfo, - ); - } -}; diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts index e697d3ef7..fb5da311d 100644 --- a/packages/instant/src/util/buy_quote_updater.ts +++ b/packages/instant/src/util/buy_quote_updater.ts @@ -1,4 +1,5 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; +import { AssetProxyId } from '@0x/types'; import { BigNumber } from '@0x/utils'; import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; @@ -6,6 +7,7 @@ import { Dispatch } from 'redux'; import { oc } from 'ts-optchain'; import { Action, actions } from '../redux/actions'; +import { State } from '../redux/reducer'; import { AffiliateInfo, ERC20Asset } from '../types'; import { assetUtils } from '../util/asset'; import { errorFlasher } from '../util/error_flasher'; @@ -16,12 +18,15 @@ export const buyQuoteUpdater = { dispatch: Dispatch<Action>, asset: ERC20Asset, assetAmount: BigNumber, + setPending = true, affiliateInfo?: AffiliateInfo, ): Promise<void> => { // get a new buy quote. const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, asset.metaData.decimals); - // mark quote as pending - dispatch(actions.setQuoteRequestStatePending()); + if (setPending) { + // mark quote as pending + dispatch(actions.setQuoteRequestStatePending()); + } const feePercentage = oc(affiliateInfo).feePercentage(); let newBuyQuote: BuyQuote | undefined; try { diff --git a/packages/instant/src/util/heartbeater.ts b/packages/instant/src/util/heartbeater.ts index bb4e99383..87af48423 100644 --- a/packages/instant/src/util/heartbeater.ts +++ b/packages/instant/src/util/heartbeater.ts @@ -4,18 +4,24 @@ type HeartbeatableFunction = () => Promise<void>; export class Heartbeater { private _intervalId?: number; private _hasPendingRequest: boolean; + private _performImmediatelyOnStart: boolean; private _performFunction: HeartbeatableFunction; - public constructor(_performingFunctionAsync: HeartbeatableFunction) { - this._performFunction = _performingFunctionAsync; + public constructor(performingFunctionAsync: HeartbeatableFunction, performImmediatelyOnStart: boolean) { + this._performFunction = performingFunctionAsync; this._hasPendingRequest = false; + this._performImmediatelyOnStart = performImmediatelyOnStart; } public start(intervalTimeMs: number): void { if (!_.isUndefined(this._intervalId)) { throw new Error('Heartbeat is running, please stop before restarting'); } - this._trackAndPerformAsync(); + + if (this._performImmediatelyOnStart) { + this._trackAndPerformAsync(); + } + this._intervalId = window.setInterval(this._trackAndPerformAsync.bind(this), intervalTimeMs); } diff --git a/packages/instant/src/util/heartbeater_factory.ts b/packages/instant/src/util/heartbeater_factory.ts index 9fac9cf4c..beedb66c8 100644 --- a/packages/instant/src/util/heartbeater_factory.ts +++ b/packages/instant/src/util/heartbeater_factory.ts @@ -1,17 +1,16 @@ import { asyncData } from '../redux/async_data'; import { Store } from '../redux/store'; -import { updateBuyQuoteOrFlashErrorAsyncForState } from './buy_quote_fetcher'; import { Heartbeater } from './heartbeater'; -export const generateAccountHeartbeater = (store: Store): Heartbeater => { +export const generateAccountHeartbeater = (store: Store, performImmediatelyOnStart: boolean): Heartbeater => { return new Heartbeater(async () => { await asyncData.fetchAccountInfoAndDispatchToStore(store, { setLoading: false }); - }); + }, performImmediatelyOnStart); }; -export const generateBuyQuoteHeartbeater = (store: Store): Heartbeater => { +export const generateBuyQuoteHeartbeater = (store: Store, performImmediatelyOnStart: boolean): Heartbeater => { return new Heartbeater(async () => { - await updateBuyQuoteOrFlashErrorAsyncForState(store.getState(), store.dispatch); - }); + await asyncData.fetchCurrentBuyQuoteAndDispatchToStore(store, false); + }, performImmediatelyOnStart); }; |