1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-28 03:08:30 +00:00

device select with webusb button

This commit is contained in:
Szymon Lesisz 2018-03-29 11:31:45 +02:00
parent ebaf57f841
commit e61f861f1f
9 changed files with 260 additions and 89 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 856 B

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -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>
); );
} }
}

View File

@ -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
} }

View File

@ -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 {

View File

@ -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 {

View File

@ -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;
}
}
} }
} }