aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/inputs
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts/components/inputs')
-rw-r--r--packages/website/ts/components/inputs/allowance_toggle.tsx7
-rw-r--r--packages/website/ts/components/inputs/balance_bounded_input.tsx5
-rw-r--r--packages/website/ts/components/inputs/token_amount_input.tsx64
3 files changed, 68 insertions, 8 deletions
diff --git a/packages/website/ts/components/inputs/allowance_toggle.tsx b/packages/website/ts/components/inputs/allowance_toggle.tsx
index da46db4f4..45531e74b 100644
--- a/packages/website/ts/components/inputs/allowance_toggle.tsx
+++ b/packages/website/ts/components/inputs/allowance_toggle.tsx
@@ -17,6 +17,8 @@ interface AllowanceToggleProps {
token: Token;
tokenState: TokenState;
userAddress: string;
+ isDisabled: boolean;
+ refetchTokenStateAsync: () => Promise<void>;
}
interface AllowanceToggleState {
@@ -45,7 +47,7 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
<div className="flex">
<div>
<Toggle
- disabled={this.state.isSpinnerVisible}
+ disabled={this.state.isSpinnerVisible || this.props.isDisabled}
toggled={this._isAllowanceSet()}
onToggle={this._onToggleAllowanceAsync.bind(this)}
/>
@@ -73,12 +75,13 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow
}
try {
await this.props.blockchain.setProxyAllowanceAsync(this.props.token, newAllowanceAmountInBaseUnits);
+ await this.props.refetchTokenStateAsync();
} catch (err) {
this.setState({
isSpinnerVisible: false,
});
const errMsg = `${err}`;
- if (_.includes(errMsg, 'User denied transaction')) {
+ if (utils.didUserDenyWeb3Request(errMsg)) {
return;
}
utils.consoleLog(`Unexpected error encountered: ${err}`);
diff --git a/packages/website/ts/components/inputs/balance_bounded_input.tsx b/packages/website/ts/components/inputs/balance_bounded_input.tsx
index ddc434b51..3bbc7a5f6 100644
--- a/packages/website/ts/components/inputs/balance_bounded_input.tsx
+++ b/packages/website/ts/components/inputs/balance_bounded_input.tsx
@@ -18,6 +18,7 @@ interface BalanceBoundedInputProps {
validate?: (amount: BigNumber) => InputErrMsg;
onVisitBalancesPageClick?: () => void;
shouldHideVisitBalancesLink?: boolean;
+ isDisabled?: boolean;
}
interface BalanceBoundedInputState {
@@ -29,6 +30,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
public static defaultProps: Partial<BalanceBoundedInputProps> = {
shouldShowIncompleteErrs: false,
shouldHideVisitBalancesLink: false,
+ isDisabled: false,
};
constructor(props: BalanceBoundedInputProps) {
super(props);
@@ -88,6 +90,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
hintText={<span style={{ textTransform: 'capitalize' }}>amount</span>}
onChange={this._onValueChange.bind(this)}
underlineStyle={{ width: 'calc(100% + 50px)' }}
+ disabled={this.props.isDisabled}
/>
);
}
@@ -100,7 +103,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
},
() => {
const isValid = _.isUndefined(errMsg);
- if (utils.isNumeric(amountString)) {
+ if (utils.isNumeric(amountString) && !_.includes(amountString, '-')) {
this.props.onChange(isValid, new BigNumber(amountString));
} else {
this.props.onChange(isValid);
diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx
index 63966d759..2b167d875 100644
--- a/packages/website/ts/components/inputs/token_amount_input.tsx
+++ b/packages/website/ts/components/inputs/token_amount_input.tsx
@@ -3,13 +3,16 @@ import { BigNumber } from '@0xproject/utils';
import * as _ from 'lodash';
import * as React from 'react';
import { Link } from 'react-router-dom';
+import { Blockchain } from 'ts/blockchain';
import { BalanceBoundedInput } from 'ts/components/inputs/balance_bounded_input';
-import { InputErrMsg, Token, TokenState, ValidatedBigNumberCallback, WebsitePaths } from 'ts/types';
+import { InputErrMsg, Token, ValidatedBigNumberCallback, WebsitePaths } from 'ts/types';
import { colors } from 'ts/utils/colors';
interface TokenAmountInputProps {
+ userAddress: string;
+ networkId: number;
+ blockchain: Blockchain;
token: Token;
- tokenState: TokenState;
label?: string;
amount?: BigNumber;
shouldShowIncompleteErrs: boolean;
@@ -17,11 +20,45 @@ interface TokenAmountInputProps {
shouldCheckAllowance: boolean;
onChange: ValidatedBigNumberCallback;
onVisitBalancesPageClick?: () => void;
+ lastForceTokenStateRefetch: number;
}
-interface TokenAmountInputState {}
+interface TokenAmountInputState {
+ balance: BigNumber;
+ allowance: BigNumber;
+ isBalanceAndAllowanceLoaded: boolean;
+}
export class TokenAmountInput extends React.Component<TokenAmountInputProps, TokenAmountInputState> {
+ private _isUnmounted: boolean;
+ constructor(props: TokenAmountInputProps) {
+ super(props);
+ this._isUnmounted = false;
+ const defaultAmount = new BigNumber(0);
+ this.state = {
+ balance: defaultAmount,
+ allowance: defaultAmount,
+ isBalanceAndAllowanceLoaded: false,
+ };
+ }
+ public componentWillMount() {
+ // tslint:disable-next-line:no-floating-promises
+ this._fetchBalanceAndAllowanceAsync(this.props.token.address, this.props.userAddress);
+ }
+ public componentWillUnmount() {
+ this._isUnmounted = true;
+ }
+ public componentWillReceiveProps(nextProps: TokenAmountInputProps) {
+ if (
+ nextProps.userAddress !== this.props.userAddress ||
+ nextProps.networkId !== this.props.networkId ||
+ nextProps.token.address !== this.props.token.address ||
+ nextProps.lastForceTokenStateRefetch !== this.props.lastForceTokenStateRefetch
+ ) {
+ // tslint:disable-next-line:no-floating-promises
+ this._fetchBalanceAndAllowanceAsync(nextProps.token.address, nextProps.userAddress);
+ }
+ }
public render() {
const amount = this.props.amount
? ZeroEx.toUnitAmount(this.props.amount, this.props.token.decimals)
@@ -32,12 +69,13 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
<BalanceBoundedInput
label={this.props.label}
amount={amount}
- balance={ZeroEx.toUnitAmount(this.props.tokenState.balance, this.props.token.decimals)}
+ balance={ZeroEx.toUnitAmount(this.state.balance, this.props.token.decimals)}
onChange={this._onChange.bind(this)}
validate={this._validate.bind(this)}
shouldCheckBalance={this.props.shouldCheckBalance}
shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
+ isDisabled={!this.state.isBalanceAndAllowanceLoaded}
/>
<div style={{ paddingTop: hasLabel ? 39 : 14 }}>{this.props.token.symbol}</div>
</div>
@@ -51,7 +89,7 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
this.props.onChange(isValid, baseUnitAmount);
}
private _validate(amount: BigNumber): InputErrMsg {
- if (this.props.shouldCheckAllowance && amount.gt(this.props.tokenState.allowance)) {
+ if (this.props.shouldCheckAllowance && amount.gt(this.state.allowance)) {
return (
<span>
Insufficient allowance.{' '}
@@ -67,4 +105,20 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
return undefined;
}
}
+ private async _fetchBalanceAndAllowanceAsync(tokenAddress: string, userAddress: string) {
+ this.setState({
+ isBalanceAndAllowanceLoaded: false,
+ });
+ const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
+ userAddress,
+ tokenAddress,
+ );
+ if (!this._isUnmounted) {
+ this.setState({
+ balance,
+ allowance,
+ isBalanceAndAllowanceLoaded: true,
+ });
+ }
+ }
}