diff options
author | Leonid <logvinov.leon@gmail.com> | 2018-02-05 19:33:40 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-05 19:33:40 +0800 |
commit | 7b4f2b47de393b7ed6d5c264c8e80864d196180c (patch) | |
tree | 8e86af8000e0aedd7241a00c2189d8f7ca0fc2ad /packages/website/ts/components/dialogs | |
parent | 400a97e7a8f76d894d47368425bbe1e33fa5b255 (diff) | |
parent | c7ad6ebad6ab65a4b1e4a2084e744c6ca2bc09b8 (diff) | |
download | dexon-0x-contracts-7b4f2b47de393b7ed6d5c264c8e80864d196180c.tar.gz dexon-0x-contracts-7b4f2b47de393b7ed6d5c264c8e80864d196180c.tar.zst dexon-0x-contracts-7b4f2b47de393b7ed6d5c264c8e80864d196180c.zip |
Merge branch 'development' into fix/ether_token_address
Diffstat (limited to 'packages/website/ts/components/dialogs')
5 files changed, 112 insertions, 41 deletions
diff --git a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx index f555ca6b1..278e2bbf5 100644 --- a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx +++ b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx @@ -3,7 +3,7 @@ import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; import { Blockchain } from 'ts/blockchain'; -import { BlockchainErrs } from 'ts/types'; +import { BlockchainErrs, Networks } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; @@ -129,7 +129,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp <div> The 0x smart contracts are not deployed on the Ethereum network you are currently connected to (network Id: {this.props.networkId}). In order to use the 0x portal dApp, please connect to the{' '} - {constants.TESTNET_NAME} testnet (network Id: {constants.NETWORK_ID_TESTNET}) + {Networks.Kovan} testnet (network Id: {constants.NETWORK_ID_KOVAN}) {configs.IS_MAINNET_ENABLED ? ` or ${constants.MAINNET_NAME} (network Id: ${constants.NETWORK_ID_MAINNET}).` : `.`} diff --git a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx index 661cc1d8c..acd4a7110 100644 --- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx +++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx @@ -2,38 +2,55 @@ import { BigNumber } from '@0xproject/utils'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; +import { Blockchain } from 'ts/blockchain'; import { EthAmountInput } from 'ts/components/inputs/eth_amount_input'; import { TokenAmountInput } from 'ts/components/inputs/token_amount_input'; -import { Side, Token, TokenState } from 'ts/types'; +import { Side, Token } from 'ts/types'; import { colors } from 'ts/utils/colors'; interface EthWethConversionDialogProps { + blockchain: Blockchain; + userAddress: string; + networkId: number; direction: Side; onComplete: (direction: Side, value: BigNumber) => void; onCancelled: () => void; isOpen: boolean; token: Token; - tokenState: TokenState; etherBalance: BigNumber; + lastForceTokenStateRefetch: number; } interface EthWethConversionDialogState { value?: BigNumber; shouldShowIncompleteErrs: boolean; hasErrors: boolean; + isEthTokenBalanceLoaded: boolean; + ethTokenBalance: BigNumber; } export class EthWethConversionDialog extends React.Component< EthWethConversionDialogProps, EthWethConversionDialogState > { + private _isUnmounted: boolean; constructor() { super(); + this._isUnmounted = false; this.state = { shouldShowIncompleteErrs: false, hasErrors: false, + isEthTokenBalanceLoaded: false, + ethTokenBalance: new BigNumber(0), }; } + public componentWillMount() { + // tslint:disable-next-line:no-floating-promises + this._fetchEthTokenBalanceAsync(); + } + public componentWillUnmount() { + this._isUnmounted = true; + } public render() { const convertDialogActions = [ <FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, @@ -72,8 +89,11 @@ export class EthWethConversionDialog extends React.Component< <div className="pt2 mx-auto" style={{ width: 245 }}> {this.props.direction === Side.Receive ? ( <TokenAmountInput + lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} + blockchain={this.props.blockchain} + userAddress={this.props.userAddress} + networkId={this.props.networkId} token={this.props.token} - tokenState={this.props.tokenState} shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs} shouldCheckBalance={true} shouldCheckAllowance={false} @@ -93,19 +113,20 @@ export class EthWethConversionDialog extends React.Component< )} <div className="pt1" style={{ fontSize: 12 }}> <div className="left">1 ETH = 1 WETH</div> - {this.props.direction === Side.Receive && ( - <div - className="right" - onClick={this._onMaxClick.bind(this)} - style={{ - color: colors.darkBlue, - textDecoration: 'underline', - cursor: 'pointer', - }} - > - Max - </div> - )} + {this.props.direction === Side.Receive && + this.state.isEthTokenBalanceLoaded && ( + <div + className="right" + onClick={this._onMaxClick.bind(this)} + style={{ + color: colors.darkBlue, + textDecoration: 'underline', + cursor: 'pointer', + }} + > + Max + </div> + )} </div> </div> </div> @@ -132,7 +153,7 @@ export class EthWethConversionDialog extends React.Component< } private _onMaxClick() { this.setState({ - value: this.props.tokenState.balance, + value: this.state.ethTokenBalance, }); } private _onValueChange(isValid: boolean, amount?: BigNumber) { @@ -160,4 +181,16 @@ export class EthWethConversionDialog extends React.Component< }); this.props.onCancelled(); } + private async _fetchEthTokenBalanceAsync() { + const [balance] = await this.props.blockchain.getTokenBalanceAndAllowanceAsync( + this.props.userAddress, + this.props.token.address, + ); + if (!this._isUnmounted) { + this.setState({ + isEthTokenBalanceLoaded: true, + ethTokenBalance: balance, + }); + } + } } diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx index 60db93c52..bc5f05241 100644 --- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx +++ b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx @@ -7,8 +7,10 @@ import TextField from 'material-ui/TextField'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); import { Blockchain } from 'ts/blockchain'; +import { NetworkDropDown } from 'ts/components/dropdowns/network_drop_down'; import { LifeCycleRaisedButton } from 'ts/components/ui/lifecycle_raised_button'; import { Dispatcher } from 'ts/redux/dispatcher'; +import { ProviderType } from 'ts/types'; import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; @@ -27,27 +29,33 @@ interface LedgerConfigDialogProps { dispatcher: Dispatcher; blockchain: Blockchain; networkId: number; + providerType: ProviderType; } interface LedgerConfigDialogState { - didConnectFail: boolean; + connectionErrMsg: string; stepIndex: LedgerSteps; userAddresses: string[]; addressBalances: BigNumber[]; derivationPath: string; derivationErrMsg: string; + preferredNetworkId: number; } export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, LedgerConfigDialogState> { constructor(props: LedgerConfigDialogProps) { super(props); + const derivationPathIfExists = props.blockchain.getLedgerDerivationPathIfExists(); this.state = { - didConnectFail: false, + connectionErrMsg: '', stepIndex: LedgerSteps.CONNECT, userAddresses: [], addressBalances: [], - derivationPath: configs.DEFAULT_DERIVATION_PATH, + derivationPath: _.isUndefined(derivationPathIfExists) + ? configs.DEFAULT_DERIVATION_PATH + : derivationPathIfExists, derivationErrMsg: '', + preferredNetworkId: props.networkId, }; } public render() { @@ -74,19 +82,28 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, ); } private _renderConnectStep() { + const networkIds = _.values(constants.NETWORK_ID_BY_NAME); return ( <div> <div className="h4 pt3">Follow these instructions before proceeding:</div> - <ol> + <ol className="mb0"> <li className="pb1">Connect your Ledger Nano S & Open the Ethereum application</li> - <li className="pb1">Verify that Browser Support is enabled in Settings</li> + <li className="pb1">Verify that "Browser Support" AND "Contract Data" are enabled in Settings</li> <li className="pb1"> If no Browser Support is found in settings, verify that you have{' '} <a href="https://www.ledgerwallet.com/apps/manager" target="_blank"> Firmware >1.2 </a> </li> + <li>Choose your desired network:</li> </ol> + <div className="pb2"> + <NetworkDropDown + updateSelectedNetwork={this._onSelectedNetworkUpdated.bind(this)} + selectedNetworkId={this.state.preferredNetworkId} + avialableNetworkIds={networkIds} + /> + </div> <div className="center pb3"> <LifeCycleRaisedButton isPrimary={true} @@ -95,9 +112,9 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, labelComplete="Connected!" onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)} /> - {this.state.didConnectFail && ( + {!_.isEmpty(this.state.connectionErrMsg) && ( <div className="pt2 left-align" style={{ color: colors.red200 }}> - Failed to connect. Follow the instructions and try again. + {this.state.connectionErrMsg} </div> )} </div> @@ -172,7 +189,8 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, } private _onClose() { this.setState({ - didConnectFail: false, + connectionErrMsg: '', + stepIndex: LedgerSteps.CONNECT, }); const isOpen = false; this.props.toggleDialogFn(isOpen); @@ -184,6 +202,8 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, const selectAddressBalance = this.state.addressBalances[selectedRowIndex]; this.props.dispatcher.updateUserAddress(selectedAddress); this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress); + // tslint:disable-next-line:no-floating-promises + this.props.blockchain.fetchTokenInformationAsync(); this.props.dispatcher.updateUserEtherBalance(selectAddressBalance); this.setState({ stepIndex: LedgerSteps.CONNECT, @@ -219,7 +239,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, } catch (err) { utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`); this.setState({ - didConnectFail: true, + connectionErrMsg: 'Failed to connect. Follow the instructions and try again.', }); return false; } @@ -241,6 +261,22 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, }); } private async _onConnectLedgerClickAsync() { + const isU2FSupported = await utils.isU2FSupportedAsync(); + if (!isU2FSupported) { + utils.consoleLog(`U2F not supported in this browser`); + this.setState({ + connectionErrMsg: 'U2F not supported by this browser. Try using Chrome.', + }); + return false; + } + + if ( + this.props.providerType !== ProviderType.Ledger || + (this.props.providerType === ProviderType.Ledger && this.props.networkId !== this.state.preferredNetworkId) + ) { + await this.props.blockchain.updateProviderToLedgerAsync(this.state.preferredNetworkId); + } + const didSucceed = await this._fetchAddressesAndBalancesAsync(); if (didSucceed) { this.setState({ @@ -258,4 +294,9 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, } return userAddresses; } + private _onSelectedNetworkUpdated(e: any, index: number, networkId: number) { + this.setState({ + preferredNetworkId: networkId, + }); + } } diff --git a/packages/website/ts/components/dialogs/send_dialog.tsx b/packages/website/ts/components/dialogs/send_dialog.tsx index b3dbce598..d44dd9aab 100644 --- a/packages/website/ts/components/dialogs/send_dialog.tsx +++ b/packages/website/ts/components/dialogs/send_dialog.tsx @@ -3,16 +3,20 @@ import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; +import { Blockchain } from 'ts/blockchain'; import { AddressInput } from 'ts/components/inputs/address_input'; import { TokenAmountInput } from 'ts/components/inputs/token_amount_input'; -import { Token, TokenState } from 'ts/types'; +import { Token } from 'ts/types'; interface SendDialogProps { + blockchain: Blockchain; + userAddress: string; + networkId: number; onComplete: (recipient: string, value: BigNumber) => void; onCancelled: () => void; isOpen: boolean; token: Token; - tokenState: TokenState; + lastForceTokenStateRefetch: number; } interface SendDialogState { @@ -66,15 +70,18 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState /> </div> <TokenAmountInput + blockchain={this.props.blockchain} + userAddress={this.props.userAddress} + networkId={this.props.networkId} label="Amount to send" token={this.props.token} - tokenState={this.props.tokenState} shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs} shouldCheckBalance={true} shouldCheckAllowance={false} onChange={this._onValueChange.bind(this)} amount={this.state.value} onVisitBalancesPageClick={this.props.onCancelled} + lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} /> </div> ); diff --git a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx index 3f29d46f8..bb7e3ed1a 100644 --- a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx +++ b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx @@ -82,16 +82,6 @@ export class TrackTokenConfirmationDialog extends React.Component< newTokenEntry.isTracked = true; trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry); this.props.dispatcher.updateTokenByAddress([newTokenEntry]); - - const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync( - token.address, - ); - this.props.dispatcher.updateTokenStateByAddress({ - [token.address]: { - balance, - allowance, - }, - }); } this.setState({ |