Rewrite balance rows using flex box

This commit is contained in:
Brandon Millman
2018-05-21 16:35:49 -07:00
parent d460c0e8b9
commit 26370da13d
3 changed files with 129 additions and 122 deletions

View File

@@ -9,7 +9,7 @@ import { BigNumber } from '@0xproject/utils';
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,7 @@ 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>
);
return this._renderBalanceRow(icon, primaryText, secondaryText, accessoryItemConfig);
}
private _renderTokenRows(): React.ReactNode {
const trackedTokens = this.props.trackedTokens;
@@ -394,6 +358,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,56 +369,48 @@ 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 : {};
return this._renderBalanceRow(icon, primaryText, secondaryText, accessoryItemConfig);
}
private _renderBalanceRow(
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 };
const etherToken = this._getEthToken();
: { ...styles.tokenItem, ...styles.borderedItem, ...styles.paddedItem };
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}
/>
{shouldShowWrapEtherItem && (
<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 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>
);
}
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 +443,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 +470,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 {