aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/inputs
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-01-28 23:19:55 +0800
committerFabio Berger <me@fabioberger.com>2018-01-28 23:19:55 +0800
commit6206ebc994a2cf76b90ac426218d6ed18b74a072 (patch)
treef8246d6ef94126af9f5c8fc3bdc7b52712397c9f /packages/website/ts/components/inputs
parentdd9f5adc2e771f3602461ae708d44536f146b902 (diff)
downloaddexon-sol-tools-6206ebc994a2cf76b90ac426218d6ed18b74a072.tar
dexon-sol-tools-6206ebc994a2cf76b90ac426218d6ed18b74a072.tar.gz
dexon-sol-tools-6206ebc994a2cf76b90ac426218d6ed18b74a072.tar.bz2
dexon-sol-tools-6206ebc994a2cf76b90ac426218d6ed18b74a072.tar.lz
dexon-sol-tools-6206ebc994a2cf76b90ac426218d6ed18b74a072.tar.xz
dexon-sol-tools-6206ebc994a2cf76b90ac426218d6ed18b74a072.tar.zst
dexon-sol-tools-6206ebc994a2cf76b90ac426218d6ed18b74a072.zip
Implement just-in-time loading of token balances & allowances
Diffstat (limited to 'packages/website/ts/components/inputs')
-rw-r--r--packages/website/ts/components/inputs/allowance_toggle.tsx5
-rw-r--r--packages/website/ts/components/inputs/balance_bounded_input.tsx3
-rw-r--r--packages/website/ts/components/inputs/token_amount_input.tsx54
3 files changed, 57 insertions, 5 deletions
diff --git a/packages/website/ts/components/inputs/allowance_toggle.tsx b/packages/website/ts/components/inputs/allowance_toggle.tsx
index d8852c11f..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,6 +75,7 @@ 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,
diff --git a/packages/website/ts/components/inputs/balance_bounded_input.tsx b/packages/website/ts/components/inputs/balance_bounded_input.tsx
index ddc434b51..67d5b781e 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}
/>
);
}
diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx
index 63966d759..f41d42d02 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 { 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,39 @@ 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> {
+ constructor(props: TokenAmountInputProps) {
+ super(props);
+ 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);
+ }
+ 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
+ ) {
+ this._fetchBalanceAndAllowanceAsync(nextProps.token.address);
+ }
+ }
public render() {
const amount = this.props.amount
? ZeroEx.toUnitAmount(this.props.amount, this.props.token.decimals)
@@ -32,12 +63,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 +83,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 +99,18 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
return undefined;
}
}
+ private async _fetchBalanceAndAllowanceAsync(tokenAddress: string) {
+ this.setState({
+ isBalanceAndAllowanceLoaded: false,
+ });
+ const [balance, allowance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync(
+ this.props.userAddress,
+ tokenAddress,
+ );
+ this.setState({
+ balance,
+ allowance,
+ isBalanceAndAllowanceLoaded: true,
+ });
+ }
}