diff options
author | Brandon Millman <brandon.millman@gmail.com> | 2018-03-21 11:55:11 +0800 |
---|---|---|
committer | Brandon Millman <brandon.millman@gmail.com> | 2018-03-23 14:13:49 +0800 |
commit | dc3be992a3a1d5f352b65effa5c05f69f8e3272c (patch) | |
tree | e57938fa5655ae6e8251090f5a1f10a779f7c81a /packages/website/ts/components/wallet/wrap_ether_item.tsx | |
parent | bed7d87b7ff64989051e6b2115a1c77e1e72ff55 (diff) | |
download | dexon-sol-tools-dc3be992a3a1d5f352b65effa5c05f69f8e3272c.tar.gz dexon-sol-tools-dc3be992a3a1d5f352b65effa5c05f69f8e3272c.tar.zst dexon-sol-tools-dc3be992a3a1d5f352b65effa5c05f69f8e3272c.zip |
Implement ETH/WETH conversion and allowance toggle styling
Diffstat (limited to 'packages/website/ts/components/wallet/wrap_ether_item.tsx')
-rw-r--r-- | packages/website/ts/components/wallet/wrap_ether_item.tsx | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/packages/website/ts/components/wallet/wrap_ether_item.tsx b/packages/website/ts/components/wallet/wrap_ether_item.tsx new file mode 100644 index 000000000..71ce6894f --- /dev/null +++ b/packages/website/ts/components/wallet/wrap_ether_item.tsx @@ -0,0 +1,185 @@ +import { ZeroEx } from '0x.js'; +import { colors, Styles } from '@0xproject/react-shared'; +import { BigNumber, logUtils } from '@0xproject/utils'; +import * as _ from 'lodash'; +import FlatButton from 'material-ui/FlatButton'; +import { ListItem } from 'material-ui/List'; +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 { Dispatcher } from 'ts/redux/dispatcher'; +import { BlockchainCallErrs, Side, Token } from 'ts/types'; +import { constants } from 'ts/utils/constants'; +import { errorReporter } from 'ts/utils/error_reporter'; +import { utils } from 'ts/utils/utils'; +import { styles as walletItemStyles } from 'ts/utils/wallet_item_styles'; + +export interface WrapEtherItemProps { + userAddress: string; + networkId: number; + blockchain: Blockchain; + dispatcher: Dispatcher; + userEtherBalanceInWei: BigNumber; + direction: Side; + etherToken: Token; + lastForceTokenStateRefetch: number; + onConversionSuccessful?: () => void; + refetchEthTokenStateAsync: () => Promise<void>; +} + +interface WrapEtherItemState { + currentInputAmount?: BigNumber; + currentInputHasErrors: boolean; + isEthConversionHappening: boolean; +} + +const styles: Styles = { + topLabel: { color: colors.black, fontSize: 11 }, + inputContainer: { + backgroundColor: colors.white, + borderBottomRightRadius: 3, + borderBottomLeftRadius: 3, + borderTopRightRadius: 3, + borderTopLeftRadius: 3, + padding: 4, + width: 125, + }, + ethAmountInput: { height: 32 }, + innerDiv: { paddingLeft: 60, paddingTop: 0 }, + wrapEtherConfirmationButtonContainer: { width: 128, top: 16 }, + wrapEtherConfirmationButtonLabel: { + fontSize: 10, + color: colors.white, + }, +}; + +export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEtherItemState> { + constructor(props: WrapEtherItemProps) { + super(props); + this.state = { + currentInputAmount: undefined, + currentInputHasErrors: false, + isEthConversionHappening: false, + }; + } + public render() { + const etherBalanceInEth = ZeroEx.toUnitAmount(this.props.userEtherBalanceInWei, constants.DECIMAL_PLACES_ETH); + const isWrappingEth = this.props.direction === Side.Deposit; + const topLabelText = isWrappingEth ? 'Convert ETH into WETH 1:1' : 'Convert WETH into ETH 1:1'; + return ( + <ListItem + primaryText={ + <div> + <div style={styles.topLabel}>{topLabelText}</div> + <div style={styles.inputContainer}> + {isWrappingEth ? ( + <EthAmountInput + balance={etherBalanceInEth} + amount={this.state.currentInputAmount} + hintText={'0.00'} + onChange={this._onValueChange.bind(this)} + shouldCheckBalance={true} + shouldShowIncompleteErrs={false} + shouldShowErrs={false} + shouldShowUnderline={false} + style={styles.ethAmountInput} + /> + ) : ( + <TokenAmountInput + lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} + blockchain={this.props.blockchain} + userAddress={this.props.userAddress} + networkId={this.props.networkId} + token={this.props.etherToken} + shouldShowIncompleteErrs={false} + shouldCheckBalance={true} + shouldCheckAllowance={false} + onChange={this._onValueChange.bind(this)} + amount={this.state.currentInputAmount} + hintText={'0.00'} + onVisitBalancesPageClick={_.noop} + shouldShowErrs={false} + shouldShowUnderline={false} + style={styles.ethAmountInput} + /> + )} + </div> + </div> + } + secondaryTextLines={2} + disableTouchRipple={true} + style={walletItemStyles.focusedItem} + innerDivStyle={styles.innerDiv} + leftIcon={this.state.isEthConversionHappening && this._renderIsEthConversionHappeningSpinner()} + rightAvatar={this._renderWrapEtherConfirmationButton()} + /> + ); + } + private _onValueChange(isValid: boolean, amount?: BigNumber) { + this.setState({ + currentInputAmount: amount, + currentInputHasErrors: !isValid, + }); + } + private _renderIsEthConversionHappeningSpinner() { + return ( + <div className="pl1" style={{ paddingTop: 10 }}> + <i className="zmdi zmdi-spinner zmdi-hc-spin" /> + </div> + ); + } + private _renderWrapEtherConfirmationButton() { + const isWrappingEth = this.props.direction === Side.Deposit; + const labelText = isWrappingEth ? 'wrap' : 'unwrap'; + return ( + <div style={styles.wrapEtherConfirmationButtonContainer}> + <FlatButton + backgroundColor={colors.wrapEtherConfirmationButton} + label={labelText} + labelStyle={styles.wrapEtherConfirmationButtonLabel} + onClick={this._wrapEtherConfirmationAction.bind(this)} + disabled={this.state.isEthConversionHappening} + /> + </div> + ); + } + private async _wrapEtherConfirmationAction() { + this.setState({ + isEthConversionHappening: true, + }); + try { + const etherToken = this.props.etherToken; + const amountToConvert = this.state.currentInputAmount; + if (this.props.direction === Side.Deposit) { + await this.props.blockchain.convertEthToWrappedEthTokensAsync(etherToken.address, amountToConvert); + const ethAmount = ZeroEx.toUnitAmount(amountToConvert, constants.DECIMAL_PLACES_ETH); + this.props.dispatcher.showFlashMessage(`Successfully wrapped ${ethAmount.toString()} ETH to WETH`); + } else { + await this.props.blockchain.convertWrappedEthTokensToEthAsync(etherToken.address, amountToConvert); + const tokenAmount = ZeroEx.toUnitAmount(amountToConvert, etherToken.decimals); + this.props.dispatcher.showFlashMessage(`Successfully unwrapped ${tokenAmount.toString()} WETH to ETH`); + } + await this.props.refetchEthTokenStateAsync(); + this.props.onConversionSuccessful(); + } catch (err) { + const errMsg = `${err}`; + if (_.includes(errMsg, BlockchainCallErrs.UserHasNoAssociatedAddresses)) { + this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true); + } else if (!utils.didUserDenyWeb3Request(errMsg)) { + logUtils.log(`Unexpected error encountered: ${err}`); + logUtils.log(err.stack); + const errorMsg = + this.props.direction === Side.Deposit + ? 'Failed to wrap your ETH. Please try again.' + : 'Failed to unwrap your WETH. Please try again.'; + this.props.dispatcher.showFlashMessage(errorMsg); + await errorReporter.reportAsync(err); + } + } + this.setState({ + isEthConversionHappening: false, + }); + } +} |