diff options
Diffstat (limited to 'packages/website/ts/components/wallet/wallet.tsx')
-rw-r--r-- | packages/website/ts/components/wallet/wallet.tsx | 153 |
1 files changed, 55 insertions, 98 deletions
diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index afcf3862f..d0354580d 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -9,7 +9,7 @@ import { Web3Wrapper } from '@0xproject/web3-wrapper'; import * as _ from 'lodash'; import FlatButton from 'material-ui/FlatButton'; import FloatingActionButton from 'material-ui/FloatingActionButton'; -import { List, ListItem } from 'material-ui/List'; +import { ListItem } from 'material-ui/List'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; import ContentAdd from 'material-ui/svg-icons/content/add'; import ContentRemove from 'material-ui/svg-icons/content/remove'; @@ -23,6 +23,7 @@ import firstBy = require('thenby'); import { Blockchain } from 'ts/blockchain'; import { AllowanceToggle } from 'ts/components/inputs/allowance_toggle'; +import { IconButton } from 'ts/components/ui/icon_button'; import { Identicon } from 'ts/components/ui/identicon'; import { TokenIcon } from 'ts/components/ui/token_icon'; import { WalletDisconnectedItem } from 'ts/components/wallet/wallet_disconnected_item'; @@ -91,12 +92,6 @@ const styles: Styles = { boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`, overflow: 'hidden', }, - list: { - padding: 0, - }, - tokenItemInnerDiv: { - paddingLeft: 60, - }, headerItemInnerDiv: { paddingLeft: 65, }, @@ -114,23 +109,19 @@ const styles: Styles = { tokenItem: { backgroundColor: colors.walletDefaultItemBackground, }, - wrappedEtherOpenButtonLabel: { - fontSize: 10, - }, amountLabel: { fontWeight: 'bold', color: colors.black, }, + valueLabel: { + color: colors.grey, + fontSize: 14, + }, paddedItem: { paddingTop: 8, paddingBottom: 8, }, - accessoryItemsContainer: { - width: 150, - right: 8, - }, bodyInnerDiv: { - padding: 0, // TODO: make this completely responsive maxHeight: 475, overflow: 'auto', @@ -154,6 +145,7 @@ const FOOTER_ITEM_KEY = 'FOOTER'; const DISCONNECTED_ITEM_KEY = 'DISCONNECTED'; const ETHER_ITEM_KEY = 'ETHER'; const USD_DECIMAL_PLACES = 2; +const NO_ALLOWANCE_TOGGLE_SPACE_WIDTH = 56; export class Wallet extends React.Component<WalletProps, WalletState> { private _isUnmounted: boolean; @@ -204,16 +196,13 @@ export class Wallet extends React.Component<WalletProps, WalletState> { } public render(): React.ReactNode { const isReadyToRender = this.props.blockchainIsLoaded && this.props.blockchainErr === BlockchainErrs.NoError; - return <div style={styles.root}>{isReadyToRender && this._renderRows()}</div>; - } - private _renderRows(): React.ReactNode { const isAddressAvailable = !_.isEmpty(this.props.userAddress); return ( - <List style={styles.list}> - {isAddressAvailable + <div className="flex flex-column" style={styles.root}> + {isReadyToRender && isAddressAvailable ? _.concat(this._renderConnectedHeaderRows(), this._renderBody(), this._renderFooterRows()) : _.concat(this._renderDisconnectedHeaderRows(), this._renderDisconnectedRows())} - </List> + </div> ); } private _renderDisconnectedHeaderRows(): React.ReactElement<{}> { @@ -259,15 +248,15 @@ export class Wallet extends React.Component<WalletProps, WalletState> { overflow: this.state.isHoveringSidebar ? 'auto' : 'hidden', }; return ( - <ListItem + <div + style={bodyStyle} key={BODY_ITEM_KEY} - innerDivStyle={bodyStyle} onMouseEnter={this._onSidebarHover.bind(this)} onMouseLeave={this._onSidebarHoverOff.bind(this)} > {this._renderEthRows()} {this._renderTokenRows()} - </ListItem> + </div> ); } private _onSidebarHover(event: React.FormEvent<HTMLInputElement>): void { @@ -329,6 +318,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { ); } private _renderEthRows(): React.ReactNode { + const icon = <img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={ETHER_ICON_PATH} />; const primaryText = this._renderAmount( this.props.userEtherBalanceInWei, constants.DECIMAL_PLACES_ETH, @@ -350,33 +340,8 @@ export class Wallet extends React.Component<WalletProps, WalletState> { const style = isInWrappedEtherState ? { ...walletItemStyles.focusedItem, ...styles.paddedItem } : { ...styles.tokenItem, ...styles.borderedItem, ...styles.paddedItem }; - return ( - <div key={ETHER_ITEM_KEY}> - <ListItem - primaryText={primaryText} - secondaryText={secondaryText} - leftIcon={<img style={{ width: ICON_DIMENSION, height: ICON_DIMENSION }} src={ETHER_ICON_PATH} />} - rightAvatar={this._renderAccessoryItems(accessoryItemConfig)} - disableTouchRipple={true} - style={style} - innerDivStyle={styles.tokenItemInnerDiv} - /> - {isInWrappedEtherState && ( - <WrapEtherItem - userAddress={this.props.userAddress} - networkId={this.props.networkId} - blockchain={this.props.blockchain} - dispatcher={this.props.dispatcher} - userEtherBalanceInWei={this.props.userEtherBalanceInWei} - direction={accessoryItemConfig.wrappedEtherDirection} - etherToken={etherToken} - lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch} - onConversionSuccessful={this._closeWrappedEtherActionRow.bind(this)} - refetchEthTokenStateAsync={this._refetchTokenStateAsync.bind(this, etherToken.address)} - /> - )} - </div> - ); + const key = ETHER_ITEM_KEY; + return this._renderBalanceRow(key, icon, primaryText, secondaryText, accessoryItemConfig); } private _renderTokenRows(): React.ReactNode { const trackedTokens = this.props.trackedTokens; @@ -394,6 +359,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { this.props.networkId, EtherscanLinkSuffixes.Address, ); + const icon = <TokenIcon token={token} diameter={ICON_DIMENSION} link={tokenLink} />; const primaryText = this._renderAmount(tokenState.balance, token.decimals, token.symbol); const secondaryText = this._renderValue(tokenState.balance, token.decimals, tokenState.price); const wrappedEtherDirection = token.symbol === ETHER_TOKEN_SYMBOL ? Side.Receive : undefined; @@ -404,26 +370,34 @@ export class Wallet extends React.Component<WalletProps, WalletState> { tokenState, }, }; - // if this is the last item in the list, do not render the border, it is rendered by the footer - const borderedStyle = index !== this.props.trackedTokens.length - 1 ? styles.borderedItem : {}; + const key = token.address; + return this._renderBalanceRow(key, icon, primaryText, secondaryText, accessoryItemConfig); + } + private _renderBalanceRow( + key: string, + icon: React.ReactNode, + primaryText: React.ReactNode, + secondaryText: React.ReactNode, + accessoryItemConfig: AccessoryItemConfig, + ): React.ReactNode { const shouldShowWrapEtherItem = !_.isUndefined(this.state.wrappedEtherDirection) && this.state.wrappedEtherDirection === accessoryItemConfig.wrappedEtherDirection; const style = shouldShowWrapEtherItem ? { ...walletItemStyles.focusedItem, ...styles.paddedItem } - : { ...styles.tokenItem, ...borderedStyle, ...styles.paddedItem }; + : { ...styles.tokenItem, ...styles.borderedItem, ...styles.paddedItem }; const etherToken = this._getEthToken(); return ( - <div key={token.address}> - <ListItem - primaryText={primaryText} - secondaryText={secondaryText} - leftIcon={this._renderTokenIcon(token, tokenLink)} - rightAvatar={this._renderAccessoryItems(accessoryItemConfig)} - disableTouchRipple={true} - style={style} - innerDivStyle={styles.tokenItemInnerDiv} - /> + <div key={key} className="flex flex-column"> + <div className="flex items-center" style={style}> + <div className="px2">{icon}</div> + <div className="flex-none pr2 pt2 pb2"> + {primaryText} + {secondaryText} + </div> + <div className="flex-auto" /> + <div>{this._renderAccessoryItems(accessoryItemConfig)}</div> + </div> {shouldShowWrapEtherItem && ( <WrapEtherItem userAddress={this.props.userAddress} @@ -444,16 +418,19 @@ export class Wallet extends React.Component<WalletProps, WalletState> { private _renderAccessoryItems(config: AccessoryItemConfig): React.ReactElement<{}> { const shouldShowWrappedEtherAction = !_.isUndefined(config.wrappedEtherDirection); const shouldShowToggle = !_.isUndefined(config.allowanceToggleConfig); + // if we don't have a toggle, we still want some space to the right of the "wrap" button so that it aligns with + // the "unwrap" button in the row below + const toggle = shouldShowToggle ? ( + this._renderAllowanceToggle(config.allowanceToggleConfig) + ) : ( + <div style={{ width: NO_ALLOWANCE_TOGGLE_SPACE_WIDTH }} /> + ); return ( - <div style={styles.accessoryItemsContainer}> - <div className="flex"> - <div className="flex-auto"> - {shouldShowWrappedEtherAction && this._renderWrappedEtherButton(config.wrappedEtherDirection)} - </div> - <div className="flex-last py1"> - {shouldShowToggle && this._renderAllowanceToggle(config.allowanceToggleConfig)} - </div> + <div className="flex items-center"> + <div className="flex-auto"> + {shouldShowWrappedEtherAction && this._renderWrappedEtherButton(config.wrappedEtherDirection)} </div> + <div className="flex-last pl2">{toggle}</div> </div> ); } @@ -486,37 +463,24 @@ export class Wallet extends React.Component<WalletProps, WalletState> { const value = unitAmount.mul(price); const formattedAmount = value.toFixed(USD_DECIMAL_PLACES); const result = `$${formattedAmount}`; - return result; - } - private _renderTokenIcon(token: Token, tokenLink?: string): React.ReactElement<{}> { - const tooltipId = `tooltip-${token.address}`; - const tokenIcon = <TokenIcon token={token} diameter={ICON_DIMENSION} />; - if (_.isUndefined(tokenLink)) { - return tokenIcon; - } else { - return ( - <a href={tokenLink} target="_blank" style={{ textDecoration: 'none' }}> - {tokenIcon} - </a> - ); - } + return <div style={styles.valueLabel}>{result}</div>; } private _renderWrappedEtherButton(wrappedEtherDirection: Side): React.ReactNode { const isWrappedEtherDirectionOpen = this.state.wrappedEtherDirection === wrappedEtherDirection; let buttonLabel; - let buttonIcon; + let buttonIconName; if (isWrappedEtherDirectionOpen) { buttonLabel = 'cancel'; - buttonIcon = <Close />; + buttonIconName = 'zmdi-close'; } else { switch (wrappedEtherDirection) { case Side.Deposit: buttonLabel = 'wrap'; - buttonIcon = <NavigationArrowDownward />; + buttonIconName = 'zmdi-long-arrow-down'; break; case Side.Receive: buttonLabel = 'unwrap'; - buttonIcon = <NavigationArrowUpward />; + buttonIconName = 'zmdi-long-arrow-up'; break; default: throw utils.spawnSwitchErr('wrappedEtherDirection', wrappedEtherDirection); @@ -526,14 +490,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { ? this._closeWrappedEtherActionRow.bind(this) : this._openWrappedEtherActionRow.bind(this, wrappedEtherDirection); return ( - <FlatButton - label={buttonLabel} - labelPosition="after" - primary={true} - icon={buttonIcon} - labelStyle={styles.wrappedEtherOpenButtonLabel} - onClick={onClick} - /> + <IconButton iconName={buttonIconName} labelText={buttonLabel} onClick={onClick} color={colors.mediumBlue} /> ); } private _getInitialTrackedTokenStateByAddress(tokenAddresses: string[]): TokenStateByAddress { |