mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-13 20:08:56 +00:00
merge master
This commit is contained in:
commit
879d92d930
@ -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
|
||||
|
@ -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';
|
37
src/components/Backdrop/index.js
Normal file
37
src/components/Backdrop/index.js
Normal 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;
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
@ -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>
|
||||
);
|
||||
|
@ -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};
|
||||
`}
|
||||
|
||||
&,
|
||||
|
@ -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)};
|
||||
|
74
src/components/images/DeviceIcon/index.js
Normal file
74
src/components/images/DeviceIcon/index.js
Normal 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;
|
@ -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;
|
@ -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`
|
||||
|
@ -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>
|
||||
|
@ -30,7 +30,7 @@ const StyledLink = styled(Link)`
|
||||
`;
|
||||
|
||||
const Wrapper = styled.div`
|
||||
width: 370px;
|
||||
max-width: 370px;
|
||||
padding: 30px 48px;
|
||||
`;
|
||||
|
||||
|
@ -25,7 +25,6 @@ type Props = {
|
||||
}
|
||||
|
||||
const Wrapper = styled.div`
|
||||
width: 360px;
|
||||
`;
|
||||
|
||||
const Header = styled.div`
|
||||
|
@ -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 (
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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%);
|
||||
}
|
||||
`;
|
@ -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',
|
||||
],
|
||||
|
@ -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',
|
||||
|
@ -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,
|
||||
|
@ -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};
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import styled from 'styled-components';
|
||||
import Notification from 'components/Notification';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
min-width: 720px;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
|
@ -18,8 +18,7 @@ type Props = {
|
||||
}
|
||||
|
||||
const Wrapper = styled.div`
|
||||
min-height: 100%;
|
||||
min-width: 720px;
|
||||
min-height: 100vh;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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)`
|
||||
|
@ -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>
|
||||
)}
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
);
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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> {
|
||||
|
@ -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;
|
@ -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()}
|
||||
>
|
||||
|
@ -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) => {
|
||||
|
@ -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()}
|
||||
>
|
||||
|
@ -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> }
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user