diff options
Diffstat (limited to 'packages/website/ts/components/dialogs')
8 files changed, 780 insertions, 780 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..e0f61a29b 100644 --- a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx +++ b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx @@ -9,150 +9,150 @@ import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; interface BlockchainErrDialogProps { - blockchain: Blockchain; - blockchainErr: BlockchainErrs; - isOpen: boolean; - userAddress: string; - toggleDialogFn: (isOpen: boolean) => void; - networkId: number; + blockchain: Blockchain; + blockchainErr: BlockchainErrs; + isOpen: boolean; + userAddress: string; + toggleDialogFn: (isOpen: boolean) => void; + networkId: number; } export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProps, undefined> { - public render() { - const dialogActions = [ - <FlatButton - key="blockchainErrOk" - label="Ok" - primary={true} - onTouchTap={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)} - />, - ]; + public render() { + const dialogActions = [ + <FlatButton + key="blockchainErrOk" + label="Ok" + primary={true} + onTouchTap={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)} + />, + ]; - const hasWalletAddress = this.props.userAddress !== ''; - return ( - <Dialog - title={this._getTitle(hasWalletAddress)} - titleStyle={{ fontWeight: 100 }} - actions={dialogActions} - open={this.props.isOpen} - contentStyle={{ width: 400 }} - onRequestClose={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)} - autoScrollBodyContent={true} - > - <div className="pt2" style={{ color: colors.grey700 }}> - {this._renderExplanation(hasWalletAddress)} - </div> - </Dialog> - ); - } - private _getTitle(hasWalletAddress: boolean) { - if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) { - return '0x smart contracts not found'; - } else if (!hasWalletAddress) { - return 'Enable wallet communication'; - } else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) { - return 'Disconnected from Ethereum network'; - } else { - return 'Unexpected error'; - } - } - private _renderExplanation(hasWalletAddress: boolean) { - if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) { - return this._renderContractsNotDeployedExplanation(); - } else if (!hasWalletAddress) { - return this._renderNoWalletFoundExplanation(); - } else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) { - return this._renderDisconnectedFromNode(); - } else { - return this._renderUnexpectedErrorExplanation(); - } - } - private _renderDisconnectedFromNode() { - return ( - <div> - You were disconnected from the backing Ethereum node. If using{' '} - <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank"> - Metamask - </a>{' '} - or{' '} - <a href={constants.URL_MIST_DOWNLOAD} target="_blank"> - Mist - </a>{' '} - try refreshing the page. If using a locally hosted Ethereum node, make sure it's still running. - </div> - ); - } - private _renderUnexpectedErrorExplanation() { - return <div>We encountered an unexpected error. Please try refreshing the page.</div>; - } - private _renderNoWalletFoundExplanation() { - return ( - <div> - <div> - We were unable to access an Ethereum wallet you control. In order to interact with the 0x portal - dApp, we need a way to interact with one of your Ethereum wallets. There are two easy ways you can - enable us to do that: - </div> - <h4>1. Metamask chrome extension</h4> - <div> - You can install the{' '} - <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank"> - Metamask - </a>{' '} - Chrome extension Ethereum wallet. Once installed and set up, refresh this page. - <div className="pt1"> - <span className="bold">Note:</span> If you already have Metamask installed, make sure it is - unlocked. - </div> - </div> - <h4>Parity Signer</h4> - <div> - The{' '} - <a href={constants.URL_PARITY_CHROME_STORE} target="_blank"> - Parity Signer Chrome extension - </a>{' '} - lets you connect to a locally running Parity node. Make sure you have started your local Parity node - with {configs.IS_MAINNET_ENABLED && '`parity ui` or'} `parity --chain kovan ui` in order to connect - to {configs.IS_MAINNET_ENABLED ? 'mainnet or Kovan respectively.' : 'Kovan.'} - </div> - <div className="pt2"> - <span className="bold">Note:</span> If you have done one of the above steps and are still seeing - this message, we might still be unable to retrieve an Ethereum address by calling - `web3.eth.accounts`. Make sure you have created at least one Ethereum address. - </div> - </div> - ); - } - private _renderContractsNotDeployedExplanation() { - return ( - <div> - <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}) - {configs.IS_MAINNET_ENABLED - ? ` or ${constants.MAINNET_NAME} (network Id: ${constants.NETWORK_ID_MAINNET}).` - : `.`} - </div> - <h4>Metamask</h4> - <div> - If you are using{' '} - <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank"> - Metamask - </a>, you can switch networks in the top left corner of the extension popover. - </div> - <h4>Parity Signer</h4> - <div> - If using the{' '} - <a href={constants.URL_PARITY_CHROME_STORE} target="_blank"> - Parity Signer Chrome extension - </a>, make sure to start your local Parity node with{' '} - {configs.IS_MAINNET_ENABLED - ? '`parity ui` or `parity --chain Kovan ui` in order to connect to mainnet \ + const hasWalletAddress = this.props.userAddress !== ''; + return ( + <Dialog + title={this._getTitle(hasWalletAddress)} + titleStyle={{ fontWeight: 100 }} + actions={dialogActions} + open={this.props.isOpen} + contentStyle={{ width: 400 }} + onRequestClose={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)} + autoScrollBodyContent={true} + > + <div className="pt2" style={{ color: colors.grey700 }}> + {this._renderExplanation(hasWalletAddress)} + </div> + </Dialog> + ); + } + private _getTitle(hasWalletAddress: boolean) { + if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) { + return '0x smart contracts not found'; + } else if (!hasWalletAddress) { + return 'Enable wallet communication'; + } else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) { + return 'Disconnected from Ethereum network'; + } else { + return 'Unexpected error'; + } + } + private _renderExplanation(hasWalletAddress: boolean) { + if (this.props.blockchainErr === BlockchainErrs.AContractNotDeployedOnNetwork) { + return this._renderContractsNotDeployedExplanation(); + } else if (!hasWalletAddress) { + return this._renderNoWalletFoundExplanation(); + } else if (this.props.blockchainErr === BlockchainErrs.DisconnectedFromEthereumNode) { + return this._renderDisconnectedFromNode(); + } else { + return this._renderUnexpectedErrorExplanation(); + } + } + private _renderDisconnectedFromNode() { + return ( + <div> + You were disconnected from the backing Ethereum node. If using{' '} + <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank"> + Metamask + </a>{' '} + or{' '} + <a href={constants.URL_MIST_DOWNLOAD} target="_blank"> + Mist + </a>{' '} + try refreshing the page. If using a locally hosted Ethereum node, make sure it's still running. + </div> + ); + } + private _renderUnexpectedErrorExplanation() { + return <div>We encountered an unexpected error. Please try refreshing the page.</div>; + } + private _renderNoWalletFoundExplanation() { + return ( + <div> + <div> + We were unable to access an Ethereum wallet you control. In order to interact with the 0x portal + dApp, we need a way to interact with one of your Ethereum wallets. There are two easy ways you can + enable us to do that: + </div> + <h4>1. Metamask chrome extension</h4> + <div> + You can install the{' '} + <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank"> + Metamask + </a>{' '} + Chrome extension Ethereum wallet. Once installed and set up, refresh this page. + <div className="pt1"> + <span className="bold">Note:</span> If you already have Metamask installed, make sure it is + unlocked. + </div> + </div> + <h4>Parity Signer</h4> + <div> + The{' '} + <a href={constants.URL_PARITY_CHROME_STORE} target="_blank"> + Parity Signer Chrome extension + </a>{' '} + lets you connect to a locally running Parity node. Make sure you have started your local Parity node + with {configs.IS_MAINNET_ENABLED && '`parity ui` or'} `parity --chain kovan ui` in order to connect + to {configs.IS_MAINNET_ENABLED ? 'mainnet or Kovan respectively.' : 'Kovan.'} + </div> + <div className="pt2"> + <span className="bold">Note:</span> If you have done one of the above steps and are still seeing + this message, we might still be unable to retrieve an Ethereum address by calling + `web3.eth.accounts`. Make sure you have created at least one Ethereum address. + </div> + </div> + ); + } + private _renderContractsNotDeployedExplanation() { + return ( + <div> + <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}) + {configs.IS_MAINNET_ENABLED + ? ` or ${constants.MAINNET_NAME} (network Id: ${constants.NETWORK_ID_MAINNET}).` + : `.`} + </div> + <h4>Metamask</h4> + <div> + If you are using{' '} + <a href={constants.URL_METAMASK_CHROME_STORE} target="_blank"> + Metamask + </a>, you can switch networks in the top left corner of the extension popover. + </div> + <h4>Parity Signer</h4> + <div> + If using the{' '} + <a href={constants.URL_PARITY_CHROME_STORE} target="_blank"> + Parity Signer Chrome extension + </a>, make sure to start your local Parity node with{' '} + {configs.IS_MAINNET_ENABLED + ? '`parity ui` or `parity --chain Kovan ui` in order to connect to mainnet \ or Kovan respectively.' - : '`parity --chain kovan ui` in order to connect to Kovan.'} - </div> - </div> - ); - } + : '`parity --chain kovan ui` in order to connect to Kovan.'} + </div> + </div> + ); + } } 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..45ba5cc9e 100644 --- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx +++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx @@ -8,156 +8,156 @@ import { Side, Token, TokenState } from 'ts/types'; import { colors } from 'ts/utils/colors'; interface EthWethConversionDialogProps { - direction: Side; - onComplete: (direction: Side, value: BigNumber) => void; - onCancelled: () => void; - isOpen: boolean; - token: Token; - tokenState: TokenState; - etherBalance: BigNumber; + direction: Side; + onComplete: (direction: Side, value: BigNumber) => void; + onCancelled: () => void; + isOpen: boolean; + token: Token; + tokenState: TokenState; + etherBalance: BigNumber; } interface EthWethConversionDialogState { - value?: BigNumber; - shouldShowIncompleteErrs: boolean; - hasErrors: boolean; + value?: BigNumber; + shouldShowIncompleteErrs: boolean; + hasErrors: boolean; } export class EthWethConversionDialog extends React.Component< - EthWethConversionDialogProps, - EthWethConversionDialogState + EthWethConversionDialogProps, + EthWethConversionDialogState > { - constructor() { - super(); - this.state = { - shouldShowIncompleteErrs: false, - hasErrors: false, - }; - } - public render() { - const convertDialogActions = [ - <FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, - <FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />, - ]; - const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH'; - return ( - <Dialog - title={title} - titleStyle={{ fontWeight: 100 }} - actions={convertDialogActions} - contentStyle={{ width: 448 }} - open={this.props.isOpen} - > - {this._renderConversionDialogBody()} - </Dialog> - ); - } - private _renderConversionDialogBody() { - const explanation = - this.props.direction === Side.Deposit - ? 'Convert your Ether into a tokenized, tradable form.' - : "Convert your Wrapped Ether back into it's native form."; - const isWrappedVersion = this.props.direction === Side.Receive; - return ( - <div> - <div className="pb2">{explanation}</div> - <div className="mx-auto" style={{ maxWidth: 312 }}> - <div className="flex"> - {this._renderCurrency(isWrappedVersion)} - <div style={{ paddingTop: 68 }}> - <i style={{ fontSize: 28, color: colors.darkBlue }} className="zmdi zmdi-arrow-right" /> - </div> - {this._renderCurrency(!isWrappedVersion)} - </div> - <div className="pt2 mx-auto" style={{ width: 245 }}> - {this.props.direction === Side.Receive ? ( - <TokenAmountInput - 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} - /> - ) : ( - <EthAmountInput - balance={this.props.etherBalance} - amount={this.state.value} - onChange={this._onValueChange.bind(this)} - shouldCheckBalance={true} - shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs} - onVisitBalancesPageClick={this.props.onCancelled} - /> - )} - <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> - )} - </div> - </div> - </div> - </div> - ); - } - private _renderCurrency(isWrappedVersion: boolean) { - const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether'; - const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png'; - const symbol = isWrappedVersion ? 'WETH' : 'ETH'; - return ( - <div className="mx-auto pt2"> - <div className="center" style={{ color: colors.darkBlue }}> - {name} - </div> - <div className="center py2"> - <img src={iconUrl} style={{ width: 60 }} /> - </div> - <div className="center" style={{ fontSize: 12 }}> - ({symbol}) - </div> - </div> - ); - } - private _onMaxClick() { - this.setState({ - value: this.props.tokenState.balance, - }); - } - private _onValueChange(isValid: boolean, amount?: BigNumber) { - this.setState({ - value: amount, - hasErrors: !isValid, - }); - } - private _onConvertClick() { - if (this.state.hasErrors) { - this.setState({ - shouldShowIncompleteErrs: true, - }); - } else { - const value = this.state.value; - this.setState({ - value: undefined, - }); - this.props.onComplete(this.props.direction, value); - } - } - private _onCancel() { - this.setState({ - value: undefined, - }); - this.props.onCancelled(); - } + constructor() { + super(); + this.state = { + shouldShowIncompleteErrs: false, + hasErrors: false, + }; + } + public render() { + const convertDialogActions = [ + <FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, + <FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />, + ]; + const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH'; + return ( + <Dialog + title={title} + titleStyle={{ fontWeight: 100 }} + actions={convertDialogActions} + contentStyle={{ width: 448 }} + open={this.props.isOpen} + > + {this._renderConversionDialogBody()} + </Dialog> + ); + } + private _renderConversionDialogBody() { + const explanation = + this.props.direction === Side.Deposit + ? 'Convert your Ether into a tokenized, tradable form.' + : "Convert your Wrapped Ether back into it's native form."; + const isWrappedVersion = this.props.direction === Side.Receive; + return ( + <div> + <div className="pb2">{explanation}</div> + <div className="mx-auto" style={{ maxWidth: 312 }}> + <div className="flex"> + {this._renderCurrency(isWrappedVersion)} + <div style={{ paddingTop: 68 }}> + <i style={{ fontSize: 28, color: colors.darkBlue }} className="zmdi zmdi-arrow-right" /> + </div> + {this._renderCurrency(!isWrappedVersion)} + </div> + <div className="pt2 mx-auto" style={{ width: 245 }}> + {this.props.direction === Side.Receive ? ( + <TokenAmountInput + 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} + /> + ) : ( + <EthAmountInput + balance={this.props.etherBalance} + amount={this.state.value} + onChange={this._onValueChange.bind(this)} + shouldCheckBalance={true} + shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs} + onVisitBalancesPageClick={this.props.onCancelled} + /> + )} + <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> + )} + </div> + </div> + </div> + </div> + ); + } + private _renderCurrency(isWrappedVersion: boolean) { + const name = isWrappedVersion ? 'Wrapped Ether' : 'Ether'; + const iconUrl = isWrappedVersion ? '/images/token_icons/ether_erc20.png' : '/images/ether.png'; + const symbol = isWrappedVersion ? 'WETH' : 'ETH'; + return ( + <div className="mx-auto pt2"> + <div className="center" style={{ color: colors.darkBlue }}> + {name} + </div> + <div className="center py2"> + <img src={iconUrl} style={{ width: 60 }} /> + </div> + <div className="center" style={{ fontSize: 12 }}> + ({symbol}) + </div> + </div> + ); + } + private _onMaxClick() { + this.setState({ + value: this.props.tokenState.balance, + }); + } + private _onValueChange(isValid: boolean, amount?: BigNumber) { + this.setState({ + value: amount, + hasErrors: !isValid, + }); + } + private _onConvertClick() { + if (this.state.hasErrors) { + this.setState({ + shouldShowIncompleteErrs: true, + }); + } else { + const value = this.state.value; + this.setState({ + value: undefined, + }); + this.props.onComplete(this.props.direction, value); + } + } + private _onCancel() { + this.setState({ + value: undefined, + }); + this.props.onCancelled(); + } } diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx index 60db93c52..8b7760a1a 100644 --- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx +++ b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx @@ -17,245 +17,245 @@ import { utils } from 'ts/utils/utils'; const VALID_ETHEREUM_DERIVATION_PATH_PREFIX = `44'/60'`; enum LedgerSteps { - CONNECT, - SELECT_ADDRESS, + CONNECT, + SELECT_ADDRESS, } interface LedgerConfigDialogProps { - isOpen: boolean; - toggleDialogFn: (isOpen: boolean) => void; - dispatcher: Dispatcher; - blockchain: Blockchain; - networkId: number; + isOpen: boolean; + toggleDialogFn: (isOpen: boolean) => void; + dispatcher: Dispatcher; + blockchain: Blockchain; + networkId: number; } interface LedgerConfigDialogState { - didConnectFail: boolean; - stepIndex: LedgerSteps; - userAddresses: string[]; - addressBalances: BigNumber[]; - derivationPath: string; - derivationErrMsg: string; + didConnectFail: boolean; + stepIndex: LedgerSteps; + userAddresses: string[]; + addressBalances: BigNumber[]; + derivationPath: string; + derivationErrMsg: string; } export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, LedgerConfigDialogState> { - constructor(props: LedgerConfigDialogProps) { - super(props); - this.state = { - didConnectFail: false, - stepIndex: LedgerSteps.CONNECT, - userAddresses: [], - addressBalances: [], - derivationPath: configs.DEFAULT_DERIVATION_PATH, - derivationErrMsg: '', - }; - } - public render() { - const dialogActions = [ - <FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />, - ]; - const dialogTitle = - this.state.stepIndex === LedgerSteps.CONNECT ? 'Connect to your Ledger' : 'Select desired address'; - return ( - <Dialog - title={dialogTitle} - titleStyle={{ fontWeight: 100 }} - actions={dialogActions} - open={this.props.isOpen} - onRequestClose={this._onClose.bind(this)} - autoScrollBodyContent={true} - bodyStyle={{ paddingBottom: 0 }} - > - <div style={{ color: colors.grey700, paddingTop: 1 }}> - {this.state.stepIndex === LedgerSteps.CONNECT && this._renderConnectStep()} - {this.state.stepIndex === LedgerSteps.SELECT_ADDRESS && this._renderSelectAddressStep()} - </div> - </Dialog> - ); - } - private _renderConnectStep() { - return ( - <div> - <div className="h4 pt3">Follow these instructions before proceeding:</div> - <ol> - <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"> - 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> - </ol> - <div className="center pb3"> - <LifeCycleRaisedButton - isPrimary={true} - labelReady="Connect to Ledger" - labelLoading="Connecting..." - labelComplete="Connected!" - onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)} - /> - {this.state.didConnectFail && ( - <div className="pt2 left-align" style={{ color: colors.red200 }}> - Failed to connect. Follow the instructions and try again. - </div> - )} - </div> - </div> - ); - } - private _renderSelectAddressStep() { - return ( - <div> - <div> - <Table bodyStyle={{ height: 300 }} onRowSelection={this._onAddressSelected.bind(this)}> - <TableHeader displaySelectAll={false}> - <TableRow> - <TableHeaderColumn colSpan={2}>Address</TableHeaderColumn> - <TableHeaderColumn>Balance</TableHeaderColumn> - </TableRow> - </TableHeader> - <TableBody>{this._renderAddressTableRows()}</TableBody> - </Table> - </div> - <div className="flex pt2" style={{ height: 100 }}> - <div className="overflow-hidden" style={{ width: 180 }}> - <TextField - floatingLabelFixed={true} - floatingLabelStyle={{ color: colors.grey }} - floatingLabelText="Update path derivation (advanced)" - value={this.state.derivationPath} - errorText={this.state.derivationErrMsg} - onChange={this._onDerivationPathChanged.bind(this)} - /> - </div> - <div className="pl2" style={{ paddingTop: 28 }}> - <LifeCycleRaisedButton - labelReady="Update" - labelLoading="Updating..." - labelComplete="Updated!" - onClickAsyncFn={this._onFetchAddressesForDerivationPathAsync.bind(this)} - /> - </div> - </div> - </div> - ); - } - private _renderAddressTableRows() { - const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => { - const balance = this.state.addressBalances[i]; - const addressTooltipId = `address-${userAddress}`; - const balanceTooltipId = `balance-${userAddress}`; - const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; - // We specifically prefix kovan ETH. - // TODO: We should probably add prefixes for all networks - const isKovanNetwork = networkName === 'Kovan'; - const balanceString = `${balance.toString()} ${isKovanNetwork ? 'Kovan ' : ''}ETH`; - return ( - <TableRow key={userAddress} style={{ height: 40 }}> - <TableRowColumn colSpan={2}> - <div data-tip={true} data-for={addressTooltipId}> - {userAddress} - </div> - <ReactTooltip id={addressTooltipId}>{userAddress}</ReactTooltip> - </TableRowColumn> - <TableRowColumn> - <div data-tip={true} data-for={balanceTooltipId}> - {balanceString} - </div> - <ReactTooltip id={balanceTooltipId}>{balanceString}</ReactTooltip> - </TableRowColumn> - </TableRow> - ); - }); - return rows; - } - private _onClose() { - this.setState({ - didConnectFail: false, - }); - const isOpen = false; - this.props.toggleDialogFn(isOpen); - } - private _onAddressSelected(selectedRowIndexes: number[]) { - const selectedRowIndex = selectedRowIndexes[0]; - this.props.blockchain.updateLedgerDerivationIndex(selectedRowIndex); - const selectedAddress = this.state.userAddresses[selectedRowIndex]; - const selectAddressBalance = this.state.addressBalances[selectedRowIndex]; - this.props.dispatcher.updateUserAddress(selectedAddress); - this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress); - this.props.dispatcher.updateUserEtherBalance(selectAddressBalance); - this.setState({ - stepIndex: LedgerSteps.CONNECT, - }); - const isOpen = false; - this.props.toggleDialogFn(isOpen); - } - private async _onFetchAddressesForDerivationPathAsync(): Promise<boolean> { - const currentlySetPath = this.props.blockchain.getLedgerDerivationPathIfExists(); - let didSucceed; - if (currentlySetPath === this.state.derivationPath) { - didSucceed = true; - return didSucceed; - } - this.props.blockchain.updateLedgerDerivationPathIfExists(this.state.derivationPath); - didSucceed = await this._fetchAddressesAndBalancesAsync(); - if (!didSucceed) { - this.setState({ - derivationErrMsg: 'Failed to connect to Ledger.', - }); - } - return didSucceed; - } - private async _fetchAddressesAndBalancesAsync() { - let userAddresses: string[]; - const addressBalances: BigNumber[] = []; - try { - userAddresses = await this._getUserAddressesAsync(); - for (const address of userAddresses) { - const balance = await this.props.blockchain.getBalanceInEthAsync(address); - addressBalances.push(balance); - } - } catch (err) { - utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`); - this.setState({ - didConnectFail: true, - }); - return false; - } - this.setState({ - userAddresses, - addressBalances, - }); - return true; - } - private _onDerivationPathChanged(e: any, derivationPath: string) { - let derivationErrMsg = ''; - if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) { - derivationErrMsg = 'Must be valid Ethereum path.'; - } + constructor(props: LedgerConfigDialogProps) { + super(props); + this.state = { + didConnectFail: false, + stepIndex: LedgerSteps.CONNECT, + userAddresses: [], + addressBalances: [], + derivationPath: configs.DEFAULT_DERIVATION_PATH, + derivationErrMsg: '', + }; + } + public render() { + const dialogActions = [ + <FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />, + ]; + const dialogTitle = + this.state.stepIndex === LedgerSteps.CONNECT ? 'Connect to your Ledger' : 'Select desired address'; + return ( + <Dialog + title={dialogTitle} + titleStyle={{ fontWeight: 100 }} + actions={dialogActions} + open={this.props.isOpen} + onRequestClose={this._onClose.bind(this)} + autoScrollBodyContent={true} + bodyStyle={{ paddingBottom: 0 }} + > + <div style={{ color: colors.grey700, paddingTop: 1 }}> + {this.state.stepIndex === LedgerSteps.CONNECT && this._renderConnectStep()} + {this.state.stepIndex === LedgerSteps.SELECT_ADDRESS && this._renderSelectAddressStep()} + </div> + </Dialog> + ); + } + private _renderConnectStep() { + return ( + <div> + <div className="h4 pt3">Follow these instructions before proceeding:</div> + <ol> + <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"> + 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> + </ol> + <div className="center pb3"> + <LifeCycleRaisedButton + isPrimary={true} + labelReady="Connect to Ledger" + labelLoading="Connecting..." + labelComplete="Connected!" + onClickAsyncFn={this._onConnectLedgerClickAsync.bind(this, true)} + /> + {this.state.didConnectFail && ( + <div className="pt2 left-align" style={{ color: colors.red200 }}> + Failed to connect. Follow the instructions and try again. + </div> + )} + </div> + </div> + ); + } + private _renderSelectAddressStep() { + return ( + <div> + <div> + <Table bodyStyle={{ height: 300 }} onRowSelection={this._onAddressSelected.bind(this)}> + <TableHeader displaySelectAll={false}> + <TableRow> + <TableHeaderColumn colSpan={2}>Address</TableHeaderColumn> + <TableHeaderColumn>Balance</TableHeaderColumn> + </TableRow> + </TableHeader> + <TableBody>{this._renderAddressTableRows()}</TableBody> + </Table> + </div> + <div className="flex pt2" style={{ height: 100 }}> + <div className="overflow-hidden" style={{ width: 180 }}> + <TextField + floatingLabelFixed={true} + floatingLabelStyle={{ color: colors.grey }} + floatingLabelText="Update path derivation (advanced)" + value={this.state.derivationPath} + errorText={this.state.derivationErrMsg} + onChange={this._onDerivationPathChanged.bind(this)} + /> + </div> + <div className="pl2" style={{ paddingTop: 28 }}> + <LifeCycleRaisedButton + labelReady="Update" + labelLoading="Updating..." + labelComplete="Updated!" + onClickAsyncFn={this._onFetchAddressesForDerivationPathAsync.bind(this)} + /> + </div> + </div> + </div> + ); + } + private _renderAddressTableRows() { + const rows = _.map(this.state.userAddresses, (userAddress: string, i: number) => { + const balance = this.state.addressBalances[i]; + const addressTooltipId = `address-${userAddress}`; + const balanceTooltipId = `balance-${userAddress}`; + const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; + // We specifically prefix kovan ETH. + // TODO: We should probably add prefixes for all networks + const isKovanNetwork = networkName === 'Kovan'; + const balanceString = `${balance.toString()} ${isKovanNetwork ? 'Kovan ' : ''}ETH`; + return ( + <TableRow key={userAddress} style={{ height: 40 }}> + <TableRowColumn colSpan={2}> + <div data-tip={true} data-for={addressTooltipId}> + {userAddress} + </div> + <ReactTooltip id={addressTooltipId}>{userAddress}</ReactTooltip> + </TableRowColumn> + <TableRowColumn> + <div data-tip={true} data-for={balanceTooltipId}> + {balanceString} + </div> + <ReactTooltip id={balanceTooltipId}>{balanceString}</ReactTooltip> + </TableRowColumn> + </TableRow> + ); + }); + return rows; + } + private _onClose() { + this.setState({ + didConnectFail: false, + }); + const isOpen = false; + this.props.toggleDialogFn(isOpen); + } + private _onAddressSelected(selectedRowIndexes: number[]) { + const selectedRowIndex = selectedRowIndexes[0]; + this.props.blockchain.updateLedgerDerivationIndex(selectedRowIndex); + const selectedAddress = this.state.userAddresses[selectedRowIndex]; + const selectAddressBalance = this.state.addressBalances[selectedRowIndex]; + this.props.dispatcher.updateUserAddress(selectedAddress); + this.props.blockchain.updateWeb3WrapperPrevUserAddress(selectedAddress); + this.props.dispatcher.updateUserEtherBalance(selectAddressBalance); + this.setState({ + stepIndex: LedgerSteps.CONNECT, + }); + const isOpen = false; + this.props.toggleDialogFn(isOpen); + } + private async _onFetchAddressesForDerivationPathAsync(): Promise<boolean> { + const currentlySetPath = this.props.blockchain.getLedgerDerivationPathIfExists(); + let didSucceed; + if (currentlySetPath === this.state.derivationPath) { + didSucceed = true; + return didSucceed; + } + this.props.blockchain.updateLedgerDerivationPathIfExists(this.state.derivationPath); + didSucceed = await this._fetchAddressesAndBalancesAsync(); + if (!didSucceed) { + this.setState({ + derivationErrMsg: 'Failed to connect to Ledger.', + }); + } + return didSucceed; + } + private async _fetchAddressesAndBalancesAsync() { + let userAddresses: string[]; + const addressBalances: BigNumber[] = []; + try { + userAddresses = await this._getUserAddressesAsync(); + for (const address of userAddresses) { + const balance = await this.props.blockchain.getBalanceInEthAsync(address); + addressBalances.push(balance); + } + } catch (err) { + utils.consoleLog(`Ledger error: ${JSON.stringify(err)}`); + this.setState({ + didConnectFail: true, + }); + return false; + } + this.setState({ + userAddresses, + addressBalances, + }); + return true; + } + private _onDerivationPathChanged(e: any, derivationPath: string) { + let derivationErrMsg = ''; + if (!_.startsWith(derivationPath, VALID_ETHEREUM_DERIVATION_PATH_PREFIX)) { + derivationErrMsg = 'Must be valid Ethereum path.'; + } - this.setState({ - derivationPath, - derivationErrMsg, - }); - } - private async _onConnectLedgerClickAsync() { - const didSucceed = await this._fetchAddressesAndBalancesAsync(); - if (didSucceed) { - this.setState({ - stepIndex: LedgerSteps.SELECT_ADDRESS, - }); - } - return didSucceed; - } - private async _getUserAddressesAsync(): Promise<string[]> { - let userAddresses: string[]; - userAddresses = await this.props.blockchain.getUserAccountsAsync(); + this.setState({ + derivationPath, + derivationErrMsg, + }); + } + private async _onConnectLedgerClickAsync() { + const didSucceed = await this._fetchAddressesAndBalancesAsync(); + if (didSucceed) { + this.setState({ + stepIndex: LedgerSteps.SELECT_ADDRESS, + }); + } + return didSucceed; + } + private async _getUserAddressesAsync(): Promise<string[]> { + let userAddresses: string[]; + userAddresses = await this.props.blockchain.getUserAccountsAsync(); - if (_.isEmpty(userAddresses)) { - throw new Error('No addresses retrieved.'); - } - return userAddresses; - } + if (_.isEmpty(userAddresses)) { + throw new Error('No addresses retrieved.'); + } + return userAddresses; + } } diff --git a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx index 3ecc454a0..1c5efc978 100644 --- a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx +++ b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx @@ -4,33 +4,33 @@ import * as React from 'react'; import { colors } from 'ts/utils/colors'; interface PortalDisclaimerDialogProps { - isOpen: boolean; - onToggleDialog: () => void; + isOpen: boolean; + onToggleDialog: () => void; } export function PortalDisclaimerDialog(props: PortalDisclaimerDialogProps) { - return ( - <Dialog - title="0x Portal Disclaimer" - titleStyle={{ fontWeight: 100 }} - actions={[<FlatButton key="portalAgree" label="I Agree" onTouchTap={props.onToggleDialog} />]} - open={props.isOpen} - onRequestClose={props.onToggleDialog} - autoScrollBodyContent={true} - modal={true} - > - <div className="pt2" style={{ color: colors.grey700 }}> - <div> - 0x Portal is a free software-based tool intended to help users to buy and sell ERC20-compatible - blockchain tokens through the 0x protocol on a purely peer-to-peer basis. 0x portal is not a - regulated marketplace, exchange or intermediary of any kind, and therefore, you should only use 0x - portal to exchange tokens that are not securities, commodity interests, or any other form of - regulated instrument. 0x has not attempted to screen or otherwise limit the tokens that you may - enter in 0x Portal. By clicking “I Agree” below, you understand that you are solely responsible for - using 0x Portal and buying and selling tokens using 0x Portal in compliance with all applicable laws - and regulations. - </div> - </div> - </Dialog> - ); + return ( + <Dialog + title="0x Portal Disclaimer" + titleStyle={{ fontWeight: 100 }} + actions={[<FlatButton key="portalAgree" label="I Agree" onTouchTap={props.onToggleDialog} />]} + open={props.isOpen} + onRequestClose={props.onToggleDialog} + autoScrollBodyContent={true} + modal={true} + > + <div className="pt2" style={{ color: colors.grey700 }}> + <div> + 0x Portal is a free software-based tool intended to help users to buy and sell ERC20-compatible + blockchain tokens through the 0x protocol on a purely peer-to-peer basis. 0x portal is not a + regulated marketplace, exchange or intermediary of any kind, and therefore, you should only use 0x + portal to exchange tokens that are not securities, commodity interests, or any other form of + regulated instrument. 0x has not attempted to screen or otherwise limit the tokens that you may + enter in 0x Portal. By clicking “I Agree” below, you understand that you are solely responsible for + using 0x Portal and buying and selling tokens using 0x Portal in compliance with all applicable laws + and regulations. + </div> + </div> + </Dialog> + ); } diff --git a/packages/website/ts/components/dialogs/send_dialog.tsx b/packages/website/ts/components/dialogs/send_dialog.tsx index b3dbce598..b9022cd9b 100644 --- a/packages/website/ts/components/dialogs/send_dialog.tsx +++ b/packages/website/ts/components/dialogs/send_dialog.tsx @@ -8,110 +8,110 @@ import { TokenAmountInput } from 'ts/components/inputs/token_amount_input'; import { Token, TokenState } from 'ts/types'; interface SendDialogProps { - onComplete: (recipient: string, value: BigNumber) => void; - onCancelled: () => void; - isOpen: boolean; - token: Token; - tokenState: TokenState; + onComplete: (recipient: string, value: BigNumber) => void; + onCancelled: () => void; + isOpen: boolean; + token: Token; + tokenState: TokenState; } interface SendDialogState { - value?: BigNumber; - recipient: string; - shouldShowIncompleteErrs: boolean; - isAmountValid: boolean; + value?: BigNumber; + recipient: string; + shouldShowIncompleteErrs: boolean; + isAmountValid: boolean; } export class SendDialog extends React.Component<SendDialogProps, SendDialogState> { - constructor() { - super(); - this.state = { - recipient: '', - shouldShowIncompleteErrs: false, - isAmountValid: false, - }; - } - public render() { - const transferDialogActions = [ - <FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, - <FlatButton - key="sendTransfer" - disabled={this._hasErrors()} - label="Send" - primary={true} - onTouchTap={this._onSendClick.bind(this)} - />, - ]; - return ( - <Dialog - title="I want to send" - titleStyle={{ fontWeight: 100 }} - actions={transferDialogActions} - open={this.props.isOpen} - > - {this._renderSendDialogBody()} - </Dialog> - ); - } - private _renderSendDialogBody() { - return ( - <div className="mx-auto" style={{ maxWidth: 300 }}> - <div style={{ height: 80 }}> - <AddressInput - initialAddress={this.state.recipient} - updateAddress={this._onRecipientChange.bind(this)} - isRequired={true} - label={'Recipient address'} - hintText={'Address'} - /> - </div> - <TokenAmountInput - 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} - /> - </div> - ); - } - private _onRecipientChange(recipient?: string) { - this.setState({ - shouldShowIncompleteErrs: false, - recipient, - }); - } - private _onValueChange(isValid: boolean, amount?: BigNumber) { - this.setState({ - isAmountValid: isValid, - value: amount, - }); - } - private _onSendClick() { - if (this._hasErrors()) { - this.setState({ - shouldShowIncompleteErrs: true, - }); - } else { - const value = this.state.value; - this.setState({ - recipient: undefined, - value: undefined, - }); - this.props.onComplete(this.state.recipient, value); - } - } - private _onCancel() { - this.setState({ - value: undefined, - }); - this.props.onCancelled(); - } - private _hasErrors() { - return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid; - } + constructor() { + super(); + this.state = { + recipient: '', + shouldShowIncompleteErrs: false, + isAmountValid: false, + }; + } + public render() { + const transferDialogActions = [ + <FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, + <FlatButton + key="sendTransfer" + disabled={this._hasErrors()} + label="Send" + primary={true} + onTouchTap={this._onSendClick.bind(this)} + />, + ]; + return ( + <Dialog + title="I want to send" + titleStyle={{ fontWeight: 100 }} + actions={transferDialogActions} + open={this.props.isOpen} + > + {this._renderSendDialogBody()} + </Dialog> + ); + } + private _renderSendDialogBody() { + return ( + <div className="mx-auto" style={{ maxWidth: 300 }}> + <div style={{ height: 80 }}> + <AddressInput + initialAddress={this.state.recipient} + updateAddress={this._onRecipientChange.bind(this)} + isRequired={true} + label={'Recipient address'} + hintText={'Address'} + /> + </div> + <TokenAmountInput + 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} + /> + </div> + ); + } + private _onRecipientChange(recipient?: string) { + this.setState({ + shouldShowIncompleteErrs: false, + recipient, + }); + } + private _onValueChange(isValid: boolean, amount?: BigNumber) { + this.setState({ + isAmountValid: isValid, + value: amount, + }); + } + private _onSendClick() { + if (this._hasErrors()) { + this.setState({ + shouldShowIncompleteErrs: true, + }); + } else { + const value = this.state.value; + this.setState({ + recipient: undefined, + value: undefined, + }); + this.props.onComplete(this.state.recipient, value); + } + } + private _onCancel() { + this.setState({ + value: undefined, + }); + this.props.onCancelled(); + } + private _hasErrors() { + return _.isUndefined(this.state.recipient) || _.isUndefined(this.state.value) || !this.state.isAmountValid; + } } 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..b1804e95c 100644 --- a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx +++ b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx @@ -9,94 +9,94 @@ import { Dispatcher } from 'ts/redux/dispatcher'; import { Token, TokenByAddress } from 'ts/types'; interface TrackTokenConfirmationDialogProps { - tokens: Token[]; - tokenByAddress: TokenByAddress; - isOpen: boolean; - onToggleDialog: (didConfirmTokenTracking: boolean) => void; - dispatcher: Dispatcher; - networkId: number; - blockchain: Blockchain; - userAddress: string; + tokens: Token[]; + tokenByAddress: TokenByAddress; + isOpen: boolean; + onToggleDialog: (didConfirmTokenTracking: boolean) => void; + dispatcher: Dispatcher; + networkId: number; + blockchain: Blockchain; + userAddress: string; } interface TrackTokenConfirmationDialogState { - isAddingTokenToTracked: boolean; + isAddingTokenToTracked: boolean; } export class TrackTokenConfirmationDialog extends React.Component< - TrackTokenConfirmationDialogProps, - TrackTokenConfirmationDialogState + TrackTokenConfirmationDialogProps, + TrackTokenConfirmationDialogState > { - constructor(props: TrackTokenConfirmationDialogProps) { - super(props); - this.state = { - isAddingTokenToTracked: false, - }; - } - public render() { - const tokens = this.props.tokens; - return ( - <Dialog - title="Tracking confirmation" - titleStyle={{ fontWeight: 100 }} - actions={[ - <FlatButton - key="trackNo" - label="No" - onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)} - />, - <FlatButton - key="trackYes" - label="Yes" - onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)} - />, - ]} - open={this.props.isOpen} - onRequestClose={this.props.onToggleDialog.bind(this, false)} - autoScrollBodyContent={true} - > - <div className="pt2"> - <TrackTokenConfirmation - tokens={tokens} - networkId={this.props.networkId} - tokenByAddress={this.props.tokenByAddress} - isAddingTokenToTracked={this.state.isAddingTokenToTracked} - /> - </div> - </Dialog> - ); - } - private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) { - if (!didUserAcceptTracking) { - this.props.onToggleDialog(didUserAcceptTracking); - return; - } - this.setState({ - isAddingTokenToTracked: true, - }); - for (const token of this.props.tokens) { - const newTokenEntry = { - ...token, - }; + constructor(props: TrackTokenConfirmationDialogProps) { + super(props); + this.state = { + isAddingTokenToTracked: false, + }; + } + public render() { + const tokens = this.props.tokens; + return ( + <Dialog + title="Tracking confirmation" + titleStyle={{ fontWeight: 100 }} + actions={[ + <FlatButton + key="trackNo" + label="No" + onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)} + />, + <FlatButton + key="trackYes" + label="Yes" + onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)} + />, + ]} + open={this.props.isOpen} + onRequestClose={this.props.onToggleDialog.bind(this, false)} + autoScrollBodyContent={true} + > + <div className="pt2"> + <TrackTokenConfirmation + tokens={tokens} + networkId={this.props.networkId} + tokenByAddress={this.props.tokenByAddress} + isAddingTokenToTracked={this.state.isAddingTokenToTracked} + /> + </div> + </Dialog> + ); + } + private async _onTrackConfirmationRespondedAsync(didUserAcceptTracking: boolean) { + if (!didUserAcceptTracking) { + this.props.onToggleDialog(didUserAcceptTracking); + return; + } + this.setState({ + isAddingTokenToTracked: true, + }); + for (const token of this.props.tokens) { + const newTokenEntry = { + ...token, + }; - newTokenEntry.isTracked = true; - trackedTokenStorage.addTrackedTokenToUser(this.props.userAddress, this.props.networkId, newTokenEntry); - this.props.dispatcher.updateTokenByAddress([newTokenEntry]); + 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, - }, - }); - } + const [balance, allowance] = await this.props.blockchain.getCurrentUserTokenBalanceAndAllowanceAsync( + token.address, + ); + this.props.dispatcher.updateTokenStateByAddress({ + [token.address]: { + balance, + allowance, + }, + }); + } - this.setState({ - isAddingTokenToTracked: false, - }); - this.props.onToggleDialog(didUserAcceptTracking); - } + this.setState({ + isAddingTokenToTracked: false, + }); + this.props.onToggleDialog(didUserAcceptTracking); + } } diff --git a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx index 098e3e26d..2ea51d07b 100644 --- a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx +++ b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx @@ -5,42 +5,42 @@ import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; interface U2fNotSupportedDialogProps { - isOpen: boolean; - onToggleDialog: () => void; + isOpen: boolean; + onToggleDialog: () => void; } export function U2fNotSupportedDialog(props: U2fNotSupportedDialogProps) { - return ( - <Dialog - title="U2F Not Supported" - titleStyle={{ fontWeight: 100 }} - actions={[<FlatButton key="u2fNo" label="Ok" onTouchTap={props.onToggleDialog.bind(this)} />]} - open={props.isOpen} - onRequestClose={props.onToggleDialog.bind(this)} - autoScrollBodyContent={true} - > - <div className="pt2" style={{ color: colors.grey700 }}> - <div> - It looks like your browser does not support U2F connections required for us to communicate with your - hardware wallet. Please use a browser that supports U2F connections and try again. - </div> - <div> - <ul> - <li className="pb1">Chrome version 38 or later</li> - <li className="pb1">Opera version 40 of later</li> - <li> - Firefox with{' '} - <a - href={constants.URL_FIREFOX_U2F_ADDON} - target="_blank" - style={{ textDecoration: 'underline' }} - > - this extension - </a>. - </li> - </ul> - </div> - </div> - </Dialog> - ); + return ( + <Dialog + title="U2F Not Supported" + titleStyle={{ fontWeight: 100 }} + actions={[<FlatButton key="u2fNo" label="Ok" onTouchTap={props.onToggleDialog.bind(this)} />]} + open={props.isOpen} + onRequestClose={props.onToggleDialog.bind(this)} + autoScrollBodyContent={true} + > + <div className="pt2" style={{ color: colors.grey700 }}> + <div> + It looks like your browser does not support U2F connections required for us to communicate with your + hardware wallet. Please use a browser that supports U2F connections and try again. + </div> + <div> + <ul> + <li className="pb1">Chrome version 38 or later</li> + <li className="pb1">Opera version 40 of later</li> + <li> + Firefox with{' '} + <a + href={constants.URL_FIREFOX_U2F_ADDON} + target="_blank" + style={{ textDecoration: 'underline' }} + > + this extension + </a>. + </li> + </ul> + </div> + </div> + </Dialog> + ); } diff --git a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx index 9e91ff12d..98436eb50 100644 --- a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx +++ b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx @@ -4,30 +4,30 @@ import { colors } from 'material-ui/styles'; import * as React from 'react'; interface WrappedEthSectionNoticeDialogProps { - isOpen: boolean; - onToggleDialog: () => void; + isOpen: boolean; + onToggleDialog: () => void; } export function WrappedEthSectionNoticeDialog(props: WrappedEthSectionNoticeDialogProps) { - return ( - <Dialog - title="Dedicated Wrapped Ether Section" - titleStyle={{ fontWeight: 100 }} - actions={[ - <FlatButton key="acknowledgeWrapEthSection" label="Sounds good" onTouchTap={props.onToggleDialog} />, - ]} - open={props.isOpen} - onRequestClose={props.onToggleDialog} - autoScrollBodyContent={true} - modal={true} - > - <div className="pt2" style={{ color: colors.grey700 }}> - <div> - We have recently updated the Wrapped Ether token (WETH) used by 0x Portal. Don't worry, unwrapping - Ether tied to the old Wrapped Ether token can be done at any time by clicking on the "Wrap ETH" - section in the menu to the left. - </div> - </div> - </Dialog> - ); + return ( + <Dialog + title="Dedicated Wrapped Ether Section" + titleStyle={{ fontWeight: 100 }} + actions={[ + <FlatButton key="acknowledgeWrapEthSection" label="Sounds good" onTouchTap={props.onToggleDialog} />, + ]} + open={props.isOpen} + onRequestClose={props.onToggleDialog} + autoScrollBodyContent={true} + modal={true} + > + <div className="pt2" style={{ color: colors.grey700 }}> + <div> + We have recently updated the Wrapped Ether token (WETH) used by 0x Portal. Don't worry, unwrapping + Ether tied to the old Wrapped Ether token can be done at any time by clicking on the "Wrap ETH" + section in the menu to the left. + </div> + </div> + </Dialog> + ); } |