diff options
-rw-r--r-- | packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx | 130 | ||||
-rw-r--r-- | packages/website/ts/components/eth_weth_conversion_button.tsx | 38 |
2 files changed, 109 insertions, 59 deletions
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 aba5b9faf..4904ee9e2 100644 --- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx +++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx @@ -1,14 +1,15 @@ import BigNumber from 'bignumber.js'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; -import RadioButton from 'material-ui/RadioButton'; -import RadioButtonGroup from 'material-ui/RadioButton/RadioButtonGroup'; import * as React from 'react'; 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'; +const DARK_BLUE = '#4D5481'; + interface EthWethConversionDialogProps { + direction: Side; onComplete: (direction: Side, value: BigNumber) => void; onCancelled: () => void; isOpen: boolean; @@ -19,7 +20,6 @@ interface EthWethConversionDialogProps { interface EthWethConversionDialogState { value?: BigNumber; - direction: Side; shouldShowIncompleteErrs: boolean; hasErrors: boolean; } @@ -29,7 +29,6 @@ export class EthWethConversionDialog extends constructor() { super(); this.state = { - direction: Side.deposit, shouldShowIncompleteErrs: false, hasErrors: true, }; @@ -48,11 +47,13 @@ export class EthWethConversionDialog extends onTouchTap={this.onConvertClick.bind(this)} />, ]; + const title = this.props.direction === Side.deposit ? 'Wrap ETH' : 'Unwrap WETH'; return ( <Dialog - title="I want to convert" + title={title} titleStyle={{fontWeight: 100}} actions={convertDialogActions} + contentStyle={{width: 600}} open={this.props.isOpen} > {this.renderConversionDialogBody()} @@ -60,56 +61,81 @@ export class EthWethConversionDialog extends ); } 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 className="mx-auto" style={{maxWidth: 300}}> - <RadioButtonGroup - className="pb1" - defaultSelected={this.state.direction} - name="conversionDirection" - onChange={this.onConversionDirectionChange.bind(this)} - > - <RadioButton - className="pb1" - value={Side.deposit} - label="Ether -> Ether Tokens" - /> - <RadioButton - value={Side.receive} - label="Ether Tokens -> Ether" - /> - </RadioButtonGroup> - {this.state.direction === Side.receive ? - <TokenAmountInput - label="Amount to convert" - 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 - label="Amount to convert" - balance={this.props.etherBalance} - amount={this.state.value} - onChange={this.onValueChange.bind(this)} - shouldCheckBalance={true} - shouldShowIncompleteErrs={this.state.shouldShowIncompleteErrs} - onVisitBalancesPageClick={this.props.onCancelled} - /> - } + <div> + <div className="pb2"> + {explanation} + </div> + <div className="mx-auto" style={{maxWidth: 332}}> + <div className="flex"> + {this.renderCurrency(isWrappedVersion)} + <div style={{paddingTop: 68}}> + <i + style={{fontSize: 28, color: DARK_BLUE}} + className="zmdi zmdi-arrow-right" + /> + </div> + {this.renderCurrency(!isWrappedVersion)} + </div> + <div + className="pt2 mx-auto" + style={{width: 235}} + > + {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}} + > + 1 ETH = 1 WETH + </div> + </div> + </div> </div> ); } - private onConversionDirectionChange(e: any, direction: Side) { - this.setState({ - value: undefined, - shouldShowIncompleteErrs: false, - direction, - hasErrors: true, - }); + 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: DARK_BLUE}} + > + {name} + </div> + <div className="center py2"> + <img src={iconUrl} style={{width: 60}} /> + </div> + <div className="center"> + ({symbol}) + </div> + </div> + ); } private onValueChange(isValid: boolean, amount?: BigNumber) { this.setState({ @@ -127,7 +153,7 @@ export class EthWethConversionDialog extends this.setState({ value: undefined, }); - this.props.onComplete(this.state.direction, value); + this.props.onComplete(this.props.direction, value); } } private onCancel() { diff --git a/packages/website/ts/components/eth_weth_conversion_button.tsx b/packages/website/ts/components/eth_weth_conversion_button.tsx index a83b1543f..bf686d44b 100644 --- a/packages/website/ts/components/eth_weth_conversion_button.tsx +++ b/packages/website/ts/components/eth_weth_conversion_button.tsx @@ -12,12 +12,15 @@ import {errorReporter} from 'ts/utils/error_reporter'; import {utils} from 'ts/utils/utils'; interface EthWethConversionButtonProps { + direction: Side; ethToken: Token; ethTokenState: TokenState; dispatcher: Dispatcher; blockchain: Blockchain; userEtherBalance: BigNumber; - onError: () => void; + isOutdatedWrappedEther: boolean; + onConversionSuccessful?: () => void; + isDisabled?: boolean; } interface EthWethConversionButtonState { @@ -27,6 +30,9 @@ interface EthWethConversionButtonState { export class EthWethConversionButton extends React.Component<EthWethConversionButtonProps, EthWethConversionButtonState> { + public static defaultProps: Partial<EthWethConversionButtonProps> = { + isDisabled: false, + }; public constructor(props: EthWethConversionButtonProps) { super(props); this.state = { @@ -36,16 +42,26 @@ export class EthWethConversionButton extends } public render() { const labelStyle = this.state.isEthConversionHappening ? {fontSize: 10} : {}; + let callToActionLabel; + let inProgressLabel; + if (this.props.direction === Side.deposit) { + callToActionLabel = 'Wrap'; + inProgressLabel = 'Wrapping...'; + } else { + callToActionLabel = 'Unwrap'; + inProgressLabel = 'Unwrapping...'; + } return ( <div> <RaisedButton style={{width: '100%'}} labelStyle={labelStyle} - disabled={this.state.isEthConversionHappening} - label={this.state.isEthConversionHappening ? 'Converting...' : 'Convert'} + disabled={this.props.isDisabled || this.state.isEthConversionHappening} + label={this.state.isEthConversionHappening ? inProgressLabel : callToActionLabel} onClick={this.toggleConversionDialog.bind(this)} /> <EthWethConversionDialog + direction={this.props.direction} isOpen={this.state.isEthConversionDialogVisible} onComplete={this.onConversionAmountSelectedAsync.bind(this)} onCancelled={this.toggleConversionDialog.bind(this)} @@ -73,15 +89,20 @@ export class EthWethConversionButton extends if (direction === Side.deposit) { await this.props.blockchain.convertEthToWrappedEthTokensAsync(value); const ethAmount = ZeroEx.toUnitAmount(value, constants.ETH_DECIMAL_PLACES); - this.props.dispatcher.showFlashMessage(`Successfully converted ${ethAmount.toString()} ETH to WETH`); + this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount.toString()} ETH to WETH`); balance = balance.plus(value); } else { await this.props.blockchain.convertWrappedEthTokensToEthAsync(value); const tokenAmount = ZeroEx.toUnitAmount(value, token.decimals); - this.props.dispatcher.showFlashMessage(`Successfully converted ${tokenAmount.toString()} WETH to ETH`); + this.props.dispatcher.showFlashMessage(`Successfully unwrapped ${tokenAmount.toString()} WETH to ETH`); balance = balance.minus(value); } - this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance); + if (!this.props.isOutdatedWrappedEther) { + this.props.dispatcher.replaceTokenBalanceByAddress(token.address, balance); + } + if (!_.isUndefined(this.props.onConversionSuccessful)) { + this.props.onConversionSuccessful(); + } } catch (err) { const errMsg = '' + err; if (_.includes(errMsg, BlockchainCallErrs.USER_HAS_NO_ASSOCIATED_ADDRESSES)) { @@ -90,7 +111,10 @@ export class EthWethConversionButton extends utils.consoleLog(`Unexpected error encountered: ${err}`); utils.consoleLog(err.stack); await errorReporter.reportAsync(err); - this.props.onError(); + const errorMsg = direction === Side.deposit ? + 'Failed to wrap your ETH. Please try again.' : + 'Failed to unwrap your WETH. Please try again.'; + this.props.dispatcher.showFlashMessage(errorMsg); } } this.setState({ |