device select with webusb button
Before Width: | Height: | Size: 608 B After Width: | Height: | Size: 856 B |
Before Width: | Height: | Size: 608 B After Width: | Height: | Size: 856 B |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
@ -1,7 +1,7 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React, { Component } from 'react';
|
||||||
import Select from 'react-select';
|
import Select from 'react-select';
|
||||||
|
|
||||||
import { findSelectedDevice } from '../../../reducers/TrezorConnectReducer';
|
import { findSelectedDevice } from '../../../reducers/TrezorConnectReducer';
|
||||||
@ -18,15 +18,21 @@ const Value = (props: any): any => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onClick = (item, device) => {
|
const onClick = (event, item, device) => {
|
||||||
if (props.onClick)
|
if (props.onClick) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
props.onClick(item, device);
|
props.onClick(item, device);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let deviceStatus: string = "Connected";
|
let deviceStatus: string = "Connected";
|
||||||
let css: string = "device";
|
let css: string = "device-select device";
|
||||||
|
if (props.opened) css += " opened";
|
||||||
|
if (props.disabled) css += " disabled";
|
||||||
|
|
||||||
|
|
||||||
const deviceMenuItems: Array<any> = [];
|
const deviceMenuItems: Array<any> = [];
|
||||||
// deviceMenuItems.push("settings");
|
|
||||||
|
|
||||||
if (device.unacquired) {
|
if (device.unacquired) {
|
||||||
css += " unacquired";
|
css += " unacquired";
|
||||||
@ -49,9 +55,13 @@ const Value = (props: any): any => {
|
|||||||
deviceMenuItems.push("forget");
|
deviceMenuItems.push("forget");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device.features && device.features.major_version > 1) {
|
||||||
|
css += " trezor-t";
|
||||||
|
}
|
||||||
|
|
||||||
const deviceMenuButtons = deviceMenuItems.map((item, index) => {
|
const deviceMenuButtons = deviceMenuItems.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={ item } className={ item } onMouseDown={ onMouseDown } onClick={ event => onClick(item, device) }></div>
|
<div key={ item } className={ item } onClick={ event => onClick(event, item, device) }></div>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
const deviceMenu = deviceMenuButtons.length < 1 ? null : (
|
const deviceMenu = deviceMenuButtons.length < 1 ? null : (
|
||||||
@ -60,12 +70,13 @@ const Value = (props: any): any => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleOpen = () => {
|
||||||
|
if (props.disabled) return;
|
||||||
|
props.opened ? props.onClose() : props.onOpen();
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={ css } onClick={ handleOpen }>
|
||||||
className={ css }
|
|
||||||
onMouseDown={ props.onMouseDown }
|
|
||||||
onMouseEnter={ props.onMouseEnter }
|
|
||||||
onMouseMove={ props.onMouseMove } >
|
|
||||||
<div className="label-container">
|
<div className="label-container">
|
||||||
<span className="label">{ device.instanceLabel }</span>
|
<span className="label">{ device.instanceLabel }</span>
|
||||||
<span className="status">{ deviceStatus }</span>
|
<span className="status">{ deviceStatus }</span>
|
||||||
@ -73,11 +84,13 @@ const Value = (props: any): any => {
|
|||||||
<div className="device-menu">
|
<div className="device-menu">
|
||||||
{ deviceMenuButtons }
|
{ deviceMenuButtons }
|
||||||
</div>
|
</div>
|
||||||
|
<div className="arrow">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeviceSelect = (props: any): any => {
|
export const DeviceSelect1 = (props: any): any => {
|
||||||
|
|
||||||
const { devices } = props.connect;
|
const { devices } = props.connect;
|
||||||
const selected = findSelectedDevice(props.connect);
|
const selected = findSelectedDevice(props.connect);
|
||||||
@ -97,7 +110,8 @@ export const DeviceSelect = (props: any): any => {
|
|||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
className="device-select"
|
className="device-select"
|
||||||
disabled={ (devices && devices.length <= 1) }
|
// disabled={ (devices && devices.length <= 1) }
|
||||||
|
disabled={ false }
|
||||||
searchable={ false }
|
searchable={ false }
|
||||||
clearable= { false }
|
clearable= { false }
|
||||||
tabSelectsValue={ false }
|
tabSelectsValue={ false }
|
||||||
@ -111,21 +125,116 @@ export const DeviceSelect = (props: any): any => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DeviceDropdown = (props: any): any => {
|
|
||||||
const { devices } = props.connect;
|
export const DeviceSelect = (props: any): any => {
|
||||||
|
|
||||||
|
const { devices, transport } = props.connect;
|
||||||
const selected = findSelectedDevice(props.connect);
|
const selected = findSelectedDevice(props.connect);
|
||||||
|
if (!selected) return null;
|
||||||
|
|
||||||
|
const handleMenuClick = (type, device) => {
|
||||||
|
console.log("handleMenuClick", type, device)
|
||||||
|
if (type === 'acquire') {
|
||||||
|
props.acquireDevice(device);
|
||||||
|
} else if (type === 'forget') {
|
||||||
|
props.forgetDevice(device);
|
||||||
|
}else if (type === 'settings') {
|
||||||
|
props.duplicateDevice(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("DEVSEL", props)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Value
|
||||||
|
className="device-select"
|
||||||
|
onClick={ handleMenuClick }
|
||||||
|
disabled={ (devices && devices.length <= 1 && transport.indexOf('webusb') < 0) }
|
||||||
|
value={ selected }
|
||||||
|
opened={ props.deviceDropdownOpened }
|
||||||
|
onOpen={ () => props.toggleDeviceDropdown(true) }
|
||||||
|
onClose={ () => props.toggleDeviceDropdown(false) }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DeviceDropdown extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.mouseDownHandler = this.mouseDownHandler.bind(this);
|
||||||
|
this.blurHandler = this.blurHandler.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
if (this.props.connect.transport.indexOf('webusb') >= 0)
|
||||||
|
TrezorConnect.renderWebUSBButton();
|
||||||
|
|
||||||
|
console.log("RENDER USB BUTTON")
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseDownHandler(event: MouseEvent): void {
|
||||||
|
console.log("HANDLE DOWN!!!!", event)
|
||||||
|
let elem = event.target;
|
||||||
|
let block: boolean = false;
|
||||||
|
while (elem.parentElement) {
|
||||||
|
// if (elem.className.indexOf('aside-button') >= 0) {
|
||||||
|
if (elem.tagName.toLowerCase() === 'aside') {
|
||||||
|
block = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
elem = elem.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!block) {
|
||||||
|
this.props.toggleDeviceDropdown(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blurHandler(event: FocusEvent): void {
|
||||||
|
this.props.toggleDeviceDropdown(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount(): void {
|
||||||
|
window.addEventListener('mousedown', this.mouseDownHandler, false);
|
||||||
|
// window.addEventListener('blur', this.blurHandler, false);
|
||||||
|
|
||||||
|
if (this.props.connect.transport.indexOf('webusb') >= 0)
|
||||||
|
TrezorConnect.renderWebUSBButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount(): void {
|
||||||
|
window.removeEventListener('mousedown', this.mouseDownHandler, false);
|
||||||
|
// window.removeEventListener('blur', this.blurHandler, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
const { devices, transport } = this.props.connect;
|
||||||
|
const selected = findSelectedDevice(this.props.connect);
|
||||||
|
|
||||||
|
let webUsbButton = null;
|
||||||
|
if (transport.indexOf('webusb') >= 0) {
|
||||||
|
webUsbButton = <button className="trezor-webusb-button">Check for devices</button>;
|
||||||
|
}
|
||||||
|
|
||||||
const deviceList: Array<any> = devices.map((dev, index) => {
|
const deviceList: Array<any> = devices.map((dev, index) => {
|
||||||
if (dev === selected) return null;
|
if (dev === selected) return null;
|
||||||
|
|
||||||
let deviceStatus: string = "Connected";
|
let deviceStatus: string = "Connected";
|
||||||
|
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";
|
||||||
} else if (!dev.connected) {
|
} else if (!dev.connected) {
|
||||||
deviceStatus = "Disconnected";
|
deviceStatus = "Disconnected";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dev.features && dev.features.major_version > 1) {
|
||||||
|
css += " trezor-t";
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={index} className="device item" onMouseDown={ () => props.onSelectDevice(dev) } onTouchStart={ () => props.onSelectDevice(dev) } >
|
<div key={index} className={ css } onMouseDown={ () => this.props.onSelectDevice(dev) } onTouchStart={ () => this.props.onSelectDevice(dev) } >
|
||||||
<div className="label-container">
|
<div className="label-container">
|
||||||
<span className="label">{ dev.instanceLabel }</span>
|
<span className="label">{ dev.instanceLabel }</span>
|
||||||
<span className="status">{ deviceStatus }</span>
|
<span className="status">{ deviceStatus }</span>
|
||||||
@ -136,7 +245,9 @@ export const DeviceDropdown = (props: any): any => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
|
{ webUsbButton }
|
||||||
{ deviceList }
|
{ deviceList }
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
@ -304,7 +304,7 @@ export default function connect(state: State = initialState, action: any): any {
|
|||||||
case 'iframe_handshake' :
|
case 'iframe_handshake' :
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
browserState: action.payload.browserState
|
browserState: action.payload.browser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +57,8 @@ aside {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.sticky-container {
|
.sticky-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -89,10 +91,57 @@ aside {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.trezor-webusb-button {
|
||||||
|
margin: 12px 0px 12px 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-select {
|
||||||
|
background: @color_white;
|
||||||
|
border-bottom: 1px solid @color_divider;
|
||||||
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.04);
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 28px;
|
||||||
|
&:after {
|
||||||
|
.icomoon-arrow-down;
|
||||||
|
transition: transform 0.3s, color 0.3s;
|
||||||
|
color: @color_text_secondary;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.arrow:after {
|
||||||
|
color: @color_text_primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.opened {
|
||||||
|
.arrow:after {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: initial;
|
||||||
|
.arrow {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.device-menu {
|
||||||
|
padding-right: 26px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.device {
|
.device {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 63px;
|
height: 64px;
|
||||||
width: 319px;
|
width: 320px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding-left: 80px;
|
padding-left: 80px;
|
||||||
@ -118,7 +167,16 @@ aside {
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-size: 13px 25px;
|
background-size: 13px 25px;
|
||||||
background-image: url('../images/icontrezor.png');
|
background-image: url('../images/trezor-1.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
&.trezor-t {
|
||||||
|
&:before {
|
||||||
|
width: 17px;
|
||||||
|
left: 31px;
|
||||||
|
background-size: 17px 25px;
|
||||||
|
background-image: url('../images/trezor-T.png');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.label-container {
|
.label-container {
|
||||||
@ -146,7 +204,7 @@ aside {
|
|||||||
.device-menu {
|
.device-menu {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding-right: 48px;
|
padding-right: 4px;
|
||||||
padding-left: 4px;
|
padding-left: 4px;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
|
@ -112,6 +112,56 @@ button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a copy of webusb.less from trezor-connect
|
||||||
|
.trezor-webusb-button {
|
||||||
|
position: relative;
|
||||||
|
padding: 12px 24px 12px 40px;
|
||||||
|
background: transparent;
|
||||||
|
color: @color_green_primary;
|
||||||
|
border: 1px solid @color_green_primary;
|
||||||
|
.hover();
|
||||||
|
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
background: @color_green_primary;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
.hover();
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
width: 12px;
|
||||||
|
height: 2px;
|
||||||
|
left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
width: 2px;
|
||||||
|
height: 12px;
|
||||||
|
left: 23px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: @color_green_primary;
|
||||||
|
color: @color_white;
|
||||||
|
|
||||||
|
&:before,
|
||||||
|
&:after {
|
||||||
|
background: @color_white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.custom-checkbox {
|
.custom-checkbox {
|
||||||
|
|
||||||
|
@ -258,55 +258,7 @@
|
|||||||
animation: connect 1.3s ease-out infinite;
|
animation: connect 1.3s ease-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a copy of webusb.less from trezor-connect
|
|
||||||
.trezor-webusb-button {
|
|
||||||
position: relative;
|
|
||||||
padding: 12px 24px 12px 40px;
|
|
||||||
background: transparent;
|
|
||||||
color: @color_green_primary;
|
|
||||||
border: 1px solid @color_green_primary;
|
|
||||||
.hover();
|
|
||||||
|
|
||||||
&:before,
|
|
||||||
&:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
background: @color_green_primary;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
margin: auto;
|
|
||||||
.hover();
|
|
||||||
}
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
width: 12px;
|
|
||||||
height: 2px;
|
|
||||||
left: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
width: 2px;
|
|
||||||
height: 12px;
|
|
||||||
left: 23px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: @color_green_primary;
|
|
||||||
color: @color_white;
|
|
||||||
|
|
||||||
&:before,
|
|
||||||
&:after {
|
|
||||||
background: @color_white;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|