mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-24 09:18:09 +00:00
added device status indicator (color-dot in aside)
This commit is contained in:
parent
55728f6ba3
commit
424339442e
@ -10,107 +10,6 @@ import { findSelectedDevice } from '../../../reducers/TrezorConnectReducer';
|
|||||||
import type { Props } from './index';
|
import type { Props } from './index';
|
||||||
import type { TrezorDevice } from '../../../flowtype';
|
import type { TrezorDevice } from '../../../flowtype';
|
||||||
|
|
||||||
type ValueProps = {
|
|
||||||
onClick: (type: string, device: TrezorDevice) => void,
|
|
||||||
onOpen: () => any,
|
|
||||||
onClose: () => any,
|
|
||||||
value: TrezorDevice,
|
|
||||||
opened: boolean,
|
|
||||||
disabled: boolean,
|
|
||||||
deviceCount: number,
|
|
||||||
}
|
|
||||||
|
|
||||||
const Value = (props: ValueProps): any => {
|
|
||||||
const device = props.value; // device is passed as value of selected item
|
|
||||||
|
|
||||||
// prevent onMouseDown event
|
|
||||||
const onMouseDown = event => {
|
|
||||||
if (props.onClick) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onClick = (event, item, device) => {
|
|
||||||
if (props.onClick) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
props.onClick(item, device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let deviceStatus: string = "Connected";
|
|
||||||
let css: string = "device-select device";
|
|
||||||
if (props.opened) css += " opened";
|
|
||||||
if (props.disabled) css += " disabled";
|
|
||||||
|
|
||||||
|
|
||||||
const deviceMenuItems: Array<any> = [];
|
|
||||||
|
|
||||||
if (device.features && device.features.passphrase_protection) {
|
|
||||||
deviceMenuItems.push("settings"); // TODO: clone
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device.unacquired) {
|
|
||||||
css += " unacquired";
|
|
||||||
deviceStatus = "Used in other window";
|
|
||||||
}
|
|
||||||
if (device.isUsedElsewhere) {
|
|
||||||
css += " used-elsewhere";
|
|
||||||
deviceStatus = "Used in other window";
|
|
||||||
deviceMenuItems.push("acquire");
|
|
||||||
} else if (device.featuresNeedsReload) {
|
|
||||||
css += " reload-features";
|
|
||||||
//deviceMenuItems.push("acquire");
|
|
||||||
}
|
|
||||||
if (!device.connected) {
|
|
||||||
css += " reload-features";
|
|
||||||
deviceStatus = "Disconnected";
|
|
||||||
} else if (!device.available) {
|
|
||||||
css += " unavailable";
|
|
||||||
deviceStatus = "Unavailable";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device.remember) {
|
|
||||||
deviceMenuItems.push("forget");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device.features && device.features.major_version > 1) {
|
|
||||||
css += " trezor-t";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const deviceMenuButtons = deviceMenuItems.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<div key={ item } className={ item } onClick={ event => onClick(event, item, device) }></div>
|
|
||||||
)
|
|
||||||
});
|
|
||||||
const deviceMenu = deviceMenuButtons.length < 1 ? null : (
|
|
||||||
<div className="device-menu">
|
|
||||||
{ deviceMenuButtons }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleOpen = () => {
|
|
||||||
if (props.disabled) return;
|
|
||||||
props.opened ? props.onClose() : props.onOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={ css } onClick={ handleOpen }>
|
|
||||||
<div className="label-container">
|
|
||||||
<span className="label">{ device.instanceLabel }</span>
|
|
||||||
<span className="status">{ deviceStatus }</span>
|
|
||||||
</div>
|
|
||||||
{ props.deviceCount > 1 ? <div className="counter">{ props.deviceCount }</div> : null }
|
|
||||||
<div className="arrow"></div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const DeviceSelect = (props: Props) => {
|
export const DeviceSelect = (props: Props) => {
|
||||||
|
|
||||||
const { devices, transport } = props.connect;
|
const { devices, transport } = props.connect;
|
||||||
@ -118,30 +17,50 @@ export const DeviceSelect = (props: Props) => {
|
|||||||
const selected: ?TrezorDevice = findSelectedDevice(props.connect);
|
const selected: ?TrezorDevice = findSelectedDevice(props.connect);
|
||||||
if (!selected) return null;
|
if (!selected) return null;
|
||||||
|
|
||||||
const handleMenuClick = (type: string, device: TrezorDevice) => {
|
let deviceStatus: string = "Connected";
|
||||||
if (type === 'acquire') {
|
let css: string = "device-select device";
|
||||||
props.acquireDevice();
|
if (props.deviceDropdownOpened) css += " opened";
|
||||||
} else if (type === 'forget') {
|
|
||||||
props.forgetDevice(device);
|
if (!selected.connected) {
|
||||||
}else if (type === 'settings') {
|
css += " disconnected";
|
||||||
props.duplicateDevice(device);
|
deviceStatus = "Disconnected";
|
||||||
|
} else if (!selected.available) {
|
||||||
|
css += " unavailable";
|
||||||
|
deviceStatus = "Unavailable";
|
||||||
|
} else {
|
||||||
|
if (selected.unacquired) {
|
||||||
|
css += " unacquired";
|
||||||
|
deviceStatus = "Used in other window";
|
||||||
|
}
|
||||||
|
if (selected.isUsedElsewhere) {
|
||||||
|
css += " used-elsewhere";
|
||||||
|
deviceStatus = "Used in other window";
|
||||||
|
} else if (selected.featuresNeedsReload) {
|
||||||
|
css += " reload-features";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selected.features && selected.features.major_version > 1) {
|
||||||
|
css += " trezor-t";
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleOpen = () => {
|
||||||
|
props.toggleDeviceDropdown(props.deviceDropdownOpened ? false : true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const deviceCount = devices.length;
|
||||||
const webusb: boolean = (transport && transport.version.indexOf('webusb') >= 0) ? true : false;
|
const webusb: boolean = (transport && transport.version.indexOf('webusb') >= 0) ? true : false;
|
||||||
const disabled: boolean = (devices.length < 1 && !webusb);
|
const disabled: boolean = (devices.length < 1 && !webusb);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Value
|
<div className={ css } onClick={ handleOpen }>
|
||||||
className="device-select"
|
<div className="label-container">
|
||||||
onClick={ handleMenuClick }
|
<span className="label">{ selected.instanceLabel }</span>
|
||||||
disabled={ disabled }
|
<span className="status">{ deviceStatus }</span>
|
||||||
value={ selected }
|
</div>
|
||||||
deviceCount={ devices.length }
|
{ deviceCount > 1 ? <div className="counter">{ deviceCount }</div> : null }
|
||||||
opened={ props.deviceDropdownOpened }
|
<div className="arrow"></div>
|
||||||
onOpen={ () => props.toggleDeviceDropdown(true) }
|
</div>
|
||||||
onClose={ () => props.toggleDeviceDropdown(false) }
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,10 +182,13 @@ export class DeviceDropdown extends Component<Props> {
|
|||||||
let css: string = "device item"
|
let css: string = "device item"
|
||||||
if (dev.unacquired || dev.isUsedElsewhere) {
|
if (dev.unacquired || dev.isUsedElsewhere) {
|
||||||
deviceStatus = "Used in other window";
|
deviceStatus = "Used in other window";
|
||||||
|
css += " unacquired";
|
||||||
} else if (!dev.connected) {
|
} else if (!dev.connected) {
|
||||||
deviceStatus = "Disconnected";
|
deviceStatus = "Disconnected";
|
||||||
|
css += " disconnected";
|
||||||
} else if (!dev.available) {
|
} else if (!dev.available) {
|
||||||
deviceStatus = "Unavailable";
|
deviceStatus = "Unavailable";
|
||||||
|
css += " unavailable";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev.features && dev.features.major_version > 1) {
|
if (dev.features && dev.features.major_version > 1) {
|
||||||
|
@ -3,61 +3,8 @@ aside {
|
|||||||
width: 320px;
|
width: 320px;
|
||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
border-right: 1px solid @color_divider;
|
border-right: 1px solid @color_divider;
|
||||||
//display: flex;
|
|
||||||
//flex-direction: column;
|
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
.Select {
|
|
||||||
width: 320px;
|
|
||||||
height: 64px;
|
|
||||||
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.04);
|
|
||||||
background: @color_white;
|
|
||||||
|
|
||||||
.Select-control {
|
|
||||||
height: 63px;
|
|
||||||
border: 0px;
|
|
||||||
// border-radius: 4px 0px 0px 0px;
|
|
||||||
border-right: 1px solid @color_divider;
|
|
||||||
border-bottom: 1px solid @color_divider;
|
|
||||||
transition: color 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Select-arrow-zone {
|
|
||||||
right: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Select-menu-outer {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-open {
|
|
||||||
.Select-control {
|
|
||||||
border-color: @color_divider;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.is-disabled {
|
|
||||||
.Select-control {
|
|
||||||
background: @color_white;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.Select-arrow {
|
|
||||||
visibility: hidden;
|
|
||||||
// &:after {
|
|
||||||
// content: ''
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
.device {
|
|
||||||
.device-menu {
|
|
||||||
padding-right: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.sticky-container {
|
.sticky-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -173,6 +120,35 @@ aside {
|
|||||||
background-image: url('../images/trezor-1.png');
|
background-image: url('../images/trezor-1.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
top: 14px;
|
||||||
|
left: 32px;
|
||||||
|
background: @color_green_primary;
|
||||||
|
border: 2px solid @color_white;
|
||||||
|
border-radius: 50%;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disconnected,
|
||||||
|
&.unavailable, {
|
||||||
|
&:after {
|
||||||
|
background: @color_error_primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.unacquired,
|
||||||
|
&.used-elsewhere,
|
||||||
|
&.reload-features, {
|
||||||
|
&:after {
|
||||||
|
background: @color_warning_primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.trezor-t {
|
&.trezor-t {
|
||||||
&:before {
|
&:before {
|
||||||
width: 17px;
|
width: 17px;
|
||||||
@ -180,6 +156,11 @@ aside {
|
|||||||
background-size: 17px 25px;
|
background-size: 17px 25px;
|
||||||
background-image: url('../images/trezor-T.png');
|
background-image: url('../images/trezor-T.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
left: 34px;
|
||||||
|
top: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-container {
|
.label-container {
|
||||||
@ -215,50 +196,6 @@ aside {
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .device-menu {
|
|
||||||
// display: flex;
|
|
||||||
// justify-content: flex-end;
|
|
||||||
// padding-right: 4px;
|
|
||||||
// padding-left: 4px;
|
|
||||||
|
|
||||||
// div {
|
|
||||||
// display: inline-block;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// .forget,
|
|
||||||
// .settings,
|
|
||||||
// .acquire {
|
|
||||||
// cursor: pointer;
|
|
||||||
|
|
||||||
// &:before {
|
|
||||||
// .icomoon-refresh;
|
|
||||||
// color: @color_text_secondary;
|
|
||||||
// position: relative;
|
|
||||||
// font-size: 24px;
|
|
||||||
// .hover();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &:hover {
|
|
||||||
// &:before {
|
|
||||||
// color: @color_text_primary;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// .forget {
|
|
||||||
// &:before {
|
|
||||||
// .icomoon-eject;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// .settings {
|
|
||||||
// &:before {
|
|
||||||
// .icomoon-settings;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-menu {
|
.device-menu {
|
||||||
|
@ -153,6 +153,7 @@
|
|||||||
&.enabled {
|
&.enabled {
|
||||||
color: @color_white;
|
color: @color_white;
|
||||||
background: @color_green_primary;
|
background: @color_green_primary;
|
||||||
|
border-color: @color_green_primary;
|
||||||
&:before {
|
&:before {
|
||||||
.icomoon-checked;
|
.icomoon-checked;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user