diff options
Diffstat (limited to 'packages/website/ts/components/inputs/token_amount_input.tsx')
-rw-r--r-- | packages/website/ts/components/inputs/token_amount_input.tsx | 64 |
1 files changed, 59 insertions, 5 deletions
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, + }); + } + } } |