1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-24 01:08:27 +00:00

Merge branch 'styled-components-refactor' of https://github.com/satoshilabs/trezor-wallet into styled-components-refactor

This commit is contained in:
Vasek Mlejnsky 2018-08-24 11:41:20 +02:00
commit db2008811d
27 changed files with 600 additions and 307 deletions

View File

@ -54,6 +54,7 @@
"react-scale-text": "^1.2.2",
"react-select": "2.0.0",
"react-transition-group": "^2.2.1",
"redbox-react": "^1.6.0",
"redux": "4.0.0",
"redux-logger": "^3.0.6",
"redux-raven-middleware": "^1.2.0",

View File

@ -14,18 +14,62 @@ const Wrapper = styled.button`
background: ${colors.GREEN_PRIMARY};
color: ${colors.WHITE};
border: 0;
&:hover {
background: ${colors.GREEN_SECONDARY};
}
&:active {
background: ${colors.GREEN_TERTIARY};
}
${props => props.disabled && css`
pointer-events: none;
color: ${colors.TEXT_SECONDARY};
background: ${colors.GRAY_LIGHT};
`}
${props => props.isBlue && css`
background: transparent;
border: 1px solid ${colors.INFO_PRIMARY};
color: ${colors.INFO_PRIMARY};
padding: 12px 58px;
&:hover {
color: ${colors.WHITE};
background: ${colors.INFO_PRIMARY};
}
`}
${props => props.isWhite && css`
background: @color_white;
color: ${colors.TEXT_SECONDARY};
border: 1px solid ${colors.DIVIDER};
&:hover {
color: ${colors.TEXT_PRIMARY};
border-color: ${colors.TEXT_PRIMARY};
background: ${colors.DIVIDER};
}
&:active {
color: ${colors.TEXT_PRIMARY};
background: ${colors.DIVIDER};
}
`}
${props => props.isTransparent && css`
background: transparent;
border: 0px;
color: ${colors.TEXT_SECONDARY};
&:hover,
&:active {
color: ${colors.TEXT_PRIMARY};
background: transparent;
}
`}
${props => props.isWebUsb && css`
position: relative;
padding: 12px 24px 12px 40px;
@ -81,7 +125,7 @@ const IconWrapper = styled.span`
`;
const Button = ({
className, text, icon, onClick = () => { }, disabled, isBlue = false, isWhite = false, isWebUsb = false,
className, text, icon, onClick = () => { }, disabled, isBlue = false, isWhite = false, isWebUsb = false, isTransparent = false,
}) => (
<Wrapper
className={className}
@ -91,6 +135,7 @@ const Button = ({
isBlue={isBlue}
isWhite={isWhite}
isWebUsb={isWebUsb}
isTransparent={isTransparent}
>
{icon && (
<IconWrapper>
@ -112,6 +157,7 @@ Button.propTypes = {
isBlue: PropTypes.bool,
isWhite: PropTypes.bool,
isWebUsb: PropTypes.bool,
isTransparent: PropTypes.bool,
icon: PropTypes.shape({
type: PropTypes.arrayOf(PropTypes.string).isRequired,
color: PropTypes.string,

View File

@ -24,9 +24,12 @@ const LayoutWrapper = styled.div`
height: 100%;
max-width: 1170px;
margin: 0 auto;
padding: 0 32px;
display: flex;
align-items: center;
@media screen and (max-width: 1170px) {
padding: 0 25px;
}
`;
const A = styled.a`

View File

@ -1,39 +1,62 @@
import React from 'react';
import PropTypes from 'prop-types';
import styled, { keyframes } from 'styled-components';
const Icon = ({ icon, size = 32, color = 'black' }) => {
const styles = {
svg: {
// TODO: make animation of icons better
const rotate180up = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(180deg);
}
`;
const rotate180down = keyframes`
from {
transform: rotate(180deg);
}
to {
transform: rotate(0deg);
}
`;
const SvgWrapper = styled.svg`
animation: ${props => (props.canAnimate ? (props.isActive ? rotate180up : rotate180down) : null)} 0.2s linear 1 forwards;
`;
const Path = styled.path``;
const Icon = ({
icon, size = 32, color = 'black', isActive, canAnimate,
}) => (
<SvgWrapper
canAnimate={canAnimate}
isActive={isActive}
style={{
display: 'inline-block',
verticalAlign: 'middle',
},
path: {
fill: color,
},
};
return (
<svg
style={styles.svg}
width={`${size}`}
height={`${size}`}
viewBox="0 0 1024 1024"
>
{icon.map(iconPath => (
<path
key={iconPath}
style={styles.path}
d={iconPath}
/>
))}
</svg>
);
};
}}
width={`${size}`}
height={`${size}`}
viewBox="0 0 1024 1024"
>
{icon.map(path => (
<Path
key={path}
isActive={isActive}
style={{ fill: color }}
d={path}
/>
))}
</SvgWrapper>
);
Icon.propTypes = {
canAnimate: PropTypes.bool,
icon: PropTypes.arrayOf(PropTypes.string).isRequired,
size: PropTypes.number,
isActive: PropTypes.bool,
color: PropTypes.string,
};

View File

@ -1,23 +1,70 @@
/* @flow */
import React from 'react';
import styled from 'styled-components';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import colors from 'config/colors';
import { H2 } from 'components/Heading';
import Icon from 'components/Icon';
import P from 'components/P';
import * as LogActions from 'actions/LogActions';
import type { State, Dispatch } from 'flowtype';
import icons from 'config/icons';
import { State, Dispatch } from 'flowtype';
const Wrapper = styled.div`
position: relative;
color: ${colors.INFO_PRIMARY};
background: ${colors.INFO_SECONDARY};
padding: 24px 48px;
display: flex;
flex-direction: column;
text-align: left;
`;
const Click = styled.div`
cursor: pointer;
position: absolute;
top: 8px;
right: 0;
padding: 12px;
color: inherit;
transition: opacity 0.3s;
&:active,
&:hover {
opacity: 0.6;
color: inherit;
}
`;
const Textarea = styled.textarea`
width: 100%;
height: 200px;
min-height: 200px;
resize: vertical;
font-size: 10px;
&:focus {
box-shadow: none;
}
`;
const StyledP = styled(P)`
margin: 10px 0;
`;
const Log = (props: Props): ?React$Element<string> => {
if (!props.log.opened) return null;
return (
<div className="log">
<button className="log-close transparent" onClick={props.toggle} />
<Wrapper>
<Click onClick={props.toggle}>
<Icon size={25} color={colors.INFO_PRIMARY} icon={icons.CLOSE} />
</Click>
<H2>Log</H2>
<p>Attention: The log contains your XPUBs. Anyone with your XPUBs can see your account history.</p>
<textarea value={JSON.stringify(props.log.entries)} readOnly />
</div>
<StyledP>Attention: The log contains your XPUBs. Anyone with your XPUBs can see your account history.</StyledP>
<Textarea value={JSON.stringify(props.log.entries)} readOnly />
</Wrapper>
);
};

View File

@ -0,0 +1,18 @@
import styled from 'styled-components';
import PropTypes from 'prop-types';
import React from 'react';
const Wrapper = styled.p`
`;
const P = ({ children, className }) => (
<Wrapper className={className}>{children}</Wrapper>
);
P.propTypes = {
className: PropTypes.string,
children: PropTypes.string.isRequired,
};
export default P;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1,22 @@
import React from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
const Wrapper = styled.div``;
const Img = styled.img`
width: ${props => (props.model === 'T' ? '17px' : '13px')};
`;
const TrezorImage = ({ model }) => (
<Wrapper>
<Img model={model} src={model === 'T' ? './images/trezor-T.png' : './images/trezor-1.png'} />
</Wrapper>
);
TrezorImage.propTypes = {
model: PropTypes.string,
status: PropTypes.string,
};
export default TrezorImage;

View File

@ -1,7 +1,8 @@
export default {
WHITE: '#FFFFFF',
BACKGROUND: '#EBEBEB',
HEADER: '#212121',
HEADER: '#1A1A1A',
BODY: '#E3E3E3',
MAIN: '#FBFBFB',
LANDING: '#F9F9F9',

View File

@ -1,4 +1,7 @@
export default {
CLOSE: [
'M754.816 689.92c17.6 17.6 17.6 46.72 0 64.64-8.96 8.64-20.48 13.44-32.64 13.44s-23.68-4.8-32.32-13.44l-177.888-177.92-177.888 177.92c-16.32 16.96-47.040 17.6-64.64 0-17.92-17.92-17.92-47.040 0-64.64l178.208-177.92-178.208-177.92c-17.92-17.92-17.92-46.72 0-64.64 17.28-17.28 47.36-17.28 64.64 0l177.888 177.92 177.888-177.92c17.92-17.92 47.040-17.92 64.96 0 17.6 17.92 17.6 46.72 0 64.64l-178.24 177.92 178.24 177.92z',
],
DOWNLOAD: [
'M346.56 410.24c3.255-1.423 7.047-2.252 11.033-2.252 0.284 0 0.566 0.004 0.848 0.013l-0.041-0.001c8.323 0.531 15.657 4.371 20.77 10.206l0.030 0.034 93.44 109.44c0.378 0.735 1.131 1.229 1.999 1.229 1.237 0 2.24-1.003 2.24-2.24 0-0.209-0.029-0.412-0.083-0.605l0.004 0.016v-233.28c-0.102-0.987-0.16-2.132-0.16-3.291 0-18.733 15.187-33.92 33.92-33.92s33.92 15.187 33.92 33.92c0 1.159-0.058 2.304-0.172 3.433l0.012-0.142v236.16c-0.050 0.177-0.079 0.379-0.079 0.589 0 1.237 1.003 2.24 2.24 2.24 0.868 0 1.621-0.494 1.993-1.216l0.006-0.013 88.32-104.32c5.204-6.343 13.042-10.358 21.819-10.358 7.711 0 14.699 3.099 19.784 8.121l-0.003-0.003c6.16 5.845 9.993 14.090 9.993 23.231 0 8.17-3.062 15.625-8.101 21.28l0.028-0.032-146.56 173.44c-5.311 6.15-13.061 10.069-21.731 10.24h-0.029c-8.727-0.036-16.523-3.991-21.724-10.196l-0.036-0.044-152-178.56c-5.441-6.124-8.764-14.234-8.764-23.121 0-12.698 6.785-23.81 16.927-29.911l0.157-0.088z',
'M694.72 731.2c0.024 0.488 0.038 1.060 0.038 1.635 0 18.891-14.881 34.306-33.561 35.163l-0.077 0.003h-292.48c-18.795-1.81-33.372-17.523-33.372-36.64s14.577-34.83 33.222-36.628l0.15-0.012h292.48c18.751 0.866 33.625 16.278 33.625 35.165 0 0.463-0.009 0.923-0.027 1.381l0.002-0.066z',
@ -9,6 +12,9 @@ export default {
ARROW_LEFT: [
'M603.072 757.216l-237.44-219.616c-8.576-8.128-13.632-19.296-13.632-31.040 0.288-11.744 5.056-23.2 13.664-31.040l227.040-208.768c16.928-15.36 43.040-14.176 58.176 3.008 15.424 16.864 13.952 43.392-2.656 59.040l-193.504 177.76 203.904 188.608c8 7.52 12.768 18.080 13.344 29.216 0.608 11.456-3.264 21.696-10.688 30.112-15.456 16.896-41.568 18.080-58.208 2.72z',
],
ARROW_DOWN: [
'M757.216 420.928l-219.616 237.44c-8.128 8.576-19.296 13.632-31.040 13.632-11.744-0.288-23.2-5.056-31.040-13.664l-208.768-227.040c-15.36-16.928-14.176-43.040 3.008-58.176 16.864-15.424 43.392-13.952 59.040 2.656l177.76 193.504 188.608-203.904c7.52-8 18.080-12.768 29.216-13.344 11.456-0.608 21.696 3.264 30.112 10.688 16.896 15.456 18.080 41.568 2.72 58.208z',
],
CHAT: [
'M580.992 256h-137.984c-103.296 0-187.008 85.952-187.008 192 0 96.608 69.536 176.32 160 189.792v130.208l128-128h36.992c103.296 0 187.008-85.952 187.008-192s-83.712-192-187.008-192z',
],

View File

@ -1,23 +1,19 @@
import React, { Component } from 'react';
import RedBox from 'redbox-react';
class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { hasError: false };
this.state = { hasError: false, error: false };
}
componentDidCatch(error, info) {
// Display fallback UI
this.setState({ hasError: true });
console.error('error', error);
// You can also log the error to an error reporting service
// logErrorToMyService(error, info);
this.setState({ hasError: true, error });
}
render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <div>Something went wrong.</div>;
return <RedBox error={this.state.error} />;
}
return this.props.children;
}

88
src/js/utils/device.js Normal file
View File

@ -0,0 +1,88 @@
import colors from 'js/config/colors';
const getStatus = (device) => {
let status = 'connected';
if (!device.connected) {
status = 'disconnected';
} else if (!device.available) {
status = 'unavailable';
} else if (device.type === 'acquired') {
if (device.status === 'occupied') {
status = 'used-in-other-window';
}
} else if (device.type === 'unacquired') {
status = 'unacquired';
}
return status;
};
const getStatusName = (deviceStatus) => {
let statusName;
switch (deviceStatus) {
case 'used-in-other-window':
statusName = 'Used in other window';
break;
case 'connected':
statusName = 'Connected';
break;
case 'disconnected':
statusName = 'Disconnected';
break;
case 'unacquired':
statusName = 'Used in other window';
break;
case 'unavailable':
statusName = 'Unavailable';
break;
default:
statusName = 'Status unknown';
}
return statusName;
};
const isWebUSB = transport => !!((transport && transport.version.indexOf('webusb') >= 0));
const isDisabled = (selectedDevice, devices, transport) => (devices.length < 1 && !isWebUSB(transport)) || (devices.length === 1 && !selectedDevice.features && !isWebUSB(transport));
const getVersion = (device) => {
let version;
if (device.features && device.features.major_version > 1) {
version = 'T';
} else {
version = '1';
}
return version;
};
const getStatusColor = (deviceStatus) => {
let color;
switch (deviceStatus) {
case 'used-in-other-window':
color = colors.WARNING_PRIMARY;
break;
case 'connected':
color = colors.GREEN_PRIMARY;
break;
case 'unacquired':
color = colors.WARNING_PRIMARY;
break;
case 'disconnected':
color = colors.ERROR_PRIMARY;
break;
case 'unavailable':
color = colors.ERROR_PRIMARY;
break;
default:
color = colors.TEXT_PRIMARY;
}
return color;
};
export {
getStatus,
isDisabled,
getStatusName,
getVersion,
getStatusColor,
};

View File

@ -0,0 +1,156 @@
import React, { Component } from 'react';
import styled, { css } from 'styled-components';
import PropTypes from 'prop-types';
import Icon from 'components/Icon';
import icons from 'config/icons';
import { getStatusColor, getStatusName } from 'utils/device';
import TrezorImage from 'components/TrezorImage';
import colors from 'config/colors';
const Wrapper = styled.div`
position: relative;
height: 64px;
width: 320px;
display: flex;
align-items: center;
background: ${colors.WHITE};
border-radius: 4px 0 0 0;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.04);
${props => props.isOpen && css`
box-shadow: none;
`}
`;
const ClickWrapper = styled.div`
width: 100%;
display: flex;
padding-left: 25px;
height: 100%;
align-items: center;
cursor: pointer;
${props => props.disabled && css`
cursor: initial;
`}
`;
const LabelWrapper = styled.div`
flex: 1;
padding-left: 18px;
`;
const Name = styled.div`
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: no-wrap;
font-weight: 500;
font-size: 14px;
color: ${colors.TEXT_PRIMARY};
`;
const Status = styled.div`
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-size: 12px;
color: ${colors.TEXT_SECONDARY};
`;
const Counter = styled.div`
border: 1px solid ${colors.DIVIDER};
border-radius: 50%;
color: ${colors.TEXT_SECONDARY};
width: 24px;
height: 24px;
line-height: 22px;
text-align: center;
font-size: 11px;
margin-right: 8px;
`;
const IconWrapper = styled.div`
padding-right: 25px;
display: flex;
`;
const ImageWrapper = styled.div`
position: relative;
`;
const Dot = styled.div`
border: 2px solid ${colors.WHITE};
border-radius: 50%;
position: absolute;
z-index: 10;
background: ${props => props.color};
top: -4px;
right: -3px;
width: 10px;
height: 10px;
`;
class DeviceHeader extends Component {
constructor(props) {
super(props);
this.state = {
clicked: false,
};
}
handleClick() {
this.setState({ clicked: true });
if (!this.props.disabled) {
this.props.handleOpen();
}
}
render() {
const {
status, label, deviceCount, isOpen, trezorModel, disabled,
} = this.props;
return (
<Wrapper isOpen={isOpen}>
<ClickWrapper disabled={disabled} onClick={() => this.handleClick()}>
<ImageWrapper>
<Dot color={getStatusColor(status)} />
<TrezorImage model={trezorModel} />
</ImageWrapper>
<LabelWrapper>
<Name>{label}</Name>
<Status>{getStatusName(status)}</Status>
</LabelWrapper>
<IconWrapper>
{deviceCount > 1 && <Counter>{deviceCount}</Counter>}
{!disabled && (
<Icon
canAnimate={this.state.clicked === true}
isActive={isOpen}
size={25}
color={colors.TEXT_SECONDARY}
icon={icons.ARROW_DOWN}
/>
)
}
</IconWrapper>
</ClickWrapper>
</Wrapper>
);
}
}
DeviceHeader.propTypes = {
deviceCount: PropTypes.number,
disabled: PropTypes.bool,
isOpen: PropTypes.bool,
trezorModel: PropTypes.string.isRequired,
handleOpen: PropTypes.func.isRequired,
status: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
};
export default DeviceHeader;

View File

@ -1,33 +1,21 @@
import React from 'react';
import React, { Component } from 'react';
import styled from 'styled-components';
import deviceConstants from 'constants/device';
import { getStatus } from 'utils/device';
const Wrapper = styled.div``;
class DeviceList {
getStatus(device) {
let deviceStatus = '';
if (device.type === 'unacquired' || (device.features && device.status === 'occupied')) {
deviceStatus = 'Used in other window';
} else if (device.type === 'unreadable') {
deviceStatus = 'Connected';
} else if (!device.connected) {
deviceStatus = 'Disconnected';
} else if (!device.available) {
deviceStatus = 'Unavailable';
}
return deviceStatus;
}
class DeviceList extends Component {
render() {
return (
<Wrapper>
{this.props.devices.map((device, index) => (
<div key={index} className={css} onClick={() => this.props.onSelectDevice(device)}>
<div
key={index}
onClick={() => this.props.onSelectDevice(device)}
>
<div className="label-container">
<span className="label">{device.instanceLabel}</span>
<span className="status">{this.getStatus(device)}</span>
<span className="status">{getStatus(device)}</span>
</div>
<div
className="forget-button"

View File

@ -1,66 +1,39 @@
/* @flow */
import React, { Component } from 'react';
import styled from 'styled-components';
import TrezorConnect from 'trezor-connect';
import type { TrezorDevice } from 'flowtype';
import { getStatus, getVersion, isDisabled } from 'utils/device';
import DeviceHeader from './components/DeviceHeader';
// import DeviceList from './components/DeviceList';
import type { Props } from '../common';
import AsideDivider from '../Divider';
const Wrapper = styled.div``;
export const DeviceSelect = (props: Props) => {
const { devices } = props;
const { transport } = props.connect;
const selected: ?TrezorDevice = props.wallet.selectedDevice;
if (!selected) return null;
let deviceStatus: string = 'Connected';
let css: string = 'device-select device';
if (props.deviceDropdownOpened) css += ' opened';
if (!selected.connected) {
css += ' disconnected';
deviceStatus = 'Disconnected';
} else if (!selected.available) {
css += ' unavailable';
deviceStatus = 'Unavailable';
} else if (selected.type === 'acquired') {
if (selected.status === 'occupied') {
css += ' used-elsewhere';
deviceStatus = 'Used in other window';
} else if (selected.status === 'used') {
css += ' reload-features';
}
} else if (selected.type === 'unacquired') {
css += ' unacquired';
deviceStatus = 'Used in other window';
}
if (selected.features && selected.features.major_version > 1) {
css += ' trezor-t';
}
const { selectedDevice } = props.wallet;
const disabled = isDisabled(selectedDevice, devices, transport);
const handleOpen = () => {
props.toggleDeviceDropdown(!props.deviceDropdownOpened);
};
const deviceCount = devices.length;
const webusb: boolean = !!((transport && transport.version.indexOf('webusb') >= 0));
const disabled: boolean = (devices.length < 1 && !webusb) || (devices.length === 1 && !selected.features && !webusb);
if (disabled) {
css += ' disabled';
}
return (
<div className={css} onClick={!disabled ? handleOpen : null}>
<div className="label-container">
<span className="label">{selected.instanceLabel}</span>
<span className="status">{deviceStatus}</span>
</div>
{deviceCount > 1 ? <div className="counter">{deviceCount}</div> : null}
<div className="arrow" />
</div>
<DeviceHeader
handleOpen={handleOpen}
disabled={disabled}
label={selectedDevice.instanceLabel}
status={getStatus(selectedDevice)}
deviceCount={devices.length}
isOpen={props.deviceDropdownOpened}
trezorModel={getVersion(selectedDevice)}
/>
);
};
@ -172,7 +145,7 @@ export class DeviceDropdown extends Component<Props> {
const sortByInstance = (a: TrezorDevice, b: TrezorDevice) => {
if (!a.instance || !b.instance) return -1;
return a.instance > b.instance ? 1 : -1;
}
};
const deviceList = devices.sort(sortByInstance).map((dev, index) => {
if (dev === selected) return null;
@ -214,14 +187,14 @@ export class DeviceDropdown extends Component<Props> {
);
});
return (
<React.Fragment>
<Wrapper>
{currentDeviceMenu}
{deviceList.length > 1 ? <AsideDivider textLeft="Other devices" /> : null}
{this.props.devices.length > 1 ? <AsideDivider textLeft="Other devices" /> : null}
{/* <DeviceList devices={devices} /> */}
{deviceList}
{webUsbButton}
</React.Fragment>
</Wrapper>
);
}
}

View File

@ -27,7 +27,9 @@ const StickyBottom = styled.div`
border-right: 1px solid ${colors.DIVIDER};
`;
const MenuWrapper = styled.div``;
const MenuWrapper = styled.div`
background: ${colors.LANDING};
`;
const Help = styled.div`
display: flex;
@ -143,12 +145,13 @@ class LeftNavigation extends Component {
}
render() {
const { selectedDevice } = this.props.wallet;
return (
<StickyContainer
location={this.props.location.pathname}
deviceSelection={this.props.deviceDropdownOpened}
>
<DeviceSelect {...this.props} />
{selectedDevice && <DeviceSelect {...this.props} />}
<MenuWrapper>
{this.state.shouldRenderDeviceSelection && <DeviceDropdown {...this.props} />}
{this.shouldRenderAccounts() && this.getMenuTransition(<AccountMenu {...this.props} />)}

View File

@ -1,6 +1,8 @@
/* @flow */
import * as React from 'react';
import colors from 'config/colors';
import styled from 'styled-components';
import { connect } from 'react-redux';
import { Route, withRouter } from 'react-router-dom';
@ -26,11 +28,43 @@ type ContentProps = {
children?: React.Node
}
const AppWrapper = styled.div`
position: relative;
min-height: 100vh;
min-width: 720px;
display: flex;
flex-direction: column;
background: ${colors.BACKGROUND};
&.resized {
// to make sure that unpacked coin menu will not overflow main container
// 512 dropdown height + 50 header + 30 margin + 64 topnav height
min-height: 680px;
}
`;
const WalletWrapper = styled.div`
width: 100%;
max-width: 1170px;
margin: 0 auto;
flex: 1;
background: ${colors.WHITE};
display: flex;
flex-direction: row;
border-radius: 4px 4px 0px 0px;
overflow: hidden;
margin-top: 32px;
@media screen and (max-width: 1170px) {
border-radius: 0px;
margin-top: 0px;
}
`;
const Wallet = (props: WalletContainerProps) => (
<div className="app">
<AppWrapper>
<Header />
{/* <div>{ props.wallet.online ? "ONLINE" : "OFFLINE" }</div> */}
<main>
<WalletWrapper>
<LeftNavigation />
<article>
<nav>
@ -42,9 +76,9 @@ const Wallet = (props: WalletContainerProps) => (
{ props.children }
<Footer />
</article>
</main>
</WalletWrapper>
<ModalContainer />
</div>
</AppWrapper>
);
const mapStateToProps: MapStateToProps<State, {}, WalletContainerProps> = (state: State, own: {}): WalletContainerProps => ({

View File

@ -1,7 +1,9 @@
/* @flow */
import React from 'react';
import styled from 'styled-components';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import colors from 'config/colors';
import { Notification } from 'components/Notification';
import * as TrezorConnectActions from 'actions/TrezorConnectActions';
@ -12,6 +14,13 @@ type Props = {
acquireDevice: typeof TrezorConnectActions.acquire
}
const Wrapper = styled.div`
display: flex;
background: ${colors.WHITE};
flex-direction: column;
flex: 1;
`;
const Acquire = (props: Props) => {
const actions = props.acquiring ? [] : [
{
@ -23,7 +32,7 @@ const Acquire = (props: Props) => {
];
return (
<section className="acquire">
<Wrapper>
<Notification
title="Device is used in other window"
message="Do you want to use your device in this window?"
@ -31,7 +40,7 @@ const Acquire = (props: Props) => {
cancelable={false}
actions={actions}
/>
</section>
</Wrapper>
);
};

View File

@ -1,17 +1,41 @@
/* @flow */
import styled from 'styled-components';
import { H2 } from 'components/Heading';
import Button from 'components/Button';
import P from 'components/P';
import React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
const Wrapper = styled.div`
display: flex;
flex: 1;
justify-content: center;
align-items: center;
`;
const Row = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
`;
const A = styled.a``;
const StyledP = styled(P)`
margin: 20px 50px;
display: block;
`;
const Initialize = () => (
<section className="device-settings">
<div className="row">
<Wrapper>
<Row>
<H2>Your device is in not initialized</H2>
<p>Please use Bitcoin wallet interface to start initialization process</p>
<a className="button" href="https://wallet.trezor.io/">Take me to the Bitcoin wallet</a>
</div>
</section>
<StyledP>Please use Bitcoin wallet interface to start initialization process</StyledP>
<A href="https://wallet.trezor.io/">
<Button text="Take me to the Bitcoin wallet" />
</A>
</Row>
</Wrapper>
);
export default connect(null, null)(Initialize);

View File

@ -1,41 +0,0 @@
.acquire {
flex: 1;
display: flex;
flex-direction: column;
background: @color_white;
.warning {
background: @color_info_secondary;
display: flex;
flex-direction: row;
padding: 26px 39px 26px 80px;
div {
flex: 1;
position: relative;
}
h2 {
color: @color_info_primary;
font-size: 14px;
-webkit-font-smoothing: auto;
margin-bottom: 5px;
padding: 0px;
&:before {
.icomoon-info;
position: absolute;
top: -7px;
left: -32px;
font-size: 32px;
}
}
p {
color: @color_info_primary;
font-size: 12px;
padding: 0px;
}
}
}

View File

@ -1,40 +0,0 @@
html, body {
width: 100%;
height: 100%;
position: relative;
background-color: @color_body;
font-family: @font-default;
font-weight: 400;
font-size: 14px;
}
.app {
position: relative;
min-height: 100vh;
min-width: 720px;
display: flex;
flex-direction: column;
&.resized {
// to make sure that unpacked coin menu will not overflow main container
// 512 dropdown height + 50 header + 30 margin + 64 topnav height
min-height: 680px;
}
}
main {
width: 100%;
max-width: 1170px;
margin: 0 auto;
flex: 1;
background: @color_main;
display: flex;
flex-direction: row;
border-radius: 4px 4px 0px 0px;
overflow: hidden;
margin-top: 32px;
@media screen and (max-width: 1170px) {
border-radius: 0px;
margin-top: 0px;
}
}

View File

@ -5,7 +5,6 @@ article {
nav {
height: 64px;
border-bottom: 1px solid @color_divider;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.06);
display: flex;
background: @color_white;

View File

@ -1,36 +0,0 @@
.history {
flex: 1;
padding: 10px;
display: flex;
flex-direction: column;
border: 1px solid red;
.history-transaction {
.amount, .time, .address {
margin-left: 10px;
}
&.in {
color: green;
.amount {
&:before {
content: '+'
}
}
}
&.out {
color: red;
.amount {
&:before {
content: '-'
}
}
}
}
}

View File

@ -1,7 +1,6 @@
@import './fonts.less';
@import './colors.less';
@import './mixins.less';
@import './base.less';
@import './aside.less';
@import './content.less';
@import './modal.less';
@ -9,16 +8,12 @@
@import './reactSelect.less';
@import './rcTooltip.less';
@import './history.less';
@import './send.less';
@import './receive.less';
@import './summary.less';
@import './landingPage.less';
@import './acquire.less';
@import './notification.less';
@import './inputs.less';
@import './loader.less';
@import './log.less';

View File

@ -1,51 +0,0 @@
.log {
position: relative;
color: @color_info_primary;
background: @color_info_secondary;
padding: 24px 48px;
display: flex;
flex-direction: column;
text-align: left;
.log-close {
position: absolute;
top: 8px;
right: 0;
padding: 12px;
color: inherit;
transition: opacity 0.3s;
&:after {
.icomoon-close;
}
&:active,
&:hover {
opacity: 0.6;
color: inherit;
}
}
h2 {
font-size: 14px;
font-weight: bold;
padding: 0px;
}
p {
padding: 0px;
margin: 2px 0px;
font-size: 12px;
color: inherit;
}
textarea {
width: 100%;
height: 200px;
min-height: 200px;
resize: vertical;
font-size: 10px;
&:focus {
box-shadow: none;
}
}
}

View File

@ -3336,6 +3336,12 @@ error-ex@^1.2.0, error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
error-stack-parser@^1.3.6:
version "1.3.6"
resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-1.3.6.tgz#e0e73b93e417138d1cd7c0b746b1a4a14854c292"
dependencies:
stackframe "^0.3.1"
error@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02"
@ -8220,6 +8226,15 @@ rechoir@^0.6.2:
dependencies:
resolve "^1.1.6"
redbox-react@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/redbox-react/-/redbox-react-1.6.0.tgz#e753ac02595bc1bf695b3935889a4f5b1b5a21a1"
dependencies:
error-stack-parser "^1.3.6"
object-assign "^4.0.1"
prop-types "^15.5.4"
sourcemapped-stacktrace "^1.1.6"
redent@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
@ -8981,6 +8996,10 @@ source-map-url@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
source-map@0.5.6:
version "0.5.6"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@ -8999,6 +9018,12 @@ source-map@^0.7.2:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
sourcemapped-stacktrace@^1.1.6:
version "1.1.8"
resolved "https://registry.yarnpkg.com/sourcemapped-stacktrace/-/sourcemapped-stacktrace-1.1.8.tgz#6b7a3f1a6fb15f6d40e701e23ce404553480d688"
dependencies:
source-map "0.5.6"
spdx-correct@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40"
@ -9080,6 +9105,10 @@ stack-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620"
stackframe@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4"
state-toggle@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.1.tgz#c3cb0974f40a6a0f8e905b96789eb41afa1cde3a"