Merge branch 'master' into feature/trezor-ui-components

pull/463/head
slowbackspace 5 years ago
commit 34ff337db1

@ -1,4 +1,4 @@
![Alt text](src/images/trezor-rocks.png?raw=true "Trezor Wallet rocks") ![Alt text](trezor-rocks.png?raw=true "Trezor Wallet rocks")
# Trezor Wallet # Trezor Wallet

@ -58,6 +58,7 @@ const KEY_PENDING: string = `${STORAGE_PATH}pending`;
const KEY_BETA_MODAL: string = '/betaModalPrivacy'; // this key needs to be compatible with "parent" (old) wallet const KEY_BETA_MODAL: string = '/betaModalPrivacy'; // this key needs to be compatible with "parent" (old) wallet
const KEY_LANGUAGE: string = `${STORAGE_PATH}language`; const KEY_LANGUAGE: string = `${STORAGE_PATH}language`;
const KEY_LOCAL_CURRENCY: string = `${STORAGE_PATH}localCurrency`; const KEY_LOCAL_CURRENCY: string = `${STORAGE_PATH}localCurrency`;
const KEY_HIDE_BALANCE: string = `${STORAGE_PATH}hideBalance`;
// https://github.com/STRML/react-localstorage/blob/master/react-localstorage.js // https://github.com/STRML/react-localstorage/blob/master/react-localstorage.js
// or // or
@ -282,6 +283,11 @@ const loadStorageData = (): ThunkAction => (dispatch: Dispatch): void => {
if (localCurrency) { if (localCurrency) {
dispatch(WalletActions.setLocalCurrency(JSON.parse(localCurrency))); dispatch(WalletActions.setLocalCurrency(JSON.parse(localCurrency)));
} }
const hideBalance: ?boolean = storageUtils.get(TYPE, KEY_HIDE_BALANCE);
if (hideBalance) {
dispatch(WalletActions.setHideBalance(hideBalance));
}
}; };
export const loadData = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => { export const loadData = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => {
@ -303,6 +309,11 @@ export const setLanguage = (): ThunkAction => (dispatch: Dispatch, getState: Get
storageUtils.set(TYPE, KEY_LANGUAGE, JSON.stringify(language)); storageUtils.set(TYPE, KEY_LANGUAGE, JSON.stringify(language));
}; };
export const setHideBalance = (): ThunkAction => (dispatch: Dispatch, getState: GetState): void => {
const { hideBalance } = getState().wallet;
storageUtils.set(TYPE, KEY_HIDE_BALANCE, hideBalance);
};
export const setLocalCurrency = (): ThunkAction => ( export const setLocalCurrency = (): ThunkAction => (
dispatch: Dispatch, dispatch: Dispatch,
getState: GetState getState: GetState

@ -62,6 +62,10 @@ export type WalletAction =
| { | {
type: typeof WALLET.SET_LOCAL_CURRENCY, type: typeof WALLET.SET_LOCAL_CURRENCY,
localCurrency: string, localCurrency: string,
}
| {
type: typeof WALLET.SET_HIDE_BALANCE,
toggled: boolean,
}; };
export const init = (): ThunkAction => (dispatch: Dispatch): void => { export const init = (): ThunkAction => (dispatch: Dispatch): void => {
@ -113,6 +117,11 @@ export const setLocalCurrency = (localCurrency: string): WalletAction => ({
localCurrency: localCurrency.toLowerCase(), localCurrency: localCurrency.toLowerCase(),
}); });
export const setHideBalance = (toggled: boolean): WalletAction => ({
type: WALLET.SET_HIDE_BALANCE,
toggled,
});
// This method will be called after each DEVICE.CONNECT action // This method will be called after each DEVICE.CONNECT action
// if connected device has different "passphrase_protection" settings than saved instances // if connected device has different "passphrase_protection" settings than saved instances
// all saved instances will be removed immediately inside DevicesReducer // all saved instances will be removed immediately inside DevicesReducer

@ -18,3 +18,4 @@ export const CLEAR_UNAVAILABLE_DEVICE_DATA: 'wallet__clear_unavailable_device_da
export const TOGGLE_SIDEBAR: 'wallet__toggle_sidebar' = 'wallet__toggle_sidebar'; export const TOGGLE_SIDEBAR: 'wallet__toggle_sidebar' = 'wallet__toggle_sidebar';
export const SET_LANGUAGE: 'wallet__set_language' = 'wallet__set_language'; export const SET_LANGUAGE: 'wallet__set_language' = 'wallet__set_language';
export const SET_LOCAL_CURRENCY: 'wallet__set_local_currency' = 'wallet__set_local_currency'; export const SET_LOCAL_CURRENCY: 'wallet__set_local_currency' = 'wallet__set_local_currency';
export const SET_HIDE_BALANCE: 'wallet__set_hide_balance' = 'wallet__set_hide_balance';

@ -5,35 +5,22 @@ import PropTypes from 'prop-types';
const Wrapper = styled.div` const Wrapper = styled.div`
padding-right: 20px; padding-right: 20px;
width: 40px; width: 40px;
display: flex;
justify-content: center;
`; `;
const Logo = styled.img` const Logo = styled.img`
width: ${props => (props.hasLongIcon ? '15px' : '23px')}; height: 23px;
margin-left: ${props => (props.hasLongIcon ? '3px' : '0px')};
display: block; display: block;
`; `;
class CoinLogo extends PureComponent { class CoinLogo extends PureComponent {
constructor() {
super();
this.longIcons = ['etc', 'eth', 'trop'];
}
hasLongIcon(network) {
let hasLongIcon = false;
if (this.longIcons.includes(network)) {
hasLongIcon = true;
}
return hasLongIcon;
}
render() { render() {
const { network, className, standalone } = this.props; const { network, className, standalone } = this.props;
const logo = ( const logo = (
<Logo <Logo
className={className} className={className}
hasLongIcon={this.hasLongIcon(network)}
src={require(`images/coins/${network}.png`)} // eslint-disable-line src={require(`images/coins/${network}.png`)} // eslint-disable-line
/> />
); );

@ -41,9 +41,7 @@ const Wrapper = styled.div`
padding: 30px 48px; padding: 30px 48px;
`; `;
const Text = styled.div` const Text = styled.div``;
padding-right: 10px;
`;
const Column = styled.div` const Column = styled.div`
display: flex; display: flex;
@ -55,8 +53,12 @@ const Column = styled.div`
`; `;
const StyledLoader = styled(Loader)` const StyledLoader = styled(Loader)`
position: absolute; padding-left: 6px;
left: 200px; `;
const ButtonWithLoader = styled(Button)`
padding-top: 6px;
padding-bottom: 6px;
`; `;
class RememberDevice extends PureComponent<Props, State> { class RememberDevice extends PureComponent<Props, State> {
@ -138,7 +140,7 @@ class RememberDevice extends PureComponent<Props, State> {
/> />
</StyledP> </StyledP>
<Column> <Column>
<Button onClick={() => this.forget()}> <ButtonWithLoader onClick={() => this.forget()}>
<ButtonContent> <ButtonContent>
<Text> <Text>
<FormattedMessage {...l10nCommonMessages.TR_FORGET_DEVICE} /> <FormattedMessage {...l10nCommonMessages.TR_FORGET_DEVICE} />
@ -150,7 +152,7 @@ class RememberDevice extends PureComponent<Props, State> {
text={this.state.countdown.toString()} text={this.state.countdown.toString()}
/> />
</ButtonContent> </ButtonContent>
</Button> </ButtonWithLoader>
<Button isWhite onClick={() => onRememberDevice(device)}> <Button isWhite onClick={() => onRememberDevice(device)}>
<FormattedMessage {...l10nMessages.TR_REMEMBER_DEVICE} /> <FormattedMessage {...l10nMessages.TR_REMEMBER_DEVICE} />
</Button> </Button>

@ -13,7 +13,7 @@ export const LANGUAGE = [
{ code: 'pl', name: 'Polski', en: 'Polish' }, { code: 'pl', name: 'Polski', en: 'Polish' },
{ code: 'pt', name: 'Português', en: 'Portuguese' }, { code: 'pt', name: 'Português', en: 'Portuguese' },
{ code: 'ru', name: 'Русский', en: 'Russian' }, { code: 'ru', name: 'Русский', en: 'Russian' },
{ code: 'uk', name: 'Український', en: 'Ukrainian' }, { code: 'uk', name: 'Українська', en: 'Ukrainian' },
{ code: 'zh', name: '中文(简体)', en: 'Chinese Simplified' }, { code: 'zh', name: '中文(简体)', en: 'Chinese Simplified' },
{ code: 'zh_TW', name: '中文(台灣)', en: 'Chinese Traditional' }, { code: 'zh_TW', name: '中文(台灣)', en: 'Chinese Traditional' },
]; ];

@ -13,8 +13,9 @@ type State = {
ready: boolean, ready: boolean,
online: boolean, online: boolean,
language: string, language: string,
localCurrency: string,
messages: { [string]: string }, messages: { [string]: string },
localCurrency: string,
hideBalance: boolean,
dropdownOpened: boolean, dropdownOpened: boolean,
showBetaDisclaimer: boolean, showBetaDisclaimer: boolean,
showSidebar: ?boolean, showSidebar: ?boolean,
@ -29,8 +30,9 @@ const initialState: State = {
ready: false, ready: false,
online: navigator.onLine, online: navigator.onLine,
language: 'en', language: 'en',
localCurrency: 'usd',
messages: {}, messages: {},
localCurrency: 'usd',
hideBalance: false,
dropdownOpened: false, dropdownOpened: false,
firstLocationChange: true, firstLocationChange: true,
showBetaDisclaimer: false, showBetaDisclaimer: false,
@ -137,6 +139,12 @@ export default function wallet(state: State = initialState, action: Action): Sta
localCurrency: action.localCurrency, localCurrency: action.localCurrency,
}; };
case WALLET.SET_HIDE_BALANCE:
return {
...state,
hideBalance: action.toggled,
};
default: default:
return state; return state;
} }

@ -26,6 +26,10 @@ const LocalStorageService: Middleware = (api: MiddlewareAPI) => (next: Middlewar
api.dispatch(LocalStorageActions.setLanguage()); api.dispatch(LocalStorageActions.setLanguage());
break; break;
case WALLET.SET_HIDE_BALANCE:
api.dispatch(LocalStorageActions.setHideBalance());
break;
case WALLET.SET_LOCAL_CURRENCY: case WALLET.SET_LOCAL_CURRENCY:
api.dispatch(LocalStorageActions.setLocalCurrency()); api.dispatch(LocalStorageActions.setLocalCurrency());
break; break;

@ -49,7 +49,7 @@ const BrowserNotSupported = () => (
</Browser> </Browser>
<Browser> <Browser>
<BrowserLogo src={FirefoxImage} /> <BrowserLogo src={FirefoxImage} />
<P size="small">Mozzila Firefox</P> <P size="small">Mozila Firefox</P>
<Link href="https://www.mozilla.org/en-US/firefox/new/"> <Link href="https://www.mozilla.org/en-US/firefox/new/">
<Button> <Button>
<FormattedMessage {...l10nMessages.TR_GET_FIREFOX} /> <FormattedMessage {...l10nMessages.TR_GET_FIREFOX} />

@ -14,6 +14,7 @@ import FirmwareUnsupported from './components/FirmwareUnsupported';
import l10nMessages from './index.messages'; import l10nMessages from './index.messages';
type Props = { type Props = {
className?: string,
children?: React.Node, children?: React.Node,
isLoading?: boolean, isLoading?: boolean,
loader?: $ElementType<$ElementType<State, 'selectedAccount'>, 'loader'>, loader?: $ElementType<$ElementType<State, 'selectedAccount'>, 'loader'>,
@ -72,8 +73,8 @@ const getExceptionPage = exceptionPage => {
} }
}; };
const Content = ({ children, isLoading = false, loader, exceptionPage }: Props) => ( const Content = ({ className, children, isLoading = false, loader, exceptionPage }: Props) => (
<Wrapper> <Wrapper className={className}>
{!isLoading && children} {!isLoading && children}
{isLoading && exceptionPage && getExceptionPage(exceptionPage)} {isLoading && exceptionPage && getExceptionPage(exceptionPage)}
{isLoading && loader && ( {isLoading && loader && (
@ -94,6 +95,7 @@ const Content = ({ children, isLoading = false, loader, exceptionPage }: Props)
Content.propTypes = { Content.propTypes = {
children: PropTypes.oneOfType([PropTypes.element, PropTypes.array]), children: PropTypes.oneOfType([PropTypes.element, PropTypes.array]),
className: PropTypes.string,
isLoading: PropTypes.bool, isLoading: PropTypes.bool,
loader: PropTypes.object, loader: PropTypes.object,
exceptionPage: PropTypes.object, exceptionPage: PropTypes.object,

@ -1,5 +1,5 @@
/* @flow */ /* @flow */
import { toggleDeviceDropdown } from 'actions/WalletActions'; import { toggleDeviceDropdown, toggleSidebar, setHideBalance } from 'actions/WalletActions';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
@ -42,6 +42,8 @@ const mapDispatchToProps: MapDispatchToProps<Dispatch, OwnProps, DispatchProps>
gotoDeviceSettings: bindActionCreators(RouterActions.gotoDeviceSettings, dispatch), gotoDeviceSettings: bindActionCreators(RouterActions.gotoDeviceSettings, dispatch),
onSelectDevice: bindActionCreators(RouterActions.selectDevice, dispatch), onSelectDevice: bindActionCreators(RouterActions.selectDevice, dispatch),
gotoExternalWallet: bindActionCreators(ModalActions.gotoExternalWallet, dispatch), gotoExternalWallet: bindActionCreators(ModalActions.gotoExternalWallet, dispatch),
toggleSidebar: bindActionCreators(toggleSidebar, dispatch),
setHideBalance: bindActionCreators(setHideBalance, dispatch),
}); });
export default withRouter( export default withRouter(

@ -137,7 +137,7 @@ const AccountMenu = (props: Props) => {
{...l10nCommonMessages.TR_ACCOUNT_HASH} {...l10nCommonMessages.TR_ACCOUNT_HASH}
values={{ number: account.index + 1 }} values={{ number: account.index + 1 }}
/> />
{balance && ( {balance && !props.wallet.hideBalance && (
<Text> <Text>
{balance} {balance}
{fiatRates && ( {fiatRates && (

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { getPattern } from 'support/routes'; import { getPattern } from 'support/routes';
import { Link, Icon, colors, icons } from 'trezor-ui-components'; import { Switch, Link, Icon, colors, icons } from 'trezor-ui-components';
import DeviceIcon from 'components/images/DeviceIcon'; import DeviceIcon from 'components/images/DeviceIcon';
import { FONT_SIZE } from 'config/variables'; import { FONT_SIZE } from 'config/variables';
@ -18,6 +18,7 @@ const Wrapper = styled.div`
const Item = styled.div` const Item = styled.div`
padding: 12px 24px; padding: 12px 24px;
display: flex; display: flex;
height: 38px;
align-items: center; align-items: center;
font-size: ${FONT_SIZE.BASE}; font-size: ${FONT_SIZE.BASE};
cursor: pointer; cursor: pointer;
@ -36,6 +37,7 @@ const Divider = styled.div`
const Label = styled.div` const Label = styled.div`
padding-left: 15px; padding-left: 15px;
flex: 1;
`; `;
class MenuItems extends PureComponent { class MenuItems extends PureComponent {
@ -105,6 +107,24 @@ class MenuItems extends PureComponent {
</Label> </Label>
</Item> </Item>
<Divider /> <Divider />
<Item>
<Icon icon={icons.EYE_CROSSED} size={25} color={colors.TEXT_SECONDARY} />
<Label>
<FormattedMessage {...l10nCommonMessages.TR_HIDE_BALANCE} />
</Label>
<Switch
width={36}
height={18}
handleDiameter={14}
checkedIcon={false}
uncheckedIcon={false}
onChange={checked => {
this.props.setHideBalance(checked);
}}
checked={this.props.wallet.hideBalance}
/>
</Item>
<Divider />
<Link to={getPattern('wallet-settings')}> <Link to={getPattern('wallet-settings')}>
<Item> <Item>
<Icon icon={icons.COG} size={14} color={colors.TEXT_SECONDARY} /> <Icon icon={icons.COG} size={14} color={colors.TEXT_SECONDARY} />
@ -120,9 +140,11 @@ class MenuItems extends PureComponent {
MenuItems.propTypes = { MenuItems.propTypes = {
device: PropTypes.object.isRequired, device: PropTypes.object.isRequired,
wallet: PropTypes.object.isRequired,
acquireDevice: PropTypes.func.isRequired, acquireDevice: PropTypes.func.isRequired,
forgetDevice: PropTypes.func.isRequired, forgetDevice: PropTypes.func.isRequired,
duplicateDevice: PropTypes.func.isRequired, duplicateDevice: PropTypes.func.isRequired,
setHideBalance: PropTypes.func.isRequired,
// toggleDeviceDropdown: PropTypes.func.isRequired, // toggleDeviceDropdown: PropTypes.func.isRequired,
// gotoDeviceSettings: PropTypes.func.isRequired, // gotoDeviceSettings: PropTypes.func.isRequired,
}; };

@ -14,7 +14,9 @@ const CoinNameWrapper = styled.div`
const RowCoinWrapper = styled.div` const RowCoinWrapper = styled.div`
padding: ${LEFT_NAVIGATION_ROW.PADDING}; padding: ${LEFT_NAVIGATION_ROW.PADDING};
height: 50px; padding-top: 0;
padding-bottom: 0;
height: 44px;
display: block; display: block;
font-size: ${FONT_SIZE.BIG}; font-size: ${FONT_SIZE.BIG};
color: ${colors.TEXT_PRIMARY}; color: ${colors.TEXT_PRIMARY};

@ -3,7 +3,7 @@ import * as TrezorConnectActions from 'actions/TrezorConnectActions';
import * as DiscoveryActions from 'actions/DiscoveryActions'; import * as DiscoveryActions from 'actions/DiscoveryActions';
import * as RouterActions from 'actions/RouterActions'; import * as RouterActions from 'actions/RouterActions';
import * as ModalActions from 'actions/ModalActions'; import * as ModalActions from 'actions/ModalActions';
import { toggleDeviceDropdown } from 'actions/WalletActions'; import * as WalletActions from 'actions/WalletActions';
import type { State } from 'flowtype'; import type { State } from 'flowtype';
export type StateProps = { export type StateProps = {
@ -19,7 +19,9 @@ export type StateProps = {
}; };
export type DispatchProps = { export type DispatchProps = {
toggleDeviceDropdown: typeof toggleDeviceDropdown, toggleDeviceDropdown: typeof WalletActions.toggleDeviceDropdown,
toggleSidebar: typeof WalletActions.toggleSidebar,
setHideBalance: typeof WalletActions.setHideBalance,
addAccount: typeof DiscoveryActions.addAccount, addAccount: typeof DiscoveryActions.addAccount,
acquireDevice: typeof TrezorConnectActions.acquire, acquireDevice: typeof TrezorConnectActions.acquire,
forgetDevice: typeof TrezorConnectActions.forget, forgetDevice: typeof TrezorConnectActions.forget,

@ -3,11 +3,12 @@
import * as React from 'react'; import * as React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Icon, Tooltip, icons, colors } from 'trezor-ui-components'; import { Icon, Tooltip, icons, colors } from 'trezor-ui-components';
import { FONT_SIZE } from 'config/variables'; import { FONT_SIZE, SCREEN_SIZE } from 'config/variables';
import WalletTypeIcon from 'components/images/WalletType'; import WalletTypeIcon from 'components/images/WalletType';
import { TransitionGroup, CSSTransition } from 'react-transition-group'; import { TransitionGroup, CSSTransition } from 'react-transition-group';
import styled from 'styled-components'; import styled from 'styled-components';
import DeviceHeader from 'components/DeviceHeader'; import DeviceHeader from 'components/DeviceHeader';
import Backdrop from 'components/Backdrop';
// import Link from 'components/Link'; // import Link from 'components/Link';
import * as deviceUtils from 'utils/device'; import * as deviceUtils from 'utils/device';
@ -104,6 +105,14 @@ type TransitionMenuProps = {
children?: React.Node, children?: React.Node,
}; };
const StyledBackdrop = styled(Backdrop)`
display: none;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
display: initial;
}
`;
// TransitionMenu needs to dispatch window.resize event // TransitionMenu needs to dispatch window.resize event
// in order to StickyContainer be recalculated // in order to StickyContainer be recalculated
const TransitionMenu = (props: TransitionMenuProps): React$Element<TransitionGroup> => ( const TransitionMenu = (props: TransitionMenuProps): React$Element<TransitionGroup> => (
@ -261,6 +270,11 @@ class LeftNavigation extends React.PureComponent<Props, State> {
return ( return (
<Sidebar isOpen={props.wallet.showSidebar}> <Sidebar isOpen={props.wallet.showSidebar}>
<StyledBackdrop
show={props.wallet.showSidebar}
onClick={props.toggleSidebar}
animated
/>
<Header <Header
isSelected isSelected
testId="Main__page__device__header" testId="Main__page__device__header"
@ -392,6 +406,7 @@ LeftNavigation.propTypes = {
duplicateDevice: PropTypes.func, duplicateDevice: PropTypes.func,
gotoDeviceSettings: PropTypes.func, gotoDeviceSettings: PropTypes.func,
onSelectDevice: PropTypes.func, onSelectDevice: PropTypes.func,
setHideBalance: PropTypes.func,
}; };
export default LeftNavigation; export default LeftNavigation;

@ -23,7 +23,6 @@ import ContextNotifications from 'components/notifications/Context';
import { SCREEN_SIZE } from 'config/variables'; import { SCREEN_SIZE } from 'config/variables';
import Log from 'components/Log'; import Log from 'components/Log';
import Backdrop from 'components/Backdrop';
import LeftNavigation from './components/LeftNavigation/Container'; import LeftNavigation from './components/LeftNavigation/Container';
import TopNavigationAccount from './components/TopNavigationAccount'; import TopNavigationAccount from './components/TopNavigationAccount';
@ -110,14 +109,6 @@ const Body = styled.div`
flex-direction: column; flex-direction: column;
`; `;
const StyledBackdrop = styled(Backdrop)`
display: none;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
display: initial;
}
`;
const Wallet = (props: Props) => ( const Wallet = (props: Props) => (
<AppWrapper> <AppWrapper>
<Header <Header
@ -127,11 +118,6 @@ const Wallet = (props: Props) => (
/> />
<AppNotifications /> <AppNotifications />
<WalletWrapper> <WalletWrapper>
<StyledBackdrop
show={props.wallet.showSidebar}
onClick={props.toggleSidebar}
animated
/>
{props.wallet.selectedDevice && <LeftNavigation />} {props.wallet.selectedDevice && <LeftNavigation />}
<MainContent preventBgScroll={props.wallet.showSidebar}> <MainContent preventBgScroll={props.wallet.showSidebar}>
<Navigation> <Navigation>

@ -401,7 +401,7 @@ const AccountSend = (props: Props) => {
<AmountInputLabel> <AmountInputLabel>
<FormattedMessage {...l10nSendMessages.TR_AMOUNT} /> <FormattedMessage {...l10nSendMessages.TR_AMOUNT} />
</AmountInputLabel> </AmountInputLabel>
{isCurrentCurrencyToken && selectedToken && ( {isCurrentCurrencyToken && selectedToken && !props.wallet.hideBalance && (
<AmountInputLabel> <AmountInputLabel>
<FormattedMessage <FormattedMessage
{...l10nMessages.YOU_HAVE_TOKEN_BALANCE} {...l10nMessages.YOU_HAVE_TOKEN_BALANCE}

@ -15,6 +15,7 @@ type Props = {
balance: string, balance: string,
fiat: $ElementType<ReducersState, 'fiat'>, fiat: $ElementType<ReducersState, 'fiat'>,
localCurrency: string, localCurrency: string,
isHidden: boolean,
}; };
type State = { type State = {
@ -103,11 +104,20 @@ class AccountBalance extends PureComponent<Props, State> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
this.state = { this.state = {
isHidden: false, isHidden: props.isHidden,
canAnimateHideBalanceIcon: false, canAnimateHideBalanceIcon: props.isHidden,
}; };
} }
componentDidUpdate(prevProps: Props) {
if (prevProps.isHidden !== this.props.isHidden) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
isHidden: this.props.isHidden,
});
}
}
handleHideBalanceIconClick() { handleHideBalanceIconClick() {
this.setState(previousState => ({ this.setState(previousState => ({
isHidden: !previousState.isHidden, isHidden: !previousState.isHidden,

@ -1,12 +1,14 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { FormattedMessage } from 'react-intl';
import ColorHash from 'color-hash'; import ColorHash from 'color-hash';
import ScaleText from 'react-scale-text'; import ScaleText from 'react-scale-text';
import { FONT_WEIGHT } from 'config/variables'; import { FONT_WEIGHT } from 'config/variables';
import { Button, Icon, colors, icons as ICONS } from 'trezor-ui-components'; import { Button, Icon, Tooltip, colors, icons as ICONS } from 'trezor-ui-components';
import * as stateUtils from 'reducers/utils'; import * as stateUtils from 'reducers/utils';
import BigNumber from 'bignumber.js'; import BigNumber from 'bignumber.js';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import l10nCommonMessages from 'views/common.messages';
const TokenWrapper = styled.div` const TokenWrapper = styled.div`
padding: 14px 0; padding: 14px 0;
@ -57,6 +59,10 @@ const RemoveTokenButton = styled(Button)`
padding: 0 0 0 10px; padding: 0 0 0 10px;
`; `;
const TooltipIcon = styled(Icon)`
cursor: pointer;
`;
class AddedToken extends PureComponent { class AddedToken extends PureComponent {
getTokenBalance(token) { getTokenBalance(token) {
const pendingAmount = stateUtils.getPendingAmount(this.props.pending, token.symbol, true); const pendingAmount = stateUtils.getPendingAmount(this.props.pending, token.symbol, true);
@ -81,7 +87,25 @@ class AddedToken extends PureComponent {
<TokenName>{this.props.token.name}</TokenName> <TokenName>{this.props.token.name}</TokenName>
<TokenBalance> <TokenBalance>
{this.getTokenBalance(this.props.token)} {this.props.token.symbol} {this.props.hideBalance ? (
<Tooltip
maxWidth={200}
placement="top"
content={
<FormattedMessage
{...l10nCommonMessages.TR_THE_ACCOUNT_BALANCE_IS_HIDDEN}
/>
}
>
<TooltipIcon
icon={ICONS.EYE_CROSSED}
size={25}
color={colors.TEXT_SECONDARY}
/>
</Tooltip>
) : (
`${this.getTokenBalance(this.props.token)} ${this.props.token.symbol}`
)}
</TokenBalance> </TokenBalance>
<RemoveTokenButton <RemoveTokenButton
isTransparent isTransparent
@ -98,6 +122,7 @@ AddedToken.propTypes = {
token: PropTypes.object, token: PropTypes.object,
pending: PropTypes.array, pending: PropTypes.array,
removeToken: PropTypes.func, removeToken: PropTypes.func,
hideBalance: PropTypes.bool,
}; };
export default AddedToken; export default AddedToken;

@ -93,6 +93,7 @@ const AccountSummary = (props: Props) => {
balance={balance} balance={balance}
fiat={props.fiat} fiat={props.fiat}
localCurrency={props.wallet.localCurrency} localCurrency={props.wallet.localCurrency}
isHidden={props.wallet.hideBalance}
/> />
<TokensHeadingWrapper> <TokensHeadingWrapper>
<H5> <H5>
@ -152,6 +153,7 @@ const AccountSummary = (props: Props) => {
token={token} token={token}
pending={pending} pending={pending}
removeToken={props.removeToken} removeToken={props.removeToken}
hideBalance={props.wallet.hideBalance}
/> />
))} ))}
</AddedTokensWrapper> </AddedTokensWrapper>

@ -14,6 +14,7 @@ type Props = {
reserve: string, reserve: string,
fiat: $ElementType<ReducersState, 'fiat'>, fiat: $ElementType<ReducersState, 'fiat'>,
localCurrency: string, localCurrency: string,
isHidden: boolean,
}; };
type State = { type State = {
@ -102,11 +103,21 @@ class AccountBalance extends PureComponent<Props, State> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
this.state = { this.state = {
isHidden: false, isHidden: props.isHidden,
canAnimateHideBalanceIcon: false, canAnimateHideBalanceIcon: props.isHidden,
}; };
} }
componentDidUpdate(prevProps: Props) {
console.log(this.props.isHidden);
if (prevProps.isHidden !== this.props.isHidden) {
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
isHidden: this.props.isHidden,
});
}
}
handleHideBalanceIconClick() { handleHideBalanceIconClick() {
this.setState(previousState => ({ this.setState(previousState => ({
isHidden: !previousState.isHidden, isHidden: !previousState.isHidden,

@ -85,6 +85,7 @@ const AccountSummary = (props: Props) => {
reserve={reserve} reserve={reserve}
fiat={props.fiat} fiat={props.fiat}
localCurrency={props.wallet.localCurrency} localCurrency={props.wallet.localCurrency}
isHidden={props.wallet.hideBalance}
/> />
{TMP_SHOW_HISTORY && ( {TMP_SHOW_HISTORY && (
<HeadingWrapper> <HeadingWrapper>

@ -18,6 +18,7 @@ type StateProps = {
type DispatchProps = { type DispatchProps = {
setLocalCurrency: typeof WalletActions.setLocalCurrency, setLocalCurrency: typeof WalletActions.setLocalCurrency,
setHideBalance: typeof WalletActions.setHideBalance,
}; };
export type Props = StateProps & DispatchProps; export type Props = StateProps & DispatchProps;
@ -34,6 +35,7 @@ const mapDispatchToProps: MapDispatchToProps<Dispatch, OwnProps, DispatchProps>
dispatch: Dispatch dispatch: Dispatch
): DispatchProps => ({ ): DispatchProps => ({
setLocalCurrency: bindActionCreators(WalletActions.setLocalCurrency, dispatch), setLocalCurrency: bindActionCreators(WalletActions.setLocalCurrency, dispatch),
setHideBalance: bindActionCreators(WalletActions.setHideBalance, dispatch),
}); });
export default injectIntl( export default injectIntl(

@ -2,21 +2,39 @@
import styled from 'styled-components'; import styled from 'styled-components';
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { Button, Link, Select, colors } from 'trezor-ui-components';
import Content from 'views/Wallet/components/Content';
import Content from 'views/Wallet/components/Content';
import {
Switch,
Select,
Link,
Button,
Tooltip,
Icon,
icons as ICONS,
colors,
} from 'trezor-ui-components';
import { FIAT_CURRENCIES } from 'config/app'; import { FIAT_CURRENCIES } from 'config/app';
import { FONT_SIZE } from 'config/variables'; import { FONT_SIZE } from 'config/variables';
import l10nCommonMessages from 'views/common.messages'; import l10nCommonMessages from 'views/common.messages';
import l10nMessages from './index.messages'; import l10nMessages from './index.messages';
import type { Props } from './Container'; import type { Props } from './Container';
const StyledContent = styled(Content)`
max-width: 800px;
`;
const CurrencySelect = styled(Select)` const CurrencySelect = styled(Select)`
min-width: 77px; min-width: 77px;
/* max-width: 200px; */
`; `;
const CurrencyLabel = styled.div` const Label = styled.div`
display: flex;
color: ${colors.TEXT_SECONDARY};
align-items: center;
`;
const LabelTop = styled.div`
color: ${colors.TEXT_SECONDARY}; color: ${colors.TEXT_SECONDARY};
padding-bottom: 10px; padding-bottom: 10px;
`; `;
@ -25,8 +43,15 @@ const Section = styled.div`
margin-bottom: 20px; margin-bottom: 20px;
`; `;
const Row = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
`;
const Actions = styled.div` const Actions = styled.div`
display: flex; display: flex;
margin-top: 40px;
`; `;
const Buttons = styled.div` const Buttons = styled.div`
@ -41,16 +66,20 @@ const Info = styled.div`
align-self: center; align-self: center;
`; `;
const TooltipIcon = styled(Icon)`
cursor: pointer;
`;
const buildCurrencyOption = currency => { const buildCurrencyOption = currency => {
return { value: currency, label: currency.toUpperCase() }; return { value: currency, label: currency.toUpperCase() };
}; };
const WalletSettings = (props: Props) => ( const WalletSettings = (props: Props) => (
<Content> <StyledContent>
<Section> <Section>
<CurrencyLabel> <LabelTop>
<FormattedMessage {...l10nMessages.TR_LOCAL_CURRENCY} /> <FormattedMessage {...l10nMessages.TR_LOCAL_CURRENCY} />
</CurrencyLabel> </LabelTop>
<CurrencySelect <CurrencySelect
isSearchable isSearchable
isClearable={false} isClearable={false}
@ -59,6 +88,26 @@ const WalletSettings = (props: Props) => (
options={FIAT_CURRENCIES.map(c => buildCurrencyOption(c))} options={FIAT_CURRENCIES.map(c => buildCurrencyOption(c))}
/> />
</Section> </Section>
<Section>
<Row>
<Label>
<FormattedMessage {...l10nCommonMessages.TR_HIDE_BALANCE} />
<Tooltip
content={<FormattedMessage {...l10nMessages.TR_HIDE_BALANCE_EXPLAINED} />}
maxWidth={210}
placement="right"
>
<TooltipIcon icon={ICONS.HELP} color={colors.TEXT_SECONDARY} size={24} />
</Tooltip>
</Label>
<Switch
onChange={checked => {
props.setHideBalance(checked);
}}
checked={props.wallet.hideBalance}
/>
</Row>
</Section>
<Actions> <Actions>
<Info> <Info>
<FormattedMessage {...l10nMessages.TR_THE_CHANGES_ARE_SAVED} /> <FormattedMessage {...l10nMessages.TR_THE_CHANGES_ARE_SAVED} />
@ -71,7 +120,7 @@ const WalletSettings = (props: Props) => (
</Link> </Link>
</Buttons> </Buttons>
</Actions> </Actions>
</Content> </StyledContent>
); );
export default WalletSettings; export default WalletSettings;

@ -7,6 +7,11 @@ const definedMessages: Messages = defineMessages({
id: 'TR_LOCAL_CURRENCY', id: 'TR_LOCAL_CURRENCY',
defaultMessage: 'Local currency', defaultMessage: 'Local currency',
}, },
TR_HIDE_BALANCE_EXPLAINED: {
id: 'TR_HIDE_BALANCE_EXPLAINED',
defaultMessage:
"Hides your account balance so you don't have to worry about anyone looking over your shoulder.",
},
TR_THE_CHANGES_ARE_SAVED: { TR_THE_CHANGES_ARE_SAVED: {
id: 'TR_THE_CHANGES_ARE_SAVED', id: 'TR_THE_CHANGES_ARE_SAVED',
defaultMessage: 'The changes are saved automatically as they are made', defaultMessage: 'The changes are saved automatically as they are made',

@ -70,6 +70,14 @@ const definedMessages: Messages = defineMessages({
id: 'TR_CLOSE', id: 'TR_CLOSE',
defaultMessage: 'Close', defaultMessage: 'Close',
}, },
TR_HIDE_BALANCE: {
id: 'TR_HIDE_BALANCE',
defaultMessage: 'Hide balance',
},
TR_THE_ACCOUNT_BALANCE_IS_HIDDEN: {
id: 'TR_THE_ACCOUNT_BALANCE_IS_HIDDEN',
defaultMessage: 'The account balance is hidden.',
},
}); });
export default definedMessages; export default definedMessages;

Before

Width:  |  Height:  |  Size: 730 KiB

After

Width:  |  Height:  |  Size: 730 KiB

Loading…
Cancel
Save