1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-13 20:08:56 +00:00

merge master

This commit is contained in:
slowbackspace 2019-02-01 09:50:41 +01:00
commit 879d92d930
48 changed files with 534 additions and 332 deletions

View File

@ -40,6 +40,8 @@ export type WalletAction = {
devices: Array<TrezorDevice>
} | {
type: typeof WALLET.SHOW_BETA_DISCLAIMER | typeof WALLET.HIDE_BETA_DISCLAIMER | typeof WALLET.SET_FIRST_LOCATION_CHANGE,
} | {
type: typeof WALLET.TOGGLE_SIDEBAR,
}
export const init = (): ThunkAction => (dispatch: Dispatch): void => {
@ -62,6 +64,10 @@ export const toggleDeviceDropdown = (opened: boolean): WalletAction => ({
opened,
});
export const toggleSidebar = (): WalletAction => ({
type: WALLET.TOGGLE_SIDEBAR,
});
// This method will be called after each DEVICE.CONNECT action
// if connected device has different "passphrase_protection" settings than saved instances
// all saved instances will be removed immediately inside DevicesReducer

View File

@ -10,4 +10,6 @@ export const UPDATE_SELECTED_DEVICE: 'wallet__update_selected_device' = 'wallet_
export const SHOW_BETA_DISCLAIMER: 'wallet__show_beta_disclaimer' = 'wallet__show_beta_disclaimer';
export const HIDE_BETA_DISCLAIMER: 'wallet__hide_beta_disclaimer' = 'wallet__hide_beta_disclaimer';
export const CLEAR_UNAVAILABLE_DEVICE_DATA: 'wallet__clear_unavailable_device_data' = 'wallet__clear_unavailable_device_data';
export const CLEAR_UNAVAILABLE_DEVICE_DATA: 'wallet__clear_unavailable_device_data' = 'wallet__clear_unavailable_device_data';
export const TOGGLE_SIDEBAR: 'wallet__toggle_sidebar' = 'wallet__toggle_sidebar';

View File

@ -0,0 +1,37 @@
import React from 'react';
import styled, { css } from 'styled-components';
import PropTypes from 'prop-types';
import { FADE_IN } from 'config/animations';
const StyledBackdrop = styled.div`
width: 100%;
height: 100%;
position: fixed;
z-index: 100;
left: 0;
top: 0;
background-color: rgba(0,0,0,0.5);
${props => props.animated && css`
animation: ${FADE_IN} 0.3s;
`};
`;
const Backdrop = ({
className,
show,
animated,
onClick,
}) => (
show ? <StyledBackdrop className={className} animated={animated} onClick={onClick} /> : null
);
Backdrop.propTypes = {
show: PropTypes.bool.isRequired,
className: PropTypes.string,
animated: PropTypes.bool,
onClick: PropTypes.func,
};
export default Backdrop;

View File

@ -18,8 +18,10 @@ const Wrapper = styled.div`
z-index: 10;
display: flex;
align-items: center;
padding: 0px 25px;
background: ${props => (props.disabled ? colors.GRAY_LIGHT : 'transparent')};
background: ${props => (props.isSelected ? colors.WHITE : 'transparent')};
cursor: pointer;
border-radius: 4px 0 0 0;
box-shadow: ${props => (props.disabled ? 'none' : '0 3px 8px rgba(0, 0, 0, 0.04)')};
@ -28,6 +30,10 @@ const Wrapper = styled.div`
box-shadow: none;
`}
${props => props.disabled && css`
cursor: default;
`}
${props => props.isHoverable && !props.disabled && css`
&:hover {
background: ${colors.GRAY_LIGHT};
@ -35,20 +41,6 @@ const Wrapper = styled.div`
`}
`;
const ClickWrapper = styled.div`
width: 100%;
display: flex;
padding-left: 25px;
padding-right: 25px;
height: 100%;
align-items: center;
cursor: pointer;
${props => props.disabled && css`
cursor: default;
`}
`;
const LabelWrapper = styled.div`
flex: 1 1 auto;
padding-left: 18px;
@ -115,23 +107,19 @@ const DeviceHeader = ({
isHoverable={isHoverable}
disabled={disabled}
className={className}
onClick={onClickWrapper}
>
<ClickWrapper
disabled={disabled}
onClick={onClickWrapper}
>
<ImageWrapper>
<Dot color={getStatusColor(status)} />
<TrezorImage model={getVersion(device)} />
</ImageWrapper>
<LabelWrapper>
<Name>{device.instanceLabel}</Name>
<Status title={getStatusName(status)}>{getStatusName(status)}</Status>
</LabelWrapper>
<IconWrapper>
{icon && !disabled && isAccessible && icon}
</IconWrapper>
</ClickWrapper>
<ImageWrapper>
<Dot color={getStatusColor(status)} />
<TrezorImage model={getVersion(device)} />
</ImageWrapper>
<LabelWrapper>
<Name>{device.instanceLabel}</Name>
<Status title={getStatusName(status)}>{getStatusName(status)}</Status>
</LabelWrapper>
<IconWrapper>
{icon && !disabled && isAccessible && icon}
</IconWrapper>
</Wrapper>
);
};

View File

@ -3,11 +3,15 @@ import React from 'react';
import styled from 'styled-components';
import { NavLink } from 'react-router-dom';
import colors from 'config/colors';
import { SCREEN_SIZE } from 'config/variables';
import type { toggleSidebar as toggleSidebarType } from 'actions/WalletActions';
const Wrapper = styled.header`
width: 100%;
height: 52px;
background: ${colors.HEADER};
overflow: hidden;
z-index: 200;
svg {
fill: ${colors.WHITE};
@ -31,12 +35,54 @@ const LayoutWrapper = styled.div`
`;
const Left = styled.div`
flex: 1;
display: flex;
justify-content: flex-start;
display: none;
flex: 0 0 33%;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
display: initial;
}
`;
const Right = styled.div``;
const MenuToggler = styled.div`
display: none;
white-space: nowrap;
color: ${colors.WHITE};
align-self: center;
cursor: pointer;
user-select: none;
padding: 10px 0px;
transition: all .1s ease-in;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
display: initial;
}
`;
const Logo = styled.div`
flex: 1;
justify-content: flex-start;
display: flex;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
flex: 1 0 33%;
justify-content: center;
}
`;
const MenuLinks = styled.div`
flex: 0;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
flex: 0 1 33%;
}
`;
const Projects = styled.div`
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
display: none;
}
`;
const A = styled.a`
color: ${colors.WHITE};
@ -58,10 +104,20 @@ const A = styled.a`
}
`;
const Header = (): React$Element<string> => (
type Props = {
sidebarEnabled?: boolean,
sidebarOpened?: boolean,
toggleSidebar?: toggleSidebarType,
};
const Header = ({ sidebarEnabled, sidebarOpened, toggleSidebar }: Props) => (
<Wrapper>
<LayoutWrapper>
<Left>
{ sidebarEnabled && <MenuToggler onClick={toggleSidebar}>{sidebarOpened ? '✕ Close' : '☰ Menu'}</MenuToggler>}
</Left>
<Logo>
<NavLink to="/">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 163.7 41.9" width="100%" height="100%" preserveAspectRatio="xMinYMin meet">
<polygon points="101.1,12.8 118.2,12.8 118.2,17.3 108.9,29.9 118.2,29.9 118.2,35.2 101.1,35.2 101.1,30.7 110.4,18.1 101.1,18.1" />
@ -73,13 +129,15 @@ const Header = (): React$Element<string> => (
<polygon points="40.5,12.8 58.6,12.8 58.6,18.1 52.4,18.1 52.4,35.2 46.6,35.2 46.6,18.1 40.5,18.1 " />
</svg>
</NavLink>
</Left>
<Right>
<A href="https://trezor.io/" target="_blank" rel="noreferrer noopener">Trezor</A>
<A href="https://wiki.trezor.io/" target="_blank" rel="noreferrer noopener">Wiki</A>
<A href="https://blog.trezor.io/" target="_blank" rel="noreferrer noopener">Blog</A>
<A href="https://trezor.io/support/" target="_blank" rel="noreferrer noopener">Support</A>
</Right>
</Logo>
<MenuLinks>
<Projects>
<A href="https://trezor.io/" target="_blank" rel="noreferrer noopener">Trezor</A>
<A href="https://wiki.trezor.io/" target="_blank" rel="noreferrer noopener">Wiki</A>
<A href="https://blog.trezor.io/" target="_blank" rel="noreferrer noopener">Blog</A>
<A href="https://trezor.io/support/" target="_blank" rel="noreferrer noopener">Support</A>
</Projects>
</MenuLinks>
</LayoutWrapper>
</Wrapper>
);

View File

@ -12,10 +12,12 @@ const A = styled.a`
font-size: ${FONT_SIZE.SMALL};
${props => props.isGreen && css`
border-bottom: 1px solid ${colors.GREEN_PRIMARY};
text-decoration: underline;
text-decoration-color: ${colors.GREEN_PRIMARY};
`}
${props => props.isGray && css`
border-bottom: 1px solid ${colors.TEXT_SECONDARY};
text-decoration: underline;
text-decoration-color: ${colors.TEXT_SECONDARY};
`}
&,

View File

@ -8,7 +8,9 @@ import colors from 'config/colors';
import { WHITE_COLOR } from 'config/animations';
import { getPrimaryColor } from 'utils/notification';
import Loader from 'components/Loader';
import { TRANSITION, FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import {
TRANSITION, FONT_SIZE, FONT_WEIGHT, SCREEN_SIZE,
} from 'config/variables';
type Props = {
type: string;
@ -48,6 +50,10 @@ const Wrapper = styled.button`
border: 1px solid ${props => getPrimaryColor(props.type)};
transition: ${TRANSITION.HOVER};
@media screen and (max-width: ${SCREEN_SIZE.SM}){
padding: 12px 24px;
}
&:hover {
color: ${colors.WHITE};
background: ${props => getPrimaryColor(props.type)};

View File

@ -0,0 +1,74 @@
/* @flow */
import React from 'react';
import PropTypes from 'prop-types';
import COLORS from 'config/colors';
import ICONS from 'config/icons';
import styled from 'styled-components';
import type { TrezorDevice } from 'flowtype';
type Props = {
device: TrezorDevice,
size?: number,
color?: string,
hoverColor?: string,
onClick?: any,
}
const SvgWrapper = styled.svg`
:hover {
path {
fill: ${props => props.hoverColor}
}
}
`;
const Path = styled.path`
fill: ${props => props.color};
`;
const getDeviceIcon = (majorVersion: number) => {
switch (majorVersion) {
case 1:
return ICONS.T1;
case 2:
return ICONS.T2;
default:
return ICONS.T2;
}
};
const DeviceIcon = ({
device,
size = 32,
color = COLORS.TEXT_SECONDARY,
hoverColor,
onClick,
}: Props) => {
const majorVersion = device.features ? device.features.major_version : 2;
return (
<SvgWrapper
hoverColor={hoverColor}
width={`${size}`}
height={`${size}`}
viewBox="0 0 1024 1024"
onClick={onClick}
>
<Path
key={majorVersion}
color={color}
d={getDeviceIcon(majorVersion)}
/>
</SvgWrapper>
);
};
DeviceIcon.propTypes = {
device: PropTypes.object,
size: PropTypes.number,
color: PropTypes.string,
hoverColor: PropTypes.string,
onClick: PropTypes.func,
};
export default DeviceIcon;

View File

@ -1,10 +1,15 @@
/* @flow */
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { H3 } from 'components/Heading';
import ICONS from 'config/icons';
import Icon from 'components/Icon';
import DeviceIcon from 'components/images/DeviceIcon';
import type { TrezorDevice } from 'flowtype';
type Props = {
device: TrezorDevice;
}
const Wrapper = styled.div``;
@ -12,13 +17,18 @@ const Header = styled.div`
padding: 48px;
`;
const ConfirmAction = () => (
const ConfirmAction = (props: Props) => (
<Wrapper>
<Header>
<Icon icon={ICONS.T1} size={100} />
<DeviceIcon device={props.device} size={100} />
<H3>Confirm action on your Trezor</H3>
</Header>
</Wrapper>
);
ConfirmAction.propTypes = {
device: PropTypes.object.isRequired,
};
export default ConfirmAction;

View File

@ -13,7 +13,7 @@ import P from 'components/Paragraph';
import type { Props } from '../../Container';
const Wrapper = styled.div`
width: 390px;
max-width: 390px;
`;
const Header = styled.div`

View File

@ -4,12 +4,11 @@ import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import icons from 'config/icons';
import colors from 'config/colors';
import { LINE_HEIGHT, FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import P from 'components/Paragraph';
import Icon from 'components/Icon';
import DeviceIcon from 'components/images/DeviceIcon';
import { H3 } from 'components/Heading';
import type { TrezorDevice, State } from 'flowtype';
@ -20,7 +19,7 @@ type Props = {
}
const Wrapper = styled.div`
width: 390px;
max-width: 390px;
`;
const Header = styled.div`
@ -71,7 +70,7 @@ const ConfirmSignTx = (props: Props) => {
return (
<Wrapper>
<Header>
<Icon icon={icons.T1} size={60} color={colors.TEXT_SECONDARY} />
<DeviceIcon device={props.device} size={60} color={colors.TEXT_SECONDARY} />
<H3>Confirm transaction on { props.device.label } device</H3>
<P isSmaller>Details are shown on display</P>
</Header>

View File

@ -30,7 +30,7 @@ const StyledLink = styled(Link)`
`;
const Wrapper = styled.div`
width: 370px;
max-width: 370px;
padding: 30px 48px;
`;

View File

@ -25,7 +25,6 @@ type Props = {
}
const Wrapper = styled.div`
width: 360px;
`;
const Header = styled.div`

View File

@ -96,11 +96,11 @@ const getDeviceContextModal = (props: Props) => {
}
case 'ButtonRequest_ProtectCall':
return <ConfirmAction />;
return <ConfirmAction device={modal.device} />;
case 'ButtonRequest_Other':
case 'ButtonRequest_ConfirmOutput':
return <ConfirmAction />;
return <ConfirmAction device={modal.device} />;
case RECEIVE.REQUEST_UNVERIFIED:
return (

View File

@ -4,10 +4,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import icons from 'config/icons';
import colors from 'config/colors';
import Icon from 'components/Icon';
import DeviceIcon from 'components/images/DeviceIcon';
import { H3 } from 'components/Heading';
import P from 'components/Paragraph';
@ -18,7 +17,7 @@ type Props = {
}
const Wrapper = styled.div`
width: 360px;
max-width: 360px;
padding: 30px 48px;
`;
@ -27,7 +26,7 @@ const Header = styled.div``;
const PassphraseType = (props: Props) => (
<Wrapper>
<Header>
<Icon icon={icons.T1} size={60} color={colors.TEXT_SECONDARY} />
<DeviceIcon device={props.device} size={60} color={colors.TEXT_SECONDARY} />
<H3>Complete the action on { props.device.label } device</H3>
<P isSmaller>If you enter a wrong passphrase, you will not unlock the desired hidden wallet.</P>
</Header>

View File

@ -4,7 +4,7 @@ import * as React from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import colors from 'config/colors';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import { FONT_SIZE, FONT_WEIGHT, SCREEN_SIZE } from 'config/variables';
type Props = {
onClick: () => void;
@ -24,6 +24,11 @@ const Wrapper = styled.button`
transition: all 0.3s;
cursor: pointer;
@media screen and (max-width: ${SCREEN_SIZE.XS}) {
width: 50px;
height: 50px;
}
&:first-child {
margin-left: 0px;
}

View File

@ -80,4 +80,22 @@ export const SLIDE_DOWN = keyframes`
100% {
transform: translateY(0%);
}
`;
export const SLIDE_RIGHT = keyframes`
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(0%);
}
`;
export const SLIDE_LEFT = keyframes`
0% {
transform: translateX(0%);
}
100% {
transform: translateX(-100%);
}
`;

View File

@ -24,6 +24,9 @@ export default {
T1: [
'M603.2 265.6h-6.4c-25.494-5.341-54.79-8.398-84.8-8.398s-59.305 3.058-87.592 8.879l2.792-0.48h-6.72c-30.053 5.643-52.489 31.68-52.489 62.956 0 0.367 0.003 0.733 0.009 1.099l-0.001-0.055v234.88c0.075 40.921 11.238 79.22 30.643 112.071l-0.563-1.031 35.2 60.48c11.655 19.297 32.515 32.001 56.342 32.001 0.105 0 0.209 0 0.314-0.001h44.144c0.359 0.007 0.783 0.011 1.208 0.011 23.569 0 44.162-12.74 55.269-31.709l0.164-0.302 36.16-64c18.232-31.447 29.027-69.173 29.12-109.413v-232.987c0.005-0.293 0.008-0.639 0.008-0.986 0-31.391-22.599-57.503-52.416-62.954l-0.392-0.059zM629.76 563.2c-0.193 35.364-9.792 68.446-26.418 96.923l0.498-0.923-35.84 64c-6.868 11.865-19.463 19.742-33.906 19.84h-44.174c-0.073 0-0.159 0.001-0.246 0.001-14.427 0-27.041-7.762-33.894-19.338l-0.1-0.183-34.88-59.84c-16.656-28.155-26.515-62.042-26.56-98.227v-235.853c0.133-19.025 13.742-34.833 31.751-38.359l0.249-0.041h6.72c24.050-5.126 51.682-8.062 80-8.062s55.949 2.936 82.608 8.519l-2.608-0.457h6.72c18.258 3.568 31.867 19.375 32 38.386v0.014zM422.4 353.92h179.2c3.535 0 6.4 2.865 6.4 6.4v99.2c0 3.535-2.865 6.4-6.4 6.4h-179.2c-3.535 0-6.4-2.865-6.4-6.4v-99.2c0-3.535 2.865-6.4 6.4-6.4z',
],
T2: [
'M 625.28 546.304 c 0 4.512 -3.84 8 -8.32 8 l -209.92 0 c -4.48 0 -8.32 -3.488 -8.32 -8 l 0 -202.208 c 0 -4.512 3.84 -8.32 8.32 -8.32 l 209.92 0 c 4.48 0 8.32 3.808 8.32 8.32 l 0 202.208 Z m 18.56 -304.32 l -263.68 0 c -23.04 0 -41.92 18.56 -41.92 41.28 l 0 233.952 c 0 55.04 16 108.768 46.72 155.168 l 64.64 96.992 c 5.12 8 13.76 12.448 23.36 12.448 l 78.4 0 c 9.28 0 17.92 -4.448 23.04 -11.84 l 60.16 -86.048 c 33.6 -47.68 51.2 -103.392 51.2 -161.28 l 0 -239.392 c 0 -22.72 -18.88 -41.28 -41.92 -41.28',
],
COG: [
'M739.552 462.144h-71.328c-4.256-13.664-10.208-26.56-17.472-38.56l47.264-47.424c11.2-11.008 11.2-29.056 0-40.192l-20.064-20.032c-11.136-11.104-29.152-11.040-40.192 0l-48.128 48.032c-12.992-7.392-27.072-13.152-42.080-16.992v-62.496c0-15.68-12.672-28.48-28.448-28.48h-28.448c-15.68 0-28.416 12.8-28.416 28.48v62.464c-16.352 4.128-31.68 10.656-45.728 19.2l-40.288-40.224c-11.072-11.040-29.184-11.104-40.288 0l-20.096 20.096c-11.104 11.072-10.976 29.152 0.064 40.288l40.992 40.992c-8.672 15.136-15.168 31.648-18.88 49.152h-53.504c-15.776 0-28.544 12.736-28.544 28.48v28.416c0 15.68 12.768 28.416 28.544 28.416h57.152c5.184 17.152 12.992 32.928 23.008 47.328l-38.656 38.656c-11.136 11.136-11.136 29.216-0.064 40.288l20.064 20.096c11.2 11.040 29.248 11.040 40.32-0.032l43.232-43.2c14.528 7.232 30.336 12.48 46.944 15.2v59.488c0 15.68 12.736 28.448 28.448 28.48h28.448c15.68-0.032 28.448-12.8 28.448-28.48v-66.816c14.336-5.088 27.904-11.872 40.224-20.544l45.76 45.888c11.104 11.072 29.12 11.072 40.224 0l20.096-20.128c11.168-11.072 11.168-29.056-0.096-40.288l-50.144-50.24c6.144-12.512 10.944-25.792 13.92-39.904h67.776c15.744 0 28.448-12.672 28.48-28.448v-28.448c-0.096-15.68-12.8-28.512-28.544-28.512zM504.928 583.072c-39.264 0-71.072-31.776-71.072-71.104 0-39.264 31.808-71.040 71.072-71.040 39.296 0 71.136 31.776 71.136 71.040 0 39.328-31.84 71.104-71.136 71.104z',
],

View File

@ -1,3 +1,15 @@
// Bootstrap 3 breakpoints
/* XS - Extra Small Devices, Phones */
/* SM - Small Devices, Tablets */
/* MD - Medium Devices, Desktops */
/* LG - Large Devices, Wide Screens */
export const SCREEN_SIZE = {
XS: '480px',
SM: '768px',
MD: '992px',
LG: '1170px',
};
// OLD UNITS
// SMALLEST: '10px',
// SMALLER: '12px',
@ -13,7 +25,6 @@
// H3: '14px',
// H4: '12px',
// COUNTER: '11px',
export const FONT_SIZE = {
SMALL: '0.8571rem',
BASE: '1rem',

View File

@ -6,6 +6,7 @@ import { DEVICE, TRANSPORT } from 'trezor-connect';
import * as MODAL from 'actions/constants/modal';
import * as WALLET from 'actions/constants/wallet';
import * as CONNECT from 'actions/constants/TrezorConnect';
import * as ACCOUNT from 'actions/constants/account';
import type { Action, RouterLocationState, TrezorDevice } from 'flowtype';
@ -14,6 +15,7 @@ type State = {
online: boolean;
dropdownOpened: boolean;
showBetaDisclaimer: boolean;
showSidebar: boolean;
initialParams: ?RouterLocationState;
initialPathname: ?string;
firstLocationChange: boolean;
@ -27,6 +29,7 @@ const initialState: State = {
dropdownOpened: false,
firstLocationChange: true,
showBetaDisclaimer: false,
showSidebar: true,
initialParams: null,
initialPathname: null,
disconnectRequest: null,
@ -71,6 +74,11 @@ export default function wallet(state: State = initialState, action: Action): Sta
...state,
dropdownOpened: false,
};
case ACCOUNT.UPDATE_SELECTED_ACCOUNT:
return {
...state,
showSidebar: false,
};
case CONNECT.DISCONNECT_REQUEST:
return {
@ -94,6 +102,12 @@ export default function wallet(state: State = initialState, action: Action): Sta
selectedDevice: action.device,
};
case WALLET.TOGGLE_SIDEBAR:
return {
...state,
showSidebar: !state.showSidebar,
};
case WALLET.SHOW_BETA_DISCLAIMER:
return {
...state,

View File

@ -8,7 +8,7 @@ import animationStyles from './Animations';
const baseStyles = createGlobalStyle`
html, body {
width: 100%;
height: 100%;
min-height: 100vh;
position: relative;
font-family: "Roboto", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
font-weight: ${FONT_WEIGHT.NORMAL};
@ -43,7 +43,7 @@ const baseStyles = createGlobalStyle`
}
#trezor-wallet-root {
height: 100%;
min-height: 100vh;
}
${animationStyles};

View File

@ -8,7 +8,9 @@ import { H2 } from 'components/Heading';
import ChromeImage from 'images/browser-chrome.png';
import FirefoxImage from 'images/browser-firefox.png';
const Wrapper = styled.div``;
const Wrapper = styled.div`
padding: 24px 0px;
`;
const ChooseBrowserWrapper = styled.div`
display: flex;

View File

@ -8,7 +8,7 @@ import Button from 'components/Button';
import { H2 } from 'components/Heading';
import { PULSATE } from 'config/animations';
import colors from 'config/colors';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import { FONT_SIZE, FONT_WEIGHT, SCREEN_SIZE } from 'config/variables';
import CaseImage from 'images/macbook.png';
import Link from 'components/Link';
@ -18,31 +18,50 @@ type Props = {
showDisconnect: boolean,
};
const StyledConnectDevice = styled.div`
padding: 0px 48px;
`;
const Title = styled.div`
margin-top: 60px;
`;
const Wrapper = styled.div`
display: flex;
justify-content: space-around;
align-items: center;
width: 400px;
margin: 0 auto;
padding: 36px 0;
justify-content: center;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
align-content: center;
flex-direction: column;
}
`;
const ConnectTrezorWrapper = styled.div`
position: relative;
top: 1px;
margin: 15px 15px 0px 15px;
animation: ${PULSATE} 1.3s ease-out infinite;
color: ${colors.GREEN_PRIMARY};
font-size: ${FONT_SIZE.BIG};
font-weight: ${FONT_WEIGHT.MEDIUM};
`;
const StyledP = styled(P)`
line-height: auto;
margin: 15px 15px 0px 15px;
`;
const StyledButton = styled(Button)`
margin: 15px 15px 5px 15px;
`;
const Image = styled.img`
width: 777px;
min-height: 500px;
width: 100%;
max-width: 777px;
height: auto;
margin: auto;
background-repeat: no-repeat;
background-position: center 0px;
@ -105,7 +124,7 @@ class ConnectDevice extends PureComponent<Props> {
render() {
return (
<div>
<StyledConnectDevice>
<Title>
<H2 claim>The private bank in your hands.</H2>
<P>Trezor Wallet is an easy-to-use interface for your Trezor.</P>
@ -124,10 +143,10 @@ class ConnectDevice extends PureComponent<Props> {
</ConnectTrezorWrapper>
{this.props.showWebUsb && !this.props.showDisconnect && (
<React.Fragment>
<P>and</P>
<Button isWebUsb>
<StyledP>and</StyledP>
<StyledButton isWebUsb>
Check for devices
</Button>
</StyledButton>
</React.Fragment>
)}
</Wrapper>
@ -156,7 +175,7 @@ class ConnectDevice extends PureComponent<Props> {
</StyledLink>
</P>
</Footer>
</div>
</StyledConnectDevice>
);
}
}

View File

@ -5,7 +5,6 @@ import styled from 'styled-components';
import Notification from 'components/Notification';
const Wrapper = styled.div`
min-width: 720px;
width: 100%;
`;

View File

@ -18,8 +18,7 @@ type Props = {
}
const Wrapper = styled.div`
min-height: 100%;
min-width: 720px;
min-height: 100vh;
display: flex;
flex-direction: column;

View File

@ -13,7 +13,6 @@ import Button from 'components/Button';
import LandingWrapper from 'views/Landing/components/LandingWrapper';
const Wrapper = styled.div`
min-width: 720px;
width: 100%;
display: flex;
flex-direction: column;

View File

@ -6,7 +6,7 @@ import colors from 'config/colors';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import { Select } from 'components/Select';
import Link from 'components/Link';
import { H1 } from 'components/Heading';
import { H1, H2 } from 'components/Heading';
import Button from 'components/Button';
import P from 'components/Paragraph';
import Icon from 'components/Icon';
@ -42,6 +42,7 @@ const Wrapper = styled.div`
justify-content: center;
align-items: center;
max-width: 500px;
padding: 0 24px;
`;
const Top = styled.div`
@ -62,6 +63,7 @@ const TitleHeader = styled(H1)`
font-size: ${FONT_SIZE.HUGE};
justify-content: center;
align-items: center;
flex-wrap: wrap;
`;
const Version = styled.span`
@ -81,12 +83,15 @@ const LearnMoreText = styled.span`
const SelectWrapper = styled(Select)`
margin-right: 10px;
width: 180px;
margin-bottom: 5px;
`;
const Download = styled.div`
margin: 24px auto;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;
`;
const DownloadBridgeButton = styled(Button)`
@ -94,6 +99,7 @@ const DownloadBridgeButton = styled(Button)`
padding-bottom: 5px;
display: flex;
align-items: center;
margin-bottom: 5px;
`;
const GoBack = styled.span`
@ -110,7 +116,7 @@ const Ol = styled.ul`
margin: 0 auto;
color: ${colors.TEXT_SECONDARY};
font-size: ${FONT_SIZE.BIG};
padding: 10px 0 15px 25px;
padding: 0px 0 15px 25px;
text-align: left;
`;
@ -175,6 +181,7 @@ class InstallBridge extends PureComponent<Props, State> {
</DownloadBridgeButton>
</Link>
</Download>
<H2>Changelog</H2>
<Ol>
{this.props.transport.bridge.changelog.map(entry => (
<Li key={entry}>{entry}</Li>

View File

@ -4,7 +4,7 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import Loader from 'components/Loader';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import { FONT_SIZE, FONT_WEIGHT, SCREEN_SIZE } from 'config/variables';
import { H1 } from 'components/Heading';
import P from 'components/Paragraph';
import colors from 'config/colors';
@ -26,6 +26,10 @@ const Wrapper = styled.div`
flex: 1;
flex-direction: column;
padding: 40px 35px 40px 35px;
@media screen and (max-width: ${SCREEN_SIZE.SM}){
padding: 20px 35px;
}
`;
const Loading = styled.div`
@ -41,6 +45,7 @@ const Title = styled(H1)`
font-weight: ${FONT_WEIGHT.NORMAL};
color: ${props => (props.type === 'progress' ? colors.TEXT_SECONDARY : '')};
margin-left: 10px;
text-align: center;
`;
const Message = styled(P)`

View File

@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import Icon from 'components/Icon';
import DeviceIcon from 'components/images/DeviceIcon';
import icons from 'config/icons';
import colors from 'config/colors';
@ -9,7 +10,6 @@ import { FONT_SIZE } from 'config/variables';
const Wrapper = styled.div`
background: ${colors.WHITE};
box-shadow: 0 3px 8px rgba(0,0,0,0.06);
`;
const Item = styled.div`
@ -74,7 +74,7 @@ class MenuItems extends PureComponent {
<Item
onClick={() => this.props.acquireDevice()}
>
<Icon icon={icons.T1} size={25} color={colors.TEXT_SECONDARY} />
<DeviceIcon device={this.props.device} size={25} color={colors.TEXT_SECONDARY} />
<Label>Renew session</Label>
</Item>
)}

View File

@ -18,6 +18,7 @@ import Divider from '../Divider';
const Wrapper = styled.div`
position: absolute;
z-index: 1;
width: 100%;
padding-bottom: 8px;
border-bottom: 1px solid #E3E3E3;

View File

@ -0,0 +1,60 @@
/* @flow */
import * as React from 'react';
import styled from 'styled-components';
import colors from 'config/colors';
import { SCREEN_SIZE } from 'config/variables';
import { SLIDE_RIGHT, SLIDE_LEFT } from 'config/animations';
type Props = {
children?: React.Node,
isOpen: boolean,
}
type State = {
footerFixed: boolean,
}
const AbsoluteWrapper = styled.aside`
width: 320px;
position: relative;
overflow-y: auto;
background: ${colors.MAIN};
border-top-left-radius: 4px;
border-right: 1px solid ${colors.DIVIDER};
overflow-x: hidden;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
position: absolute;
height: calc(100vh - 52px);
z-index: 200;
top: 52px;
animation: ${props => (props.isOpen ? SLIDE_RIGHT : SLIDE_LEFT)} 0.25s cubic-bezier(0.17, 0.04, 0.03, 0.94) forwards;
}
@media screen and (max-width: ${SCREEN_SIZE.LG}) {
border-top-left-radius: 0px;
}
`;
const SidebarWrapper = styled.div`
height: 100%;
display: flex;
flex-direction: column;
`;
export default class Sidebar extends React.PureComponent<Props, State> {
render() {
return (
<AbsoluteWrapper isOpen={this.props.isOpen}>
<SidebarWrapper>
{this.props.children}
</SidebarWrapper>
</AbsoluteWrapper>
);
}
}

View File

@ -1,189 +0,0 @@
/* @flow */
import * as React from 'react';
import raf from 'raf';
import { getViewportHeight, getScrollX, getScrollY } from 'utils/windowUtils';
import styled from 'styled-components';
import colors from 'config/colors';
type Props = {
children?: React.Node,
}
type State = {
prevScrollY: number;
asideMinHeight: number,
wrapperTopOffset: number,
wrapperLeftOffset: number,
wrapperBottomPadding: number,
footerFixed: boolean,
}
const AsideWrapper = styled.aside.attrs(props => ({
style: { minHeight: props.minHeight },
}))`
position: relative;
top: 0px;
width: 320px;
min-width: 320px;
overflow: hidden;
background: ${colors.MAIN};
border-right: 1px solid ${colors.DIVIDER};
border-top-left-radius: 4px;
@media screen and (max-width: 1170px) {
border-top-left-radius: 0px;
}
`;
const StickyContainerWrapper = styled.div.attrs(props => ({
style: {
top: props.top,
left: props.left,
paddingBottom: props.paddingBottom,
},
}))`
position: fixed;
border-right: 1px solid ${colors.DIVIDER};
width: 320px;
overflow: hidden;
`;
export default class StickyContainer extends React.PureComponent<Props, State> {
constructor() {
super();
this.state = {
prevScrollY: 0,
asideMinHeight: 0,
wrapperTopOffset: 0,
wrapperLeftOffset: 0,
wrapperBottomPadding: 0,
footerFixed: false,
};
}
componentDidMount() {
window.addEventListener('scroll', this.handleScroll);
window.addEventListener('resize', this.handleScroll);
this.update();
}
componentDidUpdate(prevProps: Props, newState: State) {
// recalculate view only if props was changed
// ignore when state is changed
if (this.state === newState) raf(this.update);
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll);
window.removeEventListener('resize', this.handleScroll);
}
update = () => {
this.recalculatePosition();
}
handleScroll = () => raf(this.update);
asideRefCallback = (element: ?HTMLElement) => {
this.aside = element;
}
wrapperRefCallback = (element: ?HTMLElement) => {
this.wrapper = element;
}
footerRefCallback = (element: ?HTMLElement) => {
this.footer = element;
}
aside: ?HTMLElement;
wrapper: ?HTMLElement;
footer: ?HTMLElement;
recalculatePosition() {
const { aside, wrapper, footer } = this;
if (!aside || !wrapper || !footer) return;
const viewportHeight = getViewportHeight();
const asideBounds = aside.getBoundingClientRect();
const wrapperBounds = wrapper.getBoundingClientRect();
const footerBounds = footer.getBoundingClientRect();
const isHeaderFixed = asideBounds.top < 0;
const isWrapperBiggerThanViewport = wrapperBounds.height > viewportHeight;
const state = { ...this.state };
const scrollX = getScrollX();
const scrollY = getScrollY();
if (isHeaderFixed) {
if (isWrapperBiggerThanViewport) {
const scrollDirection = scrollY >= state.prevScrollY ? 'down' : 'up';
const topOutOfBounds: boolean = (wrapperBounds.top > 0 && scrollDirection === 'up');
const bottomOutOfBounds: boolean = (footerBounds.bottom <= viewportHeight && scrollDirection === 'down');
if (!topOutOfBounds && !bottomOutOfBounds) {
// neither "top" or "bottom" was reached
// scroll whole wrapper
const distanceScrolled = Math.abs(scrollY - state.prevScrollY);
state.wrapperTopOffset += scrollDirection === 'down' ? -distanceScrolled : distanceScrolled;
}
}
// make sure that wrapper will not be over scrolled
if (state.wrapperTopOffset > 0) state.wrapperTopOffset = 0;
const maxScrollTop = viewportHeight - wrapperBounds.height;
if (maxScrollTop < 0 && state.wrapperTopOffset < maxScrollTop) state.wrapperTopOffset = maxScrollTop;
} else {
// update wrapper "top" to be same as "aside" element
state.wrapperTopOffset = asideBounds.top;
}
if (isWrapperBiggerThanViewport) {
state.footerFixed = false;
} else if (state.footerFixed) {
if (footerBounds.top < wrapperBounds.bottom - footerBounds.height) {
state.footerFixed = false;
}
} else if (footerBounds.bottom < viewportHeight) {
state.footerFixed = asideBounds.height > wrapperBounds.height;
}
state.prevScrollY = scrollY;
state.asideMinHeight = wrapperBounds.height;
state.wrapperBottomPadding = state.footerFixed ? footerBounds.height : 0;
// update wrapper "left" position
state.wrapperLeftOffset = scrollX > 0 ? -scrollX : asideBounds.left;
this.setState(state);
}
render() {
return (
<AsideWrapper
footerFixed={this.state.footerFixed}
minHeight={this.state.asideMinHeight}
ref={this.asideRefCallback}
onScroll={this.handleScroll}
onTouchStart={this.handleScroll}
onTouchMove={this.handleScroll}
onTouchEnd={this.handleScroll}
>
<StickyContainerWrapper
paddingBottom={this.state.wrapperBottomPadding}
top={this.state.wrapperTopOffset}
left={this.state.wrapperLeftOffset}
ref={this.wrapperRefCallback}
>
{React.Children.map(this.props.children, (child) => { // eslint-disable-line arrow-body-style
return child.key === 'sticky-footer' ? React.cloneElement(child, {
ref: this.footerRefCallback,
position: this.state.footerFixed ? 'fixed' : 'relative',
}) : child;
})}
</StickyContainerWrapper>
</AsideWrapper>
);
}
}

View File

@ -16,12 +16,13 @@ import Tooltip from 'components/Tooltip';
import AccountMenu from './components/AccountMenu';
import CoinMenu from './components/CoinMenu';
import DeviceMenu from './components/DeviceMenu';
import StickyContainer from './components/StickyContainer';
import Sidebar from './components/Sidebar';
import type { Props } from './components/common';
const Header = styled(DeviceHeader)`
border-right: 1px solid ${colors.BACKGROUND};
flex: 0 0 auto;
`;
const WalletTypeIconWrapper = styled.div`
@ -60,6 +61,7 @@ const Footer = styled.div.attrs(props => ({
`;
const Body = styled.div`
flex: 1 0 auto;
width: 320px;
min-height: ${props => (props.minHeight ? `${props.minHeight}px` : '0px')};
`;
@ -219,10 +221,7 @@ class LeftNavigation extends React.PureComponent<Props, State> {
}
return (
<StickyContainer
location={props.router.location.pathname}
deviceSelection={this.props.wallet.dropdownOpened}
>
<Sidebar isOpen={props.wallet.showSidebar}>
<Header
isSelected
isHoverable={false}
@ -295,7 +294,7 @@ class LeftNavigation extends React.PureComponent<Props, State> {
</A>
</Help>
</Footer>
</StickyContainer>
</Sidebar>
);
}
}

View File

@ -2,7 +2,7 @@
import styled from 'styled-components';
import React from 'react';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import { FONT_SIZE, FONT_WEIGHT, SCREEN_SIZE } from 'config/variables';
import { NavLink } from 'react-router-dom';
import { connect } from 'react-redux';
import colors from 'config/colors';
@ -24,6 +24,14 @@ const Wrapper = styled.div`
padding: 0px 30px 0 35px;
overflow-y: hidden;
overflow-x: auto;
@media screen and (max-width: ${SCREEN_SIZE.MD}) {
justify-content: space-between;
}
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
padding: 0px 16px;
}
`;
const StyledNavLink = styled(NavLink)`
@ -34,6 +42,15 @@ const StyledNavLink = styled(NavLink)`
padding: 20px 35px;
white-space: nowrap;
@media screen and (max-width: ${SCREEN_SIZE.MD}) {
padding: 20px 10px;
}
@media screen and (max-width: ${SCREEN_SIZE.XS}) {
font-size: ${FONT_SIZE.BASE};
padding: 20px 10px;
}
&.active,
&:hover {
transition: all 0.3s ease-in-out;

View File

@ -2,39 +2,48 @@
import * as React from 'react';
import colors from 'config/colors';
import styled from 'styled-components';
import styled, { css } from 'styled-components';
import { connect } from 'react-redux';
import { Route, withRouter } from 'react-router-dom';
import type { MapStateToProps } from 'react-redux';
import type { MapStateToProps, MapDispatchToProps } from 'react-redux';
import type { State } from 'flowtype';
import type { WalletAction } from 'actions/WalletActions';
import { toggleSidebar } from 'actions/WalletActions';
import { bindActionCreators } from 'redux';
import Header from 'components/Header';
import Footer from 'components/Footer';
import ModalContainer from 'components/modals/Container';
import AppNotifications from 'components/notifications/App';
import ContextNotifications from 'components/notifications/Context';
import { SCREEN_SIZE } from 'config/variables';
import Log from 'components/Log';
import Backdrop from 'components/Backdrop';
import LeftNavigation from './components/LeftNavigation/Container';
import TopNavigationAccount from './components/TopNavigationAccount';
import TopNavigationDeviceSettings from './components/TopNavigationDeviceSettings';
type WalletContainerProps = {
type StateProps = {
wallet: $ElementType<State, 'wallet'>,
children?: React.Node
children?: React.Node,
}
// type ContentProps = {
// children?: React.Node
// }
type DispatchProps = {
toggleSidebar: WalletAction,
};
type OwnProps = {};
export type Props = StateProps & DispatchProps;
const AppWrapper = styled.div`
position: relative;
min-height: 100%;
min-width: 720px;
min-height: 100vh;
display: flex;
flex-direction: column;
background: ${colors.BACKGROUND};
@ -67,7 +76,15 @@ const MainContent = styled.article`
flex-direction: column;
overflow: auto;
border-top-right-radius: 4px;
@media screen and (max-width: ${SCREEN_SIZE.SM}){
${props => props.preventBgScroll && css`
position: fixed;
width: 100%;
min-height: calc(100vh - 52px);
`}
}
@media screen and (max-width: 1170px) {
border-top-right-radius: 0px;
}
@ -87,13 +104,22 @@ const Body = styled.div`
flex-direction: column;
`;
const Wallet = (props: WalletContainerProps) => (
const StyledBackdrop = styled(Backdrop)`
display: none;
@media screen and (max-width: ${SCREEN_SIZE.SM}) {
display: initial;
}
`;
const Wallet = (props: Props) => (
<AppWrapper>
<Header />
<Header sidebarEnabled={!!props.wallet.selectedDevice} sidebarOpened={props.wallet.showSidebar} toggleSidebar={props.toggleSidebar} />
<AppNotifications />
<WalletWrapper>
<StyledBackdrop show={props.wallet.showSidebar} onClick={props.toggleSidebar} animated />
{props.wallet.selectedDevice && <LeftNavigation />}
<MainContent>
<MainContent preventBgScroll={props.wallet.showSidebar}>
<Navigation>
<Route path="/device/:device/network/:network/account/:account" component={TopNavigationAccount} />
<Route path="/device/:device/device-settings" component={TopNavigationDeviceSettings} />
@ -110,10 +136,14 @@ const Wallet = (props: WalletContainerProps) => (
</AppWrapper>
);
const mapStateToProps: MapStateToProps<State, {}, WalletContainerProps> = (state: State): WalletContainerProps => ({
const mapStateToProps: MapStateToProps<State, OwnProps, StateProps> = (state: State): StateProps => ({
wallet: state.wallet,
});
const mapDispatchToProps: MapDispatchToProps<Dispatch, OwnProps, DispatchProps> = (dispatch: Dispatch): DispatchProps => ({
toggleSidebar: bindActionCreators(toggleSidebar, dispatch),
});
export default withRouter(
connect(mapStateToProps, null)(Wallet),
connect(mapStateToProps, mapDispatchToProps)(Wallet),
);

View File

@ -8,6 +8,7 @@ import Button from 'components/Button';
import Icon from 'components/Icon';
import Tooltip from 'components/Tooltip';
import Input from 'components/inputs/Input';
import DeviceIcon from 'components/images/DeviceIcon';
import ICONS from 'config/icons';
import colors from 'config/colors';
@ -131,10 +132,7 @@ const AccountReceive = (props: Props) => {
isPartiallyHidden={isAddressHidden}
trezorAction={isAddressVerifying ? (
<React.Fragment>
<Icon
icon={ICONS.T1}
color={colors.WHITE}
/>
<DeviceIcon device={device} color={colors.WHITE} />
Check address on your Trezor
</React.Fragment>
) : null}

View File

@ -8,6 +8,7 @@ import Button from 'components/Button';
import Icon from 'components/Icon';
import Tooltip from 'components/Tooltip';
import Input from 'components/inputs/Input';
import DeviceIcon from 'components/images/DeviceIcon';
import ICONS from 'config/icons';
import colors from 'config/colors';
@ -131,10 +132,7 @@ const AccountReceive = (props: Props) => {
isPartiallyHidden={isAddressHidden}
trezorAction={isAddressVerifying ? (
<React.Fragment>
<Icon
icon={ICONS.T1}
color={colors.WHITE}
/>
<DeviceIcon device={device} color={colors.WHITE} />
Check address on your Trezor
</React.Fragment>
) : null}

View File

@ -124,6 +124,10 @@ const StyledLink = styled(Link)`
white-space: nowrap;
`;
const StyledIcon = styled(Icon)`
cursor: pointer;
`;
// stateless component
const AdvancedForm = (props: Props) => {
const {
@ -186,7 +190,7 @@ const AdvancedForm = (props: Props) => {
readMoreLink="https://wiki.trezor.io/Ethereum_Wallet#Gas_limit"
placement="top"
>
<Icon
<StyledIcon
icon={ICONS.HELP}
color={colors.TEXT_SECONDARY}
size={24}
@ -228,7 +232,7 @@ const AdvancedForm = (props: Props) => {
readMoreLink="https://wiki.trezor.io/Ethereum_Wallet#Gas_price"
placement="top"
>
<Icon
<StyledIcon
icon={ICONS.HELP}
color={colors.TEXT_SECONDARY}
size={24}
@ -256,7 +260,7 @@ const AdvancedForm = (props: Props) => {
)}
placement="top"
>
<Icon
<StyledIcon
icon={ICONS.HELP}
color={colors.TEXT_SECONDARY}
size={24}

View File

@ -64,6 +64,10 @@ const AdvancedSettingsSendButtonWrapper = styled.div`
justify-content: flex-end;
`;
const StyledIcon = styled(Icon)`
cursor: pointer;
`;
const getFeeInputState = (feeErrors: string, feeWarnings: string): string => {
let state = '';
if (feeWarnings && !feeErrors) {
@ -132,7 +136,7 @@ const AdvancedForm = (props: Props) => {
readMoreLink="https://developers.ripple.com/transaction-cost.html"
placement="top"
>
<Icon
<StyledIcon
icon={ICONS.HELP}
color={colors.TEXT_SECONDARY}
size={24}
@ -168,7 +172,7 @@ const AdvancedForm = (props: Props) => {
readMoreLink="https://developers.ripple.com/rippleapi-reference.html#payment"
placement="top"
>
<Icon
<StyledIcon
icon={ICONS.HELP}
color={colors.TEXT_SECONDARY}
size={24}

View File

@ -7,6 +7,8 @@ import Title from 'views/Wallet/components/Title';
import Button from 'components/Button';
import Content from 'views/Wallet/components/Content';
import colors from 'config/colors';
import { SCREEN_SIZE } from 'config/variables';
import type { Props } from './Container';
@ -14,6 +16,7 @@ const Wrapper = styled.div`
display: flex;
flex: 1;
flex-direction: row;
flex-wrap: wrap;
background: ${colors.WHITE};
`;
@ -52,14 +55,22 @@ const StyledButton = styled(Button)`
const Column = styled.div`
display: flex;
flex: 1;
flex: 1 1 50%;
flex-direction: column;
@media screen and (max-width: ${SCREEN_SIZE.XS}) {
flex: 1 1 100%;
}
`;
const Sign = styled(Column)``;
const Verify = styled(Column)`
padding-left: 20px;
@media screen and (max-width: ${SCREEN_SIZE.XS}) {
padding-left: 0px;
}
`;
class SignVerify extends Component <Props> {

View File

@ -16,6 +16,10 @@ const StyledSVG = styled.svg`
margin-bottom: 24px;
`;
const StyledP = styled(P)`
text-align: center;
`;
const AddTokenMessage = () => (
<Wrapper>
<StyledSVG width="84px" height="76px" viewBox="0 0 84 76">
@ -51,7 +55,7 @@ const AddTokenMessage = () => (
</g>
</StyledSVG>
<H2>Add your tokens</H2>
<P isSmaller>Search for the token or add them manually by pasting token address into search input.</P>
<StyledP isSmaller>Search for the token or add them manually by pasting token address into search input.</StyledP>
</Wrapper>
);
export default AddTokenMessage;

View File

@ -21,7 +21,7 @@ type State = {
};
const Wrapper = styled.div`
padding-bottom: 28px;
padding-bottom: ${props => (props.isHidden ? '0px' : '28px')};
position: relative;
display: flex;
@ -116,7 +116,7 @@ class AccountBalance extends PureComponent<Props, State> {
}
return (
<Wrapper>
<Wrapper isHidden={this.state.isHidden}>
<HideBalanceIconWrapper
onClick={() => this.handleHideBalanceIconClick()}
>

View File

@ -50,10 +50,6 @@ const AccountTitle = styled.div`
color: ${colors.WALLET_TITLE};
`;
const StyledCoinLogo = styled(CoinLogo)`
margin-right: 10px;
`;
const StyledIcon = styled(Icon)`
position: relative;
top: -7px;
@ -93,7 +89,7 @@ const AccountSummary = (props: Props) => {
<React.Fragment>
<AccountHeading>
<AccountName>
<StyledCoinLogo network={account.network} />
<CoinLogo network={account.network} />
<AccountTitle>Account #{parseInt(account.index, 10) + 1}</AccountTitle>
</AccountName>
<Link href={explorerLink} isGray>See full transaction history</Link>
@ -123,7 +119,7 @@ const AccountSummary = (props: Props) => {
defaultOptions
value={null}
isMulti={false}
placeholder="Type in a token name or paste a token address directly"
placeholder="Type in a token name or a token address"
loadingMessage={() => 'Loading...'}
noOptionsMessage={() => 'Token not found'}
onChange={(token) => {

View File

@ -22,7 +22,7 @@ type State = {
};
const Wrapper = styled.div`
padding-bottom: 28px;
padding-bottom: ${props => (props.isHidden ? '0px' : '28px')};
position: relative;
display: flex;
@ -117,7 +117,7 @@ class AccountBalance extends PureComponent<Props, State> {
}
return (
<Wrapper>
<Wrapper isHidden={this.state.isHidden}>
<HideBalanceIconWrapper
onClick={() => this.handleHideBalanceIconClick()}
>

View File

@ -47,10 +47,6 @@ const AccountTitle = styled.div`
color: ${colors.WALLET_TITLE};
`;
const StyledCoinLogo = styled(CoinLogo)`
margin-right: 10px;
`;
const StyledIcon = styled(Icon)`
position: relative;
top: -7px;
@ -86,7 +82,7 @@ const AccountSummary = (props: Props) => {
<React.Fragment>
<AccountHeading>
<AccountName>
<StyledCoinLogo network={account.network} />
<CoinLogo network={account.network} />
<AccountTitle>Account #{parseInt(account.index, 10) + 1}</AccountTitle>
</AccountName>
{ !account.empty && <Link href={explorerLink} isGray>See full transaction history</Link> }

View File

@ -22,10 +22,14 @@ const StyledP = styled(P)`
text-align: center;
`;
const StyledH1 = styled(H1)`
text-align: center;
`;
const Bootloader = () => (
<Wrapper>
<Row>
<H1>Your device is in firmware update mode</H1>
<StyledH1>Your device is in firmware update mode</StyledH1>
<StyledP>Please re-connect it</StyledP>
</Row>
</Wrapper>

View File

@ -28,6 +28,10 @@ const StyledP = styled(P)`
text-align: center;
`;
const StyledH1 = styled(H1)`
text-align: center;
`;
const DeviceSettings = () => (
<Content>
<Section>
@ -37,7 +41,7 @@ const DeviceSettings = () => (
color={colors.WARNING_PRIMARY}
icon={ICONS.WARNING}
/>
<H1>Device settings is under construction</H1>
<StyledH1>Device settings is under construction</StyledH1>
<StyledP>Please use Bitcoin wallet interface to change your device settings</StyledP>
<Link href="https://beta-wallet.trezor.io/">
<Button>Take me to the Bitcoin wallet</Button>

View File

@ -23,6 +23,10 @@ const Row = styled.div`
padding: 50px 0;
`;
const StyledH1 = styled(H1)`
text-align: center;
`;
const WalletSettings = () => (
<Content>
<Section>
@ -32,7 +36,7 @@ const WalletSettings = () => (
color={colors.WARNING_PRIMARY}
icon={icons.WARNING}
/>
<H1>Wallet settings is under construction</H1>
<StyledH1>Wallet settings is under construction</StyledH1>
<Link to="/">
<Button>Take me back</Button>
</Link>