From 62466e3424fc2f3027ff916f63c64dfe3a3ef38a Mon Sep 17 00:00:00 2001 From: meriadec Date: Fri, 16 Mar 2018 12:28:50 +0100 Subject: [PATCH] Create DeviceMonit component and use it in SendModal --- src/components/DeviceMonit/index.js | 111 ++++++++++++++++++ src/components/base/Button/index.js | 2 +- .../modals/Send/02-step-connect-device.js | 34 +++++- src/components/modals/Send/Footer.js | 5 +- src/components/modals/Send/index.js | 31 ++++- src/internals/usb/wallet/index.js | 25 ++++ src/reducers/devices.js | 6 +- 7 files changed, 204 insertions(+), 10 deletions(-) create mode 100644 src/components/DeviceMonit/index.js diff --git a/src/components/DeviceMonit/index.js b/src/components/DeviceMonit/index.js new file mode 100644 index 00000000..82b47a9f --- /dev/null +++ b/src/components/DeviceMonit/index.js @@ -0,0 +1,111 @@ +// @flow + +import React, { PureComponent } from 'react' +import { connect } from 'react-redux' +import { ipcRenderer } from 'electron' + +import { sendEvent } from 'renderer/events' +import { getCurrentDevice } from 'reducers/devices' +import type { Device, Account } from 'types/common' + +const mapStateToProps = state => ({ + currentDevice: getCurrentDevice(state), +}) + +type DeviceStatus = 'unconnected' | 'connected' | 'appOpened' + +type Props = { + currentDevice: Device | null, + account: Account, + onStatusChange: DeviceStatus => void, +} + +type State = { + status: DeviceStatus, +} + +class DeviceMonit extends PureComponent { + state = { + status: this.props.currentDevice ? 'connected' : 'unconnected', + } + + componentDidMount() { + ipcRenderer.on('msg', this.handleMsgEvent) + if (this.props.currentDevice !== null) { + this.checkAppOpened() + } + } + + componentWillReceiveProps(nextProps) { + const { status } = this.state + const { currentDevice } = this.props + const { currentDevice: nextCurrentDevice } = nextProps + + if (status === 'unconnected' && !currentDevice && nextCurrentDevice) { + this.handleStatusChange('connected') + } + + if (status !== 'unconnected' && !nextCurrentDevice) { + this.handleStatusChange('unconnected') + } + } + + componentDidUpdate() { + const { currentDevice } = this.props + + if (currentDevice !== null) { + this.checkAppOpened() + } else { + clearTimeout(this._timeout) + } + } + + componentWillUnmount() { + ipcRenderer.removeListener('msg', this.handleMsgEvent) + clearTimeout(this._timeout) + } + + checkAppOpened = () => { + const { currentDevice, account } = this.props + + if (currentDevice === null || account.currency === null) { + return + } + + sendEvent('usb', 'wallet.checkIfAppOpened', { + devicePath: currentDevice.path, + accountPath: account.path, + accountAddress: account.address, + }) + } + + _timeout: any = null + + handleStatusChange = status => { + this.setState({ status }) + this.props.onStatusChange(status) + } + + handleMsgEvent = (e, { type }) => { + if (type === 'wallet.checkIfAppOpened.success') { + this.handleStatusChange('appOpened') + clearTimeout(this._timeout) + } + + if (type === 'wallet.checkIfAppOpened.fail') { + this._timeout = setTimeout(this.checkAppOpened, 1e3) + } + } + + render() { + const { status } = this.state + return ( +
+
device connected {status !== 'unconnected' ? 'TRUE' : 'FALSE'}
+
app opened {status === 'appOpened' ? 'TRUE' : 'FALSE'}
+
+ ) + } +} + +export default connect(mapStateToProps)(DeviceMonit) diff --git a/src/components/base/Button/index.js b/src/components/base/Button/index.js index 14b53bb0..3c224787 100644 --- a/src/components/base/Button/index.js +++ b/src/components/base/Button/index.js @@ -27,7 +27,7 @@ const Base = styled.button.attrs({ outline: none; &:hover { - background: ${p => (p.primary ? lighten(p.theme.colors.wallet, 0.05) : '')}; + background: ${p => (p.disabled ? '' : p.primary ? lighten(p.theme.colors.wallet, 0.05) : '')}; } &:active { diff --git a/src/components/modals/Send/02-step-connect-device.js b/src/components/modals/Send/02-step-connect-device.js index ba744f9c..b11f91cf 100644 --- a/src/components/modals/Send/02-step-connect-device.js +++ b/src/components/modals/Send/02-step-connect-device.js @@ -1,7 +1,37 @@ +// @flow + import React from 'react' -function StepConnectDevice() { - return
step connect device
+import DeviceMonit from 'components/DeviceMonit' +import type { Account } from 'types/common' + +type Props = { + account: Account | null, + isDeviceReady: boolean, + onChange: Function, +} + +function StepConnectDevice(props: Props) { + const { account, isDeviceReady, onChange } = props + const setReady = onChange('isDeviceReady') + if (!account) { + return null + } + return ( +
+ { + if (status === 'appOpened' && !isDeviceReady) { + setReady(true) + } + if (status !== 'appOpened' && isDeviceReady) { + setReady(false) + } + }} + /> +
+ ) } export default StepConnectDevice diff --git a/src/components/modals/Send/Footer.js b/src/components/modals/Send/Footer.js index ae910023..ed6d234a 100644 --- a/src/components/modals/Send/Footer.js +++ b/src/components/modals/Send/Footer.js @@ -17,9 +17,10 @@ type Props = { account: Account, amount: DoubleVal, onNext: Function, + canNext: boolean, } -function Footer({ account, amount, t, onNext }: Props) { +function Footer({ account, amount, t, onNext, canNext }: Props) { return ( @@ -42,7 +43,7 @@ function Footer({ account, amount, t, onNext }: Props) { - diff --git a/src/components/modals/Send/index.js b/src/components/modals/Send/index.js index 098db49e..675f4968 100644 --- a/src/components/modals/Send/index.js +++ b/src/components/modals/Send/index.js @@ -25,6 +25,7 @@ type Props = { type State = { stepIndex: number, + isDeviceReady: boolean, amount: DoubleVal, account: Account | null, recipientAddress: string, @@ -40,6 +41,7 @@ const GET_STEPS = t => [ const INITIAL_STATE = { stepIndex: 0, + isDeviceReady: false, account: null, recipientAddress: '', amount: { @@ -54,6 +56,24 @@ class SendModal extends PureComponent { _steps = GET_STEPS(this.props.t) + canNext = account => { + const { stepIndex } = this.state + + // informations + if (stepIndex === 0) { + const { amount, recipientAddress } = this.state + return !!amount.left && !!recipientAddress && !!account + } + + // connect device + if (stepIndex === 1) { + const { isDeviceReady } = this.state + return !!isDeviceReady + } + + return false + } + handleReset = () => this.setState(INITIAL_STATE) handleNextStep = () => { @@ -90,6 +110,7 @@ class SendModal extends PureComponent { onHide={this.handleReset} render={({ data, onClose }) => { const acc = account || get(data, 'account', null) + const canNext = this.canNext(acc) return ( {t('send:title')} @@ -97,7 +118,15 @@ class SendModal extends PureComponent { {this.renderStep(acc)} - {acc &&