mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-30 20:28:09 +00:00
merge master
This commit is contained in:
commit
0f005062fe
@ -37,6 +37,11 @@ const Wrapper = styled.button`
|
|||||||
background: ${colors.GREEN_TERTIARY};
|
background: ${colors.GREEN_TERTIARY};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: ${colors.INPUT_FOCUSED_BORDER};
|
||||||
|
box-shadow: 0 0px 6px 0 ${colors.INPUT_FOCUSED_SHADOW};
|
||||||
|
}
|
||||||
|
|
||||||
${props => props.isDisabled && css`
|
${props => props.isDisabled && css`
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
@ -48,6 +53,10 @@ const Wrapper = styled.button`
|
|||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
border: 1px solid ${colors.DIVIDER};
|
border: 1px solid ${colors.DIVIDER};
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: ${colors.INPUT_FOCUSED_BORDER};
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: ${colors.TEXT_PRIMARY};
|
color: ${colors.TEXT_PRIMARY};
|
||||||
background: ${colors.DIVIDER};
|
background: ${colors.DIVIDER};
|
||||||
@ -64,6 +73,11 @@ const Wrapper = styled.button`
|
|||||||
border: 0px;
|
border: 0px;
|
||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
color: ${colors.TEXT_PRIMARY};
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:active {
|
&:active {
|
||||||
color: ${colors.TEXT_PRIMARY};
|
color: ${colors.TEXT_PRIMARY};
|
||||||
|
@ -15,6 +15,7 @@ const Wrapper = styled.div`
|
|||||||
position: relative;
|
position: relative;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
width: 320px;
|
width: 320px;
|
||||||
|
z-index: 10;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: ${props => (props.disabled ? colors.GRAY_LIGHT : 'transparent')};
|
background: ${props => (props.disabled ? colors.GRAY_LIGHT : 'transparent')};
|
||||||
|
@ -11,17 +11,16 @@ const styles = isSearchable => ({
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
color: colors.TEXT_SECONDARY,
|
color: colors.TEXT_SECONDARY,
|
||||||
}),
|
}),
|
||||||
control: (base, { isDisabled }) => ({
|
control: (base, { isDisabled, isFocused }) => ({
|
||||||
...base,
|
...base,
|
||||||
minHeight: 'initial',
|
minHeight: 'initial',
|
||||||
height: '40px',
|
height: '40px',
|
||||||
borderRadius: '2px',
|
borderRadius: '2px',
|
||||||
borderColor: colors.DIVIDER,
|
borderColor: isFocused ? colors.INPUT_FOCUSED_BORDER : colors.DIVIDER,
|
||||||
boxShadow: 'none',
|
boxShadow: isFocused ? `0 0px 6px 0 ${colors.INPUT_FOCUSED_SHADOW}` : 'none',
|
||||||
background: isDisabled ? colors.LANDING : colors.WHITE,
|
background: isDisabled ? colors.LANDING : colors.WHITE,
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
cursor: isSearchable ? 'text' : 'pointer',
|
cursor: isSearchable ? 'text' : 'pointer',
|
||||||
borderColor: colors.DIVIDER,
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
indicatorSeparator: () => ({
|
indicatorSeparator: () => ({
|
||||||
|
@ -67,6 +67,11 @@ const StyledTextarea = styled(Textarea)`
|
|||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: ${colors.INPUT_FOCUSED_BORDER};
|
||||||
|
box-shadow: 0 0px 6px 0 ${colors.INPUT_FOCUSED_SHADOW};
|
||||||
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background: ${colors.GRAY_LIGHT};
|
background: ${colors.GRAY_LIGHT};
|
||||||
|
@ -59,6 +59,11 @@ const StyledInput = styled.input`
|
|||||||
background-color: ${colors.WHITE};
|
background-color: ${colors.WHITE};
|
||||||
transition: ${TRANSITION.HOVER};
|
transition: ${TRANSITION.HOVER};
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: ${colors.INPUT_FOCUSED_BORDER};
|
||||||
|
box-shadow: 0 0px 6px 0 ${colors.INPUT_FOCUSED_SHADOW};
|
||||||
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background: ${colors.GRAY_LIGHT};
|
background: ${colors.GRAY_LIGHT};
|
||||||
|
@ -72,3 +72,12 @@ export const FADE_IN = keyframes`
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const SLIDE_DOWN = keyframes`
|
||||||
|
0% {
|
||||||
|
transform: translateY(-100%);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateY(0%);
|
||||||
|
}
|
||||||
|
`;
|
@ -34,4 +34,7 @@ export default {
|
|||||||
|
|
||||||
LABEL_COLOR: '#A9A9A9',
|
LABEL_COLOR: '#A9A9A9',
|
||||||
TOOLTIP_BACKGROUND: '#333333',
|
TOOLTIP_BACKGROUND: '#333333',
|
||||||
|
|
||||||
|
INPUT_FOCUSED_BORDER: '#A9A9A9',
|
||||||
|
INPUT_FOCUSED_SHADOW: '#d6d7d7',
|
||||||
};
|
};
|
@ -8,18 +8,21 @@ import colors from 'config/colors';
|
|||||||
import { FONT_SIZE } from 'config/variables';
|
import { FONT_SIZE } from 'config/variables';
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
padding: 0px 24px 8px 19px;
|
|
||||||
box-shadow: 0 3px 8px rgba(0,0,0,0.06);
|
|
||||||
background: ${colors.WHITE};
|
background: ${colors.WHITE};
|
||||||
|
box-shadow: 0 3px 8px rgba(0,0,0,0.06);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Item = styled.div`
|
const Item = styled.div`
|
||||||
padding: 4px 2px;
|
padding: 6px 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: ${FONT_SIZE.BASE};
|
font-size: ${FONT_SIZE.BASE};
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: ${colors.GRAY_LIGHT};
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Label = styled.div`
|
const Label = styled.div`
|
||||||
|
@ -3,6 +3,11 @@ import React, { PureComponent } from 'react';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import TrezorConnect from 'trezor-connect';
|
import TrezorConnect from 'trezor-connect';
|
||||||
import type { TrezorDevice } from 'flowtype';
|
import type { TrezorDevice } from 'flowtype';
|
||||||
|
|
||||||
|
import COLORS from 'config/colors';
|
||||||
|
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
|
||||||
|
import { SLIDE_DOWN } from 'config/animations';
|
||||||
|
|
||||||
import Button from 'components/Button';
|
import Button from 'components/Button';
|
||||||
import * as deviceUtils from 'utils/device';
|
import * as deviceUtils from 'utils/device';
|
||||||
import MenuItems from './components/MenuItems';
|
import MenuItems from './components/MenuItems';
|
||||||
@ -12,9 +17,18 @@ import type { Props } from '../common';
|
|||||||
|
|
||||||
import Divider from '../Divider';
|
import Divider from '../Divider';
|
||||||
|
|
||||||
const Wrapper = styled.div``;
|
const Wrapper = styled.div`
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #E3E3E3;
|
||||||
|
background: white;
|
||||||
|
box-shadow: 0 3px 8px rgba(0,0,0,0.06);
|
||||||
|
animation: ${SLIDE_DOWN} 0.25s cubic-bezier(0.17, 0.04, 0.03, 0.94) forwards;
|
||||||
|
`;
|
||||||
|
|
||||||
const ButtonWrapper = styled.div`
|
const ButtonWrapper = styled.div`
|
||||||
margin-top: 10px;
|
margin: 10px 0;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
`;
|
`;
|
||||||
@ -22,6 +36,14 @@ const StyledButton = styled(Button)`
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const StyledDivider = styled(Divider)`
|
||||||
|
background: #fff;
|
||||||
|
color: ${COLORS.TEXT_PRIMARY};
|
||||||
|
font-weight: ${FONT_WEIGHT.MEDIUM};
|
||||||
|
font-size: ${FONT_SIZE.BASE};
|
||||||
|
border: none;
|
||||||
|
`;
|
||||||
|
|
||||||
type DeviceMenuItem = {
|
type DeviceMenuItem = {
|
||||||
type: string;
|
type: string;
|
||||||
label: string;
|
label: string;
|
||||||
@ -32,6 +54,7 @@ class DeviceMenu extends PureComponent<Props> {
|
|||||||
super(props);
|
super(props);
|
||||||
this.mouseDownHandler = this.mouseDownHandler.bind(this);
|
this.mouseDownHandler = this.mouseDownHandler.bind(this);
|
||||||
this.blurHandler = this.blurHandler.bind(this);
|
this.blurHandler = this.blurHandler.bind(this);
|
||||||
|
this.myRef = React.createRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
@ -63,6 +86,10 @@ class DeviceMenu extends PureComponent<Props> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMenuHeight(): number {
|
||||||
|
return this.myRef.current ? this.myRef.current.getBoundingClientRect().height : 0;
|
||||||
|
}
|
||||||
|
|
||||||
blurHandler(): void {
|
blurHandler(): void {
|
||||||
this.props.toggleDeviceDropdown(false);
|
this.props.toggleDeviceDropdown(false);
|
||||||
}
|
}
|
||||||
@ -96,26 +123,28 @@ class DeviceMenu extends PureComponent<Props> {
|
|||||||
return deviceUtils.isDeviceAccessible(this.props.wallet.selectedDevice);
|
return deviceUtils.isDeviceAccessible(this.props.wallet.selectedDevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myRef: { current: ?HTMLDivElement }
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { devices, onSelectDevice, forgetDevice } = this.props;
|
const { devices, onSelectDevice, forgetDevice } = this.props;
|
||||||
const { transport } = this.props.connect;
|
const { transport } = this.props.connect;
|
||||||
const { selectedDevice } = this.props.wallet;
|
const { selectedDevice } = this.props.wallet;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Wrapper>
|
<Wrapper ref={this.myRef}>
|
||||||
{this.showMenuItems() && <MenuItems device={selectedDevice} {...this.props} />}
|
{this.showMenuItems() && <MenuItems device={selectedDevice} {...this.props} />}
|
||||||
{this.showDivider() && <Divider hasBorder textLeft="Other devices" />}
|
{this.showDivider() && <StyledDivider hasBorder textLeft="Other devices" />}
|
||||||
<DeviceList
|
<DeviceList
|
||||||
devices={devices}
|
devices={devices}
|
||||||
selectedDevice={selectedDevice}
|
selectedDevice={selectedDevice}
|
||||||
onSelectDevice={onSelectDevice}
|
onSelectDevice={onSelectDevice}
|
||||||
forgetDevice={forgetDevice}
|
forgetDevice={forgetDevice}
|
||||||
/>
|
/>
|
||||||
<ButtonWrapper>
|
{deviceUtils.isWebUSB(transport) && (
|
||||||
{deviceUtils.isWebUSB(transport) && (
|
<ButtonWrapper>
|
||||||
<StyledButton isWebUsb>Check for devices</StyledButton>
|
<StyledButton isWebUsb>Check for devices</StyledButton>
|
||||||
)}
|
</ButtonWrapper>
|
||||||
</ButtonWrapper>
|
)}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -23,10 +23,11 @@ const TextLeft = styled.p`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const Divider = ({
|
const Divider = ({
|
||||||
textLeft, textRight, hasBorder = false,
|
textLeft, textRight, hasBorder = false, className,
|
||||||
}) => (
|
}) => (
|
||||||
<Wrapper
|
<Wrapper
|
||||||
hasBorder={hasBorder}
|
hasBorder={hasBorder}
|
||||||
|
className={className}
|
||||||
>
|
>
|
||||||
<TextLeft>{textLeft}</TextLeft>
|
<TextLeft>{textLeft}</TextLeft>
|
||||||
<p>{textRight}</p>
|
<p>{textRight}</p>
|
||||||
@ -34,6 +35,7 @@ const Divider = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
Divider.propTypes = {
|
Divider.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
textLeft: PropTypes.string,
|
textLeft: PropTypes.string,
|
||||||
textRight: PropTypes.string,
|
textRight: PropTypes.string,
|
||||||
hasBorder: PropTypes.bool,
|
hasBorder: PropTypes.bool,
|
||||||
|
@ -57,6 +57,7 @@ const Footer = styled.div.attrs(props => ({
|
|||||||
|
|
||||||
const Body = styled.div`
|
const Body = styled.div`
|
||||||
width: 320px;
|
width: 320px;
|
||||||
|
min-height: ${props => (props.minHeight ? `${props.minHeight}px` : '0px')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Help = styled.div`
|
const Help = styled.div`
|
||||||
@ -110,42 +111,48 @@ const TransitionMenu = (props: TransitionMenuProps): React$Element<TransitionGro
|
|||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
animationType: ?string;
|
animationType: ?string;
|
||||||
shouldRenderDeviceSelection: boolean;
|
|
||||||
clicked: boolean;
|
clicked: boolean;
|
||||||
|
bodyMinHeight: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class LeftNavigation extends React.PureComponent<Props, State> {
|
class LeftNavigation extends React.PureComponent<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
this.deviceMenuRef = React.createRef();
|
||||||
const { location } = this.props.router;
|
const { location } = this.props.router;
|
||||||
const hasNetwork = location && location.state && location.state.network;
|
const hasNetwork = location && location.state && location.state.network;
|
||||||
this.state = {
|
this.state = {
|
||||||
animationType: hasNetwork ? 'slide-left' : null,
|
animationType: hasNetwork ? 'slide-left' : null,
|
||||||
shouldRenderDeviceSelection: false,
|
|
||||||
clicked: false,
|
clicked: false,
|
||||||
|
bodyMinHeight: 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.recalculateBodyMinHeight();
|
||||||
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps: Props) {
|
componentWillReceiveProps(nextProps: Props) {
|
||||||
const { dropdownOpened, selectedDevice } = nextProps.wallet;
|
const { selectedDevice } = nextProps.wallet;
|
||||||
const { location } = nextProps.router;
|
const { location } = nextProps.router;
|
||||||
const hasNetwork = location && location.state.network;
|
const hasNetwork = location && location.state.network;
|
||||||
const deviceReady = selectedDevice && selectedDevice.features && selectedDevice.mode === 'normal';
|
const deviceReady = selectedDevice && selectedDevice.features && selectedDevice.mode === 'normal';
|
||||||
if (dropdownOpened) {
|
|
||||||
this.setState({ shouldRenderDeviceSelection: true });
|
if (hasNetwork) {
|
||||||
} else if (hasNetwork) {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
shouldRenderDeviceSelection: false,
|
|
||||||
animationType: 'slide-left',
|
animationType: 'slide-left',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({
|
this.setState({
|
||||||
shouldRenderDeviceSelection: false,
|
|
||||||
animationType: deviceReady ? 'slide-right' : null,
|
animationType: deviceReady ? 'slide-right' : null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
this.recalculateBodyMinHeight();
|
||||||
|
}
|
||||||
|
|
||||||
shouldRenderAccounts() {
|
shouldRenderAccounts() {
|
||||||
const { selectedDevice } = this.props.wallet;
|
const { selectedDevice } = this.props.wallet;
|
||||||
const { location } = this.props.router;
|
const { location } = this.props.router;
|
||||||
@ -153,7 +160,6 @@ class LeftNavigation extends React.PureComponent<Props, State> {
|
|||||||
&& location
|
&& location
|
||||||
&& location.state
|
&& location.state
|
||||||
&& location.state.network
|
&& location.state.network
|
||||||
&& !this.state.shouldRenderDeviceSelection
|
|
||||||
&& this.state.animationType === 'slide-left';
|
&& this.state.animationType === 'slide-left';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,9 +169,19 @@ class LeftNavigation extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
shouldRenderCoins() {
|
shouldRenderCoins() {
|
||||||
return !this.state.shouldRenderDeviceSelection && this.state.animationType !== 'slide-left';
|
return this.state.animationType !== 'slide-left';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recalculateBodyMinHeight() {
|
||||||
|
if (this.deviceMenuRef.current) {
|
||||||
|
this.setState({
|
||||||
|
bodyMinHeight: this.deviceMenuRef.current.getMenuHeight(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceMenuRef: { current: any };
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { props } = this;
|
const { props } = this;
|
||||||
let menu;
|
let menu;
|
||||||
@ -183,7 +199,7 @@ class LeftNavigation extends React.PureComponent<Props, State> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { selectedDevice } = props.wallet;
|
const { selectedDevice, dropdownOpened } = props.wallet;
|
||||||
const isDeviceAccessible = deviceUtils.isDeviceAccessible(selectedDevice);
|
const isDeviceAccessible = deviceUtils.isDeviceAccessible(selectedDevice);
|
||||||
return (
|
return (
|
||||||
<StickyContainer
|
<StickyContainer
|
||||||
@ -218,8 +234,8 @@ class LeftNavigation extends React.PureComponent<Props, State> {
|
|||||||
)}
|
)}
|
||||||
{...this.props}
|
{...this.props}
|
||||||
/>
|
/>
|
||||||
<Body>
|
<Body minHeight={this.state.bodyMinHeight}>
|
||||||
{this.state.shouldRenderDeviceSelection && <DeviceMenu {...this.props} />}
|
{dropdownOpened && <DeviceMenu ref={this.deviceMenuRef} {...this.props} />}
|
||||||
{isDeviceAccessible && menu}
|
{isDeviceAccessible && menu}
|
||||||
</Body>
|
</Body>
|
||||||
<Footer key="sticky-footer">
|
<Footer key="sticky-footer">
|
||||||
|
Loading…
Reference in New Issue
Block a user