mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-28 03:08:30 +00:00
Refactorize "AccountMenu" component
This commit is contained in:
parent
25ee6a9b0a
commit
55fc01454d
@ -15,3 +15,7 @@ export const ICON_SIZE = {
|
|||||||
export const BORDER_WIDTH = {
|
export const BORDER_WIDTH = {
|
||||||
SELECTED: '3px',
|
SELECTED: '3px',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const LEFT_NAVIGATION_ROW = {
|
||||||
|
PADDING: '16px 24px',
|
||||||
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
import React, { Component } from 'react';
|
import React from 'react';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import Icon from 'components/Icon';
|
import Icon from 'components/Icon';
|
||||||
import colors from 'config/colors';
|
import colors from 'config/colors';
|
||||||
@ -13,7 +13,7 @@ import ICONS from 'config/icons';
|
|||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
import { findDeviceAccounts } from 'reducers/AccountsReducer';
|
import { findDeviceAccounts } from 'reducers/AccountsReducer';
|
||||||
import {
|
import {
|
||||||
FONT_SIZE, BORDER_WIDTH, TRANSITION_TIME,
|
FONT_SIZE, BORDER_WIDTH, TRANSITION_TIME, LEFT_NAVIGATION_ROW,
|
||||||
} from 'config/variables';
|
} from 'config/variables';
|
||||||
|
|
||||||
import type { Accounts } from 'flowtype';
|
import type { Accounts } from 'flowtype';
|
||||||
@ -30,83 +30,109 @@ const Text = styled.span`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const RowAccountWrapper = styled.div`
|
const RowAccountWrapper = styled.div`
|
||||||
height: 64px;
|
width: 100%;
|
||||||
padding: 16px 0 16px 24px;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: ${LEFT_NAVIGATION_ROW.PADDING};
|
||||||
font-size: ${FONT_SIZE.SMALL};
|
font-size: ${FONT_SIZE.SMALL};
|
||||||
color: ${colors.TEXT_PRIMARY};
|
color: ${colors.TEXT_PRIMARY};
|
||||||
|
${props => props.borderTop && css`
|
||||||
border-top: 1px solid ${colors.DIVIDER};
|
border-top: 1px solid ${colors.DIVIDER};
|
||||||
|
`}
|
||||||
|
border-bottom: 1px solid ${colors.DIVIDER};
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: ${colors.GRAY_LIGHT};
|
background-color: ${colors.GRAY_LIGHT};
|
||||||
}
|
}
|
||||||
${props => props.isSelected && css`
|
${props => props.isSelected && css`
|
||||||
border-left: ${BORDER_WIDTH.SELECTED} solid ${colors.GREEN_PRIMARY};
|
border-left: ${BORDER_WIDTH.SELECTED} solid ${colors.GREEN_PRIMARY};
|
||||||
background: ${colors.WHITE};
|
background: ${colors.WHITE};
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: ${colors.WHITE};
|
background-color: ${colors.WHITE};
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-bottom: 1px solid ${colors.DIVIDER};
|
|
||||||
}
|
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RowAccount = ({
|
const RowAccount = ({
|
||||||
accountIndex, balance, isSelected = false,
|
accountIndex, balance, isSelected = false, borderTop = false,
|
||||||
}) => (
|
}) => (
|
||||||
|
<Row column>
|
||||||
<RowAccountWrapper
|
<RowAccountWrapper
|
||||||
isSelected={isSelected}
|
isSelected={isSelected}
|
||||||
|
borderTop={borderTop}
|
||||||
>
|
>
|
||||||
<Row column>
|
|
||||||
Account #{accountIndex + 1}
|
Account #{accountIndex + 1}
|
||||||
{balance ? (
|
{balance ? (
|
||||||
<Text>{balance}</Text>
|
<Text>{balance}</Text>
|
||||||
) : (
|
) : (
|
||||||
<Text>Loading...</Text>
|
<Text>Loading...</Text>
|
||||||
)}
|
)}
|
||||||
</Row>
|
|
||||||
</RowAccountWrapper>
|
</RowAccountWrapper>
|
||||||
|
</Row>
|
||||||
);
|
);
|
||||||
|
|
||||||
RowAccount.propTypes = {
|
RowAccount.propTypes = {
|
||||||
accountIndex: PropTypes.number.isRequired,
|
accountIndex: PropTypes.number.isRequired,
|
||||||
balance: PropTypes.string,
|
balance: PropTypes.string,
|
||||||
isSelected: PropTypes.bool,
|
isSelected: PropTypes.bool,
|
||||||
|
borderTop: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
const AddAccountWrapper = styled.div`
|
const RowAddAccountWrapper = styled.div`
|
||||||
position: relative;
|
width: 100%;
|
||||||
padding: 8px 0 8px 20px;
|
padding: ${LEFT_NAVIGATION_ROW.PADDING};
|
||||||
cursor: pointer;
|
|
||||||
color: ${colors.TEXT_SECONDARY};
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: ${colors.TEXT_PRIMARY};
|
|
||||||
transition: background-color ${TRANSITION_TIME.BASE} ease-in-out, color ${TRANSITION_TIME.BASE} ease-in-out, border-color ${TRANSITION_TIME.BASE} ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
${props => props.disabled && css`
|
|
||||||
cursor: not-allowed;
|
|
||||||
&:hover {
|
|
||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
|
&:hover {
|
||||||
|
cursor: ${props => (props.disabled ? 'default' : 'pointer')};
|
||||||
|
color: ${props => (props.disabled ? colors.TEXT_SECONDARY : colors.TEXT_PRIMARY)};
|
||||||
}
|
}
|
||||||
`}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const AddAccountIconWrapper = styled.div`
|
const AddAccountIconWrapper = styled.div`
|
||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const RowAddAccount = (({
|
||||||
|
disabled = false, onClick, onMouseEnter, onMouseLeave, onFocus,
|
||||||
|
}) => (
|
||||||
|
<Row
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={onClick}
|
||||||
|
onMouseEnter={onMouseEnter}
|
||||||
|
onMouseLeave={onMouseLeave}
|
||||||
|
onFocus={onFocus}
|
||||||
|
>
|
||||||
|
<RowAddAccountWrapper
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
|
<AddAccountIconWrapper>
|
||||||
|
<Icon
|
||||||
|
icon={ICONS.PLUS}
|
||||||
|
size={24}
|
||||||
|
color={colors.TEXT_SECONDARY}
|
||||||
|
/>
|
||||||
|
</AddAccountIconWrapper>
|
||||||
|
Add account
|
||||||
|
</RowAddAccountWrapper>
|
||||||
|
</Row>
|
||||||
|
));
|
||||||
|
|
||||||
|
RowAddAccount.propTypes = {
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
onMouseEnter: PropTypes.func,
|
||||||
|
onMouseLeave: PropTypes.func,
|
||||||
|
onFocus: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
const DiscoveryStatusWrapper = styled.div`
|
const DiscoveryStatusWrapper = styled.div`
|
||||||
height: 64px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-evenly;
|
|
||||||
font-size: ${FONT_SIZE.SMALL};
|
font-size: ${FONT_SIZE.SMALL};
|
||||||
padding: 16px 28px 16px 30px;
|
padding: ${LEFT_NAVIGATION_ROW.PADDING};
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border-top: 1px solid ${colors.DIVIDER};
|
border-top: 1px solid ${colors.DIVIDER};
|
||||||
`;
|
`;
|
||||||
@ -119,12 +145,28 @@ const DiscoveryStatusText = styled.div`
|
|||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const RowDiscoveryStatus = (({
|
||||||
|
instanceLabel,
|
||||||
|
}) => (
|
||||||
|
<Row>
|
||||||
|
<DiscoveryStatusWrapper>
|
||||||
|
Accounts could not be loaded
|
||||||
|
<DiscoveryStatusText>
|
||||||
|
{`Connect ${instanceLabel} device`}
|
||||||
|
</DiscoveryStatusText>
|
||||||
|
</DiscoveryStatusWrapper>
|
||||||
|
</Row>
|
||||||
|
));
|
||||||
|
|
||||||
|
RowDiscoveryStatus.propTypes = {
|
||||||
|
instanceLabel: PropTypes.number.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
const DiscoveryLoadingWrapper = styled.div`
|
const DiscoveryLoadingWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding: ${LEFT_NAVIGATION_ROW.PADDING};
|
||||||
font-size: ${FONT_SIZE.SMALL};
|
font-size: ${FONT_SIZE.SMALL};
|
||||||
padding: 8px 0 8px 22px;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
`;
|
`;
|
||||||
@ -133,27 +175,16 @@ const DiscoveryLoadingText = styled.span`
|
|||||||
margin-left: 14px;
|
margin-left: 14px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
// class AccountMenu extends Component {
|
const RowDiscoveryLoading = (() => (
|
||||||
// constructor(props: Props) {
|
<Row>
|
||||||
// super(props);
|
<DiscoveryLoadingWrapper>
|
||||||
// this.state = {
|
<Loader size="20" />
|
||||||
// selectedAccounts: null,
|
<DiscoveryLoadingText>
|
||||||
// selectedCoin: null,
|
Loading...
|
||||||
// };
|
</DiscoveryLoadingText>
|
||||||
// }
|
</DiscoveryLoadingWrapper>
|
||||||
|
</Row>
|
||||||
// componentWillReceiveProps(nextProps) {
|
));
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// render() {
|
|
||||||
// return (
|
|
||||||
// <div>
|
|
||||||
// Hello
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
const AccountMenu = (props: Props): ?React$Element<string> => {
|
const AccountMenu = (props: Props): ?React$Element<string> => {
|
||||||
const selected = props.wallet.selectedDevice;
|
const selected = props.wallet.selectedDevice;
|
||||||
@ -198,6 +229,7 @@ const AccountMenu = (props: Props): ?React$Element<string> => {
|
|||||||
url={url}
|
url={url}
|
||||||
balance={balance}
|
balance={balance}
|
||||||
isSelected={urlAccountIndex === account.index}
|
isSelected={urlAccountIndex === account.index}
|
||||||
|
borderTop={account.index === 0}
|
||||||
/>
|
/>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
);
|
);
|
||||||
@ -214,6 +246,7 @@ const AccountMenu = (props: Props): ?React$Element<string> => {
|
|||||||
accountIndex={0}
|
accountIndex={0}
|
||||||
url={url}
|
url={url}
|
||||||
isSelected
|
isSelected
|
||||||
|
borderTop
|
||||||
/>
|
/>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
);
|
);
|
||||||
@ -229,20 +262,7 @@ const AccountMenu = (props: Props): ?React$Element<string> => {
|
|||||||
//if (selectedAccounts.length > 0 && selectedAccounts[selectedAccounts.length - 1])
|
//if (selectedAccounts.length > 0 && selectedAccounts[selectedAccounts.length - 1])
|
||||||
const lastAccount = deviceAccounts[deviceAccounts.length - 1];
|
const lastAccount = deviceAccounts[deviceAccounts.length - 1];
|
||||||
if (lastAccount && (new BigNumber(lastAccount.balance).greaterThan(0) || lastAccount.nonce > 0)) {
|
if (lastAccount && (new BigNumber(lastAccount.balance).greaterThan(0) || lastAccount.nonce > 0)) {
|
||||||
discoveryStatus = (
|
discoveryStatus = <RowAddAccount onClick={props.addAccount} />;
|
||||||
<AddAccountWrapper
|
|
||||||
onClick={props.addAccount}
|
|
||||||
>
|
|
||||||
<AddAccountIconWrapper>
|
|
||||||
<Icon
|
|
||||||
icon={ICONS.PLUS}
|
|
||||||
size={24}
|
|
||||||
color={colors.TEXT_SECONDARY}
|
|
||||||
/>
|
|
||||||
</AddAccountIconWrapper>
|
|
||||||
Add account
|
|
||||||
</AddAccountWrapper>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
const tooltip = (
|
const tooltip = (
|
||||||
<div className="aside-tooltip-wrapper">
|
<div className="aside-tooltip-wrapper">
|
||||||
@ -253,41 +273,17 @@ const AccountMenu = (props: Props): ?React$Element<string> => {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
arrowContent={<div className="rc-tooltip-arrow-inner" />}
|
arrowContent={<div className="rc-tooltip-arrow-inner" />}
|
||||||
overlay={tooltip}
|
overlay={tooltip}
|
||||||
placement="top"
|
placement="bottom"
|
||||||
>
|
>
|
||||||
<AddAccountWrapper
|
<RowAddAccount disabled />
|
||||||
onClick={props.addAccount}
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
<AddAccountIconWrapper>
|
|
||||||
<Icon
|
|
||||||
icon={ICONS.PLUS}
|
|
||||||
size={24}
|
|
||||||
color={colors.TEXT_SECONDARY}
|
|
||||||
/>
|
|
||||||
</AddAccountIconWrapper>
|
|
||||||
Add account
|
|
||||||
</AddAccountWrapper>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (!selected.connected || !selected.available) {
|
} else if (!selected.connected || !selected.available) {
|
||||||
discoveryStatus = (
|
discoveryStatus = <RowDiscoveryStatus instanceLabel={selected.instanceLabel} />;
|
||||||
<DiscoveryStatusWrapper>
|
|
||||||
Accounts could not be loaded
|
|
||||||
<DiscoveryStatusText>
|
|
||||||
{`Connect ${selected.instanceLabel} device`}
|
|
||||||
</DiscoveryStatusText>
|
|
||||||
</DiscoveryStatusWrapper>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
discoveryStatus = (
|
discoveryStatus = (
|
||||||
<DiscoveryLoadingWrapper>
|
<RowDiscoveryLoading />
|
||||||
<Loader size="20" />
|
|
||||||
<DiscoveryLoadingText>
|
|
||||||
Loading accounts...
|
|
||||||
</DiscoveryLoadingText>
|
|
||||||
</DiscoveryLoadingWrapper>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,21 +6,27 @@ import { TRANSITION_TIME } from 'config/variables';
|
|||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
cursor: pointer;
|
transition: background-color ${TRANSITION_TIME.BASE} ease-in-out, color ${TRANSITION_TIME.BASE} ease-in-out, border-color ${TRANSITION_TIME.BASE} ease-in-out;
|
||||||
transition: background-color ${TRANSITION_TIME.BASE}, color ${TRANSITION_TIME.BASE};
|
|
||||||
|
|
||||||
${props => props.column && css`
|
${props => props.disabled && css`
|
||||||
flex-direction: column;
|
cursor: not-allowed;
|
||||||
align-items: flex-start;
|
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Row = ({ children, column = false }) => (
|
const Row = ({
|
||||||
<Wrapper column={column}>
|
children, disabled = false, onClick, onMouseEnter, onMouseLeave, onFocus,
|
||||||
|
}) => (
|
||||||
|
<Wrapper
|
||||||
|
disabled={disabled}
|
||||||
|
onClick={onClick}
|
||||||
|
onMouseEnter={onMouseEnter}
|
||||||
|
onMouseLeave={onMouseLeave}
|
||||||
|
onFocus={onFocus}
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
@ -30,7 +36,11 @@ Row.propTypes = {
|
|||||||
PropTypes.arrayOf(PropTypes.node),
|
PropTypes.arrayOf(PropTypes.node),
|
||||||
PropTypes.node,
|
PropTypes.node,
|
||||||
]),
|
]),
|
||||||
column: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
onMouseEnter: PropTypes.func,
|
||||||
|
onMouseLeave: PropTypes.func,
|
||||||
|
onFocus: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Row;
|
export default Row;
|
||||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import Icon from 'components/Icon';
|
import Icon from 'components/Icon';
|
||||||
import { ICON_SIZE, FONT_SIZE } from 'config/variables';
|
import { ICON_SIZE, FONT_SIZE, LEFT_NAVIGATION_ROW } from 'config/variables';
|
||||||
import colors from 'config/colors';
|
import colors from 'config/colors';
|
||||||
import Row from '../Row';
|
import Row from '../Row';
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ const Logo = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const RowCoinWrapper = styled.div`
|
const RowCoinWrapper = styled.div`
|
||||||
padding: 16px 24px;
|
padding: ${LEFT_NAVIGATION_ROW.PADDING};
|
||||||
height: 50px;
|
height: 50px;
|
||||||
display: block;
|
display: block;
|
||||||
font-size: ${FONT_SIZE.BASE};
|
font-size: ${FONT_SIZE.BASE};
|
||||||
|
Loading…
Reference in New Issue
Block a user