Implement loading body rows

This commit is contained in:
Brandon Millman 2018-06-26 15:01:20 -07:00
parent 6a39a69afe
commit f76c9bc226
4 changed files with 80 additions and 28 deletions

View File

@ -48,10 +48,10 @@ const styles: Styles = {
width: 25, width: 25,
}, },
offTrackStyle: { offTrackStyle: {
backgroundColor: colors.allowanceToggleOffTrack, backgroundColor: colors.grey300,
}, },
onTrackStyle: { onTrackStyle: {
backgroundColor: colors.allowanceToggleOnTrack, backgroundColor: colors.mediumBlue,
}, },
}; };

View File

@ -15,6 +15,7 @@ export interface ContainerProps {
borderRadius?: StringOrNum; borderRadius?: StringOrNum;
maxWidth?: StringOrNum; maxWidth?: StringOrNum;
width?: StringOrNum; width?: StringOrNum;
height?: StringOrNum;
minHeight?: StringOrNum; minHeight?: StringOrNum;
isHidden?: boolean; isHidden?: boolean;
className?: string; className?: string;

View File

@ -19,10 +19,12 @@ import { Link } from 'react-router-dom';
import firstBy = require('thenby'); import firstBy = require('thenby');
import { Blockchain } from 'ts/blockchain'; import { Blockchain } from 'ts/blockchain';
import { Circle } from 'ts/components/ui/circle';
import { Container } from 'ts/components/ui/container'; import { Container } from 'ts/components/ui/container';
import { IconButton } from 'ts/components/ui/icon_button'; import { IconButton } from 'ts/components/ui/icon_button';
import { Identicon } from 'ts/components/ui/identicon'; import { Identicon } from 'ts/components/ui/identicon';
import { Island } from 'ts/components/ui/island'; import { Island } from 'ts/components/ui/island';
import { Text } from 'ts/components/ui/text';
import { TokenIcon } from 'ts/components/ui/token_icon'; import { TokenIcon } from 'ts/components/ui/token_icon';
import { WalletDisconnectedItem } from 'ts/components/wallet/wallet_disconnected_item'; import { WalletDisconnectedItem } from 'ts/components/wallet/wallet_disconnected_item';
import { WrapEtherItem } from 'ts/components/wallet/wrap_ether_item'; import { WrapEtherItem } from 'ts/components/wallet/wrap_ether_item';
@ -123,9 +125,6 @@ const styles: Styles = {
color: colors.mediumBlue, color: colors.mediumBlue,
fontWeight: 'bold', fontWeight: 'bold',
}, },
loadingBody: {
height: 381,
},
}; };
const ETHER_ICON_PATH = '/images/ether.png'; const ETHER_ICON_PATH = '/images/ether.png';
@ -138,6 +137,8 @@ const ETHER_ITEM_KEY = 'ETHER';
const USD_DECIMAL_PLACES = 2; const USD_DECIMAL_PLACES = 2;
const NO_ALLOWANCE_TOGGLE_SPACE_WIDTH = 56; const NO_ALLOWANCE_TOGGLE_SPACE_WIDTH = 56;
const ACCOUNT_PATH = `${WebsitePaths.Portal}/account`; const ACCOUNT_PATH = `${WebsitePaths.Portal}/account`;
const PLACEHOLDER_COLOR = colors.grey300;
const LOADING_ROWS_COUNT = 5;
const ActionButton = styled(FloatingActionButton)` const ActionButton = styled(FloatingActionButton)`
button { button {
@ -178,31 +179,49 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
</Island> </Island>
); );
} }
private _renderLoadedRows(): React.ReactNode {
const isAddressAvailable = !_.isEmpty(this.props.userAddress);
return isAddressAvailable
? _.concat(this._renderConnectedHeaderRows(), this._renderBody(), this._renderFooterRows())
: _.concat(this._renderDisconnectedHeaderRows(), this._renderDisconnectedRows());
}
private _renderLoadingRows(): React.ReactNode { private _renderLoadingRows(): React.ReactNode {
return _.concat(this._renderDisconnectedHeaderRows(), this._renderLoadingBodyRows()); return _.concat(this._renderLoadingHeaderRows(), this._renderLoadingBodyRows());
}
private _renderLoadingHeaderRows(): React.ReactElement<{}> {
return this._renderPlainHeaderRow('Loading...');
} }
private _renderLoadingBodyRows(): React.ReactElement<{}> { private _renderLoadingBodyRows(): React.ReactElement<{}> {
const bodyStyle = this._getBodyStyle();
const loadingRowsRange = _.range(LOADING_ROWS_COUNT + 1);
return ( return (
<div key={BODY_ITEM_KEY} className="flex items-center" style={styles.loadingBody}> <div key={BODY_ITEM_KEY} className="flex flex-column" style={bodyStyle}>
<div className="mx-auto"> {_.map(loadingRowsRange, index => {
<CircularProgress size={40} thickness={5} /> return <NullTokenRow />;
</div> })}
</div> </div>
); );
} }
private _renderLoadedRows(): React.ReactNode {
const isAddressAvailable = !_.isEmpty(this.props.userAddress);
return isAddressAvailable
? _.concat(this._renderConnectedHeaderRows(), this._renderBody())
: _.concat(this._renderDisconnectedHeaderRows(), this._renderLoadingBodyRows());
}
private _renderDisconnectedHeaderRows(): React.ReactElement<{}> { private _renderDisconnectedHeaderRows(): React.ReactElement<{}> {
const primaryText = 'wallet'; const isExternallyInjectedProvider = utils.isExternallyInjected(
this.props.providerType,
this.props.injectedProviderName,
);
const text = isExternallyInjectedProvider ? 'Please unlock MetaMask...' : 'Please connect a wallet...';
return this._renderPlainHeaderRow(text);
}
private _renderPlainHeaderRow(text: string): React.ReactElement<{}> {
return ( return (
<StandardIconRow <StandardIconRow
key={HEADER_ITEM_KEY} key={HEADER_ITEM_KEY}
icon={<ActionAccountBalanceWallet color={colors.mediumBlue} />} icon={<ActionAccountBalanceWallet color={colors.grey} />}
main={primaryText.toUpperCase()} main={
<Text fontSize="16px" fontColor={colors.grey}>
{text}
</Text>
// https://github.com/palantir/tslint-react/issues/140
// tslint:disable-next-line:jsx-curly-spacing
}
style={styles.borderedItem} style={styles.borderedItem}
/> />
); );
@ -231,12 +250,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
); );
} }
private _renderBody(): React.ReactElement<{}> { private _renderBody(): React.ReactElement<{}> {
const bodyStyle: React.CSSProperties = { const bodyStyle = this._getBodyStyle();
...styles.bodyInnerDiv,
overflow: this.state.isHoveringSidebar ? 'auto' : 'hidden',
// TODO: make this completely responsive
maxHeight: this.props.screenWidth !== ScreenWidths.Sm ? 475 : undefined,
};
return ( return (
<div <div
style={bodyStyle} style={bodyStyle}
@ -249,6 +263,14 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
</div> </div>
); );
} }
private _getBodyStyle(): React.CSSProperties {
return {
...styles.bodyInnerDiv,
overflow: this.state.isHoveringSidebar ? 'auto' : 'hidden',
// TODO: make this completely responsive
maxHeight: this.props.screenWidth !== ScreenWidths.Sm ? 475 : undefined,
};
}
private _onSidebarHover(_event: React.FormEvent<HTMLInputElement>): void { private _onSidebarHover(_event: React.FormEvent<HTMLInputElement>): void {
this.setState({ this.setState({
isHoveringSidebar: true, isHoveringSidebar: true,
@ -572,7 +594,7 @@ interface PlaceHolderProps {
children?: React.ReactNode; children?: React.ReactNode;
} }
const PlaceHolder = (props: PlaceHolderProps) => { const PlaceHolder = (props: PlaceHolderProps) => {
const rootBackgroundColor = props.hideChildren ? colors.lightGrey : 'transparent'; const rootBackgroundColor = props.hideChildren ? PLACEHOLDER_COLOR : 'transparent';
const rootStyle: React.CSSProperties = { const rootStyle: React.CSSProperties = {
backgroundColor: rootBackgroundColor, backgroundColor: rootBackgroundColor,
display: 'inline-block', display: 'inline-block',
@ -586,4 +608,35 @@ const PlaceHolder = (props: PlaceHolderProps) => {
</div> </div>
); );
}; };
const NullTokenRow = () => {
const icon = <Circle diameter={ICON_DIMENSION} fillColor={PLACEHOLDER_COLOR} />;
const main = (
<div className="flex flex-column">
<PlaceHolder hideChildren={true}>
<div style={styles.amountLabel}>0.00 XXX</div>
</PlaceHolder>
<Container marginTop="3px">
<PlaceHolder hideChildren={true}>
<div style={styles.valueLabel}>0.00</div>
</PlaceHolder>
</Container>
</div>
);
const accessory = (
<Container marginRight="12px">
<PlaceHolder hideChildren={true}>
<Container width="20px" height="14px" />
</PlaceHolder>
</Container>
);
return (
<StandardIconRow
icon={icon}
main={main}
accessory={accessory}
style={{ ...styles.tokenItem, ...styles.borderedItem }}
/>
);
};
// tslint:disable:max-file-line-count // tslint:disable:max-file-line-count

View File

@ -6,8 +6,6 @@ const appColors = {
walletDefaultItemBackground: '#fbfbfc', walletDefaultItemBackground: '#fbfbfc',
walletFocusedItemBackground: '#f0f1f4', walletFocusedItemBackground: '#f0f1f4',
allowanceToggleShadow: 'rgba(0, 0, 0, 0)', allowanceToggleShadow: 'rgba(0, 0, 0, 0)',
allowanceToggleOffTrack: '#adadad',
allowanceToggleOnTrack: sharedColors.mediumBlue,
wrapEtherConfirmationButton: sharedColors.mediumBlue, wrapEtherConfirmationButton: sharedColors.mediumBlue,
drawerMenuBackground: '#4a4a4a', drawerMenuBackground: '#4a4a4a',
menuItemDefaultSelectedBackground: '#424242', menuItemDefaultSelectedBackground: '#424242',