aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant/src/redux
diff options
context:
space:
mode:
Diffstat (limited to 'packages/instant/src/redux')
-rw-r--r--packages/instant/src/redux/actions.ts12
-rw-r--r--packages/instant/src/redux/async_data.ts79
-rw-r--r--packages/instant/src/redux/reducer.ts51
3 files changed, 90 insertions, 52 deletions
diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts
index 8947c6c97..77e3dec12 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 } from '../types';
+import { ActionsUnion, AddressAndEthBalanceInWei, Asset, StandardSlidingPanelContent } from '../types';
export interface PlainAction<T extends string> {
type: T;
@@ -26,7 +26,7 @@ export enum ActionTypes {
SET_ACCOUNT_STATE_READY = 'SET_ACCOUNT_STATE_READY',
UPDATE_ACCOUNT_ETH_BALANCE = 'UPDATE_ACCOUNT_ETH_BALANCE',
UPDATE_ETH_USD_PRICE = 'UPDATE_ETH_USD_PRICE',
- UPDATE_SELECTED_ASSET_AMOUNT = 'UPDATE_SELECTED_ASSET_AMOUNT',
+ UPDATE_SELECTED_ASSET_UNIT_AMOUNT = 'UPDATE_SELECTED_ASSET_UNIT_AMOUNT',
SET_BUY_ORDER_STATE_NONE = 'SET_BUY_ORDER_STATE_NONE',
SET_BUY_ORDER_STATE_VALIDATING = 'SET_BUY_ORDER_STATE_VALIDATING',
SET_BUY_ORDER_STATE_PROCESSING = 'SET_BUY_ORDER_STATE_PROCESSING',
@@ -41,6 +41,8 @@ export enum ActionTypes {
HIDE_ERROR = 'HIDE_ERROR',
CLEAR_ERROR = 'CLEAR_ERROR',
RESET_AMOUNT = 'RESET_AMOUNT',
+ OPEN_STANDARD_SLIDING_PANEL = 'OPEN_STANDARD_SLIDING_PANEL',
+ CLOSE_STANDARD_SLIDING_PANEL = 'CLOSE_STANDARD_SLIDING_PANEL',
}
export const actions = {
@@ -50,7 +52,8 @@ export const actions = {
updateAccountEthBalance: (addressAndBalance: AddressAndEthBalanceInWei) =>
createAction(ActionTypes.UPDATE_ACCOUNT_ETH_BALANCE, addressAndBalance),
updateEthUsdPrice: (price?: BigNumber) => createAction(ActionTypes.UPDATE_ETH_USD_PRICE, price),
- updateSelectedAssetAmount: (amount?: BigNumber) => createAction(ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, amount),
+ updateSelectedAssetAmount: (amount?: BigNumber) =>
+ createAction(ActionTypes.UPDATE_SELECTED_ASSET_UNIT_AMOUNT, amount),
setBuyOrderStateNone: () => createAction(ActionTypes.SET_BUY_ORDER_STATE_NONE),
setBuyOrderStateValidating: () => createAction(ActionTypes.SET_BUY_ORDER_STATE_VALIDATING),
setBuyOrderStateProcessing: (txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) =>
@@ -66,4 +69,7 @@ export const actions = {
hideError: () => createAction(ActionTypes.HIDE_ERROR),
clearError: () => createAction(ActionTypes.CLEAR_ERROR),
resetAmount: () => createAction(ActionTypes.RESET_AMOUNT),
+ openStandardSlidingPanel: (content: StandardSlidingPanelContent) =>
+ createAction(ActionTypes.OPEN_STANDARD_SLIDING_PANEL, content),
+ closeStandardSlidingPanel: () => createAction(ActionTypes.CLOSE_STANDARD_SLIDING_PANEL),
};
diff --git a/packages/instant/src/redux/async_data.ts b/packages/instant/src/redux/async_data.ts
index b920ac914..5d30388b8 100644
--- a/packages/instant/src/redux/async_data.ts
+++ b/packages/instant/src/redux/async_data.ts
@@ -1,102 +1,103 @@
import { AssetProxyId } from '@0x/types';
+import { Web3Wrapper } from '@0x/web3-wrapper';
import * as _ from 'lodash';
+import { Dispatch } from 'redux';
import { BIG_NUMBER_ZERO } from '../constants';
-import { AccountState, ERC20Asset, OrderProcessState } from '../types';
+import { AccountState, ERC20Asset, OrderProcessState, ProviderState } from '../types';
import { assetUtils } from '../util/asset';
import { buyQuoteUpdater } from '../util/buy_quote_updater';
import { coinbaseApi } from '../util/coinbase_api';
import { errorFlasher } from '../util/error_flasher';
import { actions } from './actions';
-import { Store } from './store';
+import { State } from './reducer';
export const asyncData = {
- fetchEthPriceAndDispatchToStore: async (store: Store) => {
+ fetchEthPriceAndDispatchToStore: async (dispatch: Dispatch) => {
try {
const ethUsdPrice = await coinbaseApi.getEthUsdPrice();
- store.dispatch(actions.updateEthUsdPrice(ethUsdPrice));
+ dispatch(actions.updateEthUsdPrice(ethUsdPrice));
} catch (e) {
const errorMessage = 'Error fetching ETH/USD price';
- errorFlasher.flashNewErrorMessage(store.dispatch, errorMessage);
- store.dispatch(actions.updateEthUsdPrice(BIG_NUMBER_ZERO));
+ errorFlasher.flashNewErrorMessage(dispatch, errorMessage);
+ dispatch(actions.updateEthUsdPrice(BIG_NUMBER_ZERO));
}
},
- fetchAvailableAssetDatasAndDispatchToStore: async (store: Store) => {
- const { providerState, assetMetaDataMap, network } = store.getState();
+ fetchAvailableAssetDatasAndDispatchToStore: async (state: State, dispatch: Dispatch) => {
+ const { providerState, assetMetaDataMap, network } = state;
const assetBuyer = providerState.assetBuyer;
try {
const assetDatas = await assetBuyer.getAvailableAssetDatasAsync();
const assets = assetUtils.createAssetsFromAssetDatas(assetDatas, assetMetaDataMap, network);
- store.dispatch(actions.setAvailableAssets(assets));
+ dispatch(actions.setAvailableAssets(assets));
} catch (e) {
const errorMessage = 'Could not find any assets';
- errorFlasher.flashNewErrorMessage(store.dispatch, errorMessage);
+ errorFlasher.flashNewErrorMessage(dispatch, errorMessage);
// On error, just specify that none are available
- store.dispatch(actions.setAvailableAssets([]));
+ dispatch(actions.setAvailableAssets([]));
}
},
- fetchAccountInfoAndDispatchToStore: async (options: { store: Store; shouldSetToLoading: boolean }) => {
- const { store, shouldSetToLoading } = options;
- const { providerState } = store.getState();
+ fetchAccountInfoAndDispatchToStore: async (
+ providerState: ProviderState,
+ dispatch: Dispatch,
+ shouldAttemptUnlock: boolean = false,
+ shouldSetToLoading: boolean = false,
+ ) => {
const web3Wrapper = providerState.web3Wrapper;
const provider = providerState.provider;
if (shouldSetToLoading && providerState.account.state !== AccountState.Loading) {
- store.dispatch(actions.setAccountStateLoading());
+ dispatch(actions.setAccountStateLoading());
}
let availableAddresses: string[];
try {
// TODO(bmillman): Add support at the web3Wrapper level for calling `eth_requestAccounts` instead of calling enable here
const isPrivacyModeEnabled = !_.isUndefined((provider as any).enable);
- availableAddresses = isPrivacyModeEnabled
- ? await (provider as any).enable()
- : await web3Wrapper.getAvailableAddressesAsync();
+ availableAddresses =
+ isPrivacyModeEnabled && shouldAttemptUnlock
+ ? await (provider as any).enable()
+ : await web3Wrapper.getAvailableAddressesAsync();
} catch (e) {
- store.dispatch(actions.setAccountStateLocked());
+ dispatch(actions.setAccountStateLocked());
return;
}
if (!_.isEmpty(availableAddresses)) {
const activeAddress = availableAddresses[0];
- store.dispatch(actions.setAccountStateReady(activeAddress));
+ dispatch(actions.setAccountStateReady(activeAddress));
// tslint:disable-next-line:no-floating-promises
- asyncData.fetchAccountBalanceAndDispatchToStore(store);
+ asyncData.fetchAccountBalanceAndDispatchToStore(activeAddress, providerState.web3Wrapper, dispatch);
} else {
- store.dispatch(actions.setAccountStateLocked());
+ dispatch(actions.setAccountStateLocked());
}
},
- fetchAccountBalanceAndDispatchToStore: async (store: Store) => {
- const { providerState } = store.getState();
- const web3Wrapper = providerState.web3Wrapper;
- const account = providerState.account;
- if (account.state !== AccountState.Ready) {
- return;
- }
+ fetchAccountBalanceAndDispatchToStore: async (address: string, web3Wrapper: Web3Wrapper, dispatch: Dispatch) => {
try {
- const address = account.address;
const ethBalanceInWei = await web3Wrapper.getBalanceInWeiAsync(address);
- store.dispatch(actions.updateAccountEthBalance({ address, ethBalanceInWei }));
+ dispatch(actions.updateAccountEthBalance({ address, ethBalanceInWei }));
} catch (e) {
// leave balance as is
return;
}
},
- fetchCurrentBuyQuoteAndDispatchToStore: async (options: { store: Store; shouldSetPending: boolean }) => {
- const { store, shouldSetPending } = options;
- const { buyOrderState, providerState, selectedAsset, selectedAssetAmount, affiliateInfo } = store.getState();
+ fetchCurrentBuyQuoteAndDispatchToStore: async (
+ state: State,
+ dispatch: Dispatch,
+ options: { updateSilently: boolean },
+ ) => {
+ const { buyOrderState, providerState, selectedAsset, selectedAssetUnitAmount, affiliateInfo } = state;
const assetBuyer = providerState.assetBuyer;
if (
- !_.isUndefined(selectedAssetAmount) &&
+ !_.isUndefined(selectedAssetUnitAmount) &&
!_.isUndefined(selectedAsset) &&
buyOrderState.processState === OrderProcessState.None &&
selectedAsset.metaData.assetProxyId === AssetProxyId.ERC20
) {
await buyQuoteUpdater.updateBuyQuoteAsync(
assetBuyer,
- store.dispatch,
+ dispatch,
selectedAsset as ERC20Asset,
- selectedAssetAmount,
- shouldSetPending,
- affiliateInfo,
+ selectedAssetUnitAmount,
+ { setPending: !options.updateSilently, dispatchErrors: !options.updateSilently, affiliateInfo },
);
}
},
diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts
index ef46fdd9d..dfc2b89f3 100644
--- a/packages/instant/src/redux/reducer.ts
+++ b/packages/instant/src/redux/reducer.ts
@@ -19,6 +19,8 @@ import {
OrderProcessState,
OrderState,
ProviderState,
+ StandardSlidingPanelContent,
+ StandardSlidingPanelSettings,
} from '../types';
import { Action, ActionTypes } from './actions';
@@ -30,6 +32,7 @@ export interface DefaultState {
buyOrderState: OrderState;
latestErrorDisplayStatus: DisplayStatus;
quoteRequestState: AsyncProcessState;
+ standardSlidingPanelSettings: StandardSlidingPanelSettings;
}
// State that is required but needs to be derived from the props
@@ -41,7 +44,7 @@ interface PropsDerivedState {
interface OptionalState {
selectedAsset: Asset;
availableAssets: Asset[];
- selectedAssetAmount: BigNumber;
+ selectedAssetUnitAmount: BigNumber;
ethUsdPrice: BigNumber;
latestBuyQuote: BuyQuote;
latestErrorMessage: string;
@@ -56,6 +59,10 @@ export const DEFAULT_STATE: DefaultState = {
buyOrderState: { processState: OrderProcessState.None },
latestErrorDisplayStatus: DisplayStatus.Hidden,
quoteRequestState: AsyncProcessState.None,
+ standardSlidingPanelSettings: {
+ animationState: 'none',
+ content: StandardSlidingPanelContent.None,
+ },
};
export const createReducer = (initialState: State) => {
@@ -66,11 +73,19 @@ export const createReducer = (initialState: State) => {
case ActionTypes.SET_ACCOUNT_STATE_LOCKED:
return reduceStateWithAccount(state, LOCKED_ACCOUNT);
case ActionTypes.SET_ACCOUNT_STATE_READY: {
- const account: AccountReady = {
+ const address = action.data;
+ let newAccount: AccountReady = {
state: AccountState.Ready,
- address: action.data,
+ address,
};
- return reduceStateWithAccount(state, account);
+ const currentAccount = state.providerState.account;
+ if (currentAccount.state === AccountState.Ready && currentAccount.address === address) {
+ newAccount = {
+ ...newAccount,
+ ethBalanceInWei: currentAccount.ethBalanceInWei,
+ };
+ }
+ return reduceStateWithAccount(state, newAccount);
}
case ActionTypes.UPDATE_ACCOUNT_ETH_BALANCE: {
const { address, ethBalanceInWei } = action.data;
@@ -90,10 +105,10 @@ export const createReducer = (initialState: State) => {
...state,
ethUsdPrice: action.data,
};
- case ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT:
+ case ActionTypes.UPDATE_SELECTED_ASSET_UNIT_AMOUNT:
return {
...state,
- selectedAssetAmount: action.data,
+ selectedAssetUnitAmount: action.data,
};
case ActionTypes.UPDATE_LATEST_BUY_QUOTE:
const newBuyQuoteIfExists = action.data;
@@ -204,13 +219,29 @@ export const createReducer = (initialState: State) => {
latestBuyQuote: undefined,
quoteRequestState: AsyncProcessState.None,
buyOrderState: { processState: OrderProcessState.None },
- selectedAssetAmount: undefined,
+ selectedAssetUnitAmount: undefined,
};
case ActionTypes.SET_AVAILABLE_ASSETS:
return {
...state,
availableAssets: action.data,
};
+ case ActionTypes.OPEN_STANDARD_SLIDING_PANEL:
+ return {
+ ...state,
+ standardSlidingPanelSettings: {
+ content: action.data,
+ animationState: 'slidIn',
+ },
+ };
+ case ActionTypes.CLOSE_STANDARD_SLIDING_PANEL:
+ return {
+ ...state,
+ standardSlidingPanelSettings: {
+ content: state.standardSlidingPanelSettings.content,
+ animationState: 'slidOut',
+ },
+ };
default:
return state;
}
@@ -232,9 +263,9 @@ const reduceStateWithAccount = (state: State, account: Account) => {
const doesBuyQuoteMatchState = (buyQuote: BuyQuote, state: State): boolean => {
const selectedAssetIfExists = state.selectedAsset;
- const selectedAssetAmountIfExists = state.selectedAssetAmount;
+ const selectedAssetUnitAmountIfExists = state.selectedAssetUnitAmount;
// if no selectedAsset or selectedAssetAmount exists on the current state, return false
- if (_.isUndefined(selectedAssetIfExists) || _.isUndefined(selectedAssetAmountIfExists)) {
+ if (_.isUndefined(selectedAssetIfExists) || _.isUndefined(selectedAssetUnitAmountIfExists)) {
return false;
}
// if buyQuote's assetData does not match that of the current selected asset, return false
@@ -246,7 +277,7 @@ const doesBuyQuoteMatchState = (buyQuote: BuyQuote, state: State): boolean => {
const selectedAssetMetaData = selectedAssetIfExists.metaData;
if (selectedAssetMetaData.assetProxyId === AssetProxyId.ERC20) {
const selectedAssetAmountBaseUnits = Web3Wrapper.toBaseUnitAmount(
- selectedAssetAmountIfExists,
+ selectedAssetUnitAmountIfExists,
selectedAssetMetaData.decimals,
);
const doesAssetAmountMatch = selectedAssetAmountBaseUnits.eq(buyQuote.assetBuyAmount);