diff --git a/src/components/DeviceConnect/index.js b/src/components/DeviceConnect/index.js index dcb3014f..00917f0d 100644 --- a/src/components/DeviceConnect/index.js +++ b/src/components/DeviceConnect/index.js @@ -22,6 +22,8 @@ import IconHome from 'icons/Home' import * as IconDevice from 'icons/device' +// TODO: CHECK IF COMPONENT CAN BE REMOVED + const Step = styled(Box).attrs({ borderRadius: 1, justifyContent: 'center', @@ -147,7 +149,10 @@ type Props = { deviceSelected: ?Device, onChangeDevice: Device => void, t: T, - error: ?Error, + errors: ?{ + genuineError: ?Error, + dashboardError: ?Error, + }, } const emitChangeDevice = props => { @@ -187,7 +192,7 @@ class DeviceConnect extends PureComponent { genuineCheckStatus, withGenuineCheck, appOpened, - error, + errors, currency, t, onChangeDevice, @@ -304,11 +309,11 @@ class DeviceConnect extends PureComponent { )} - {appState.fail ? ( + {errors && (errors.genuineError || errors.dashboardError) ? ( - + ) : null} diff --git a/src/components/GenuineCheckModal/index.js b/src/components/GenuineCheckModal/index.js index a9c938a4..8b27eaa7 100644 --- a/src/components/GenuineCheckModal/index.js +++ b/src/components/GenuineCheckModal/index.js @@ -1,26 +1,16 @@ // @flow -import logger from 'logger' import React, { PureComponent } from 'react' -import { compose } from 'redux' -import { connect } from 'react-redux' import { translate } from 'react-i18next' -import type { T, Device } from 'types/common' +import type { T } from 'types/common' -import { getCurrentDevice } from 'reducers/devices' - -import DeviceConnect from 'components/DeviceConnect' -import EnsureDeviceApp from 'components/EnsureDeviceApp' import Modal, { ModalBody, ModalTitle, ModalContent } from 'components/base/Modal' - -const mapStateToProps = state => ({ - currentDevice: getCurrentDevice(state), -}) +import Workflow from 'components/Workflow' +import WorkflowDefault from 'components/Workflow/WorkflowDefault' type Props = { t: T, - currentDevice: ?Device, onGenuineCheck: (isGenuine: boolean) => void, } @@ -28,33 +18,23 @@ type State = {} class GenuineCheck extends PureComponent { renderBody = ({ onClose }) => { - const { t, currentDevice, onGenuineCheck } = this.props + const { t, onGenuineCheck } = this.props // TODO: use the real devices list. for now we force choosing only // the current device because we don't handle multi device in MVP - const reducedDevicesList = currentDevice ? [currentDevice] : [] return ( {t('app:genuinecheck.modal.title')} - { - logger.log(`status changed to ${status}`) - }} - render={({ appStatus, genuineCheckStatus, deviceSelected, error }) => ( - onGenuineCheck(isGenuine)} + renderDefault={(device, deviceInfo, isGenuine, errors) => ( + )} /> @@ -69,7 +49,4 @@ class GenuineCheck extends PureComponent { } } -export default compose( - connect(mapStateToProps), - translate(), -)(GenuineCheck) +export default translate()(GenuineCheck) diff --git a/src/components/ManagerPage/index.js b/src/components/ManagerPage/index.js index 5dea5135..6b1b48a7 100644 --- a/src/components/ManagerPage/index.js +++ b/src/components/ManagerPage/index.js @@ -6,8 +6,8 @@ import React from 'react' import type { Node } from 'react' import type { Device } from 'types/common' -import Workflow from './Workflow' -import WorkflowDefault from './WorkflowDefault' +import Workflow from 'components/Workflow' +import WorkflowWithIcon from 'components/Workflow/WorkflowWithIcon' import Dashboard from './Dashboard' type DeviceInfo = { @@ -43,7 +43,7 @@ function ManagerPage(): Node { genuineError: ?Error, }, ) => ( - { } handleOpenGenuineCheckModal = () => this.setState({ isGenuineCheckModalOpened: true }) - handleCloseGenuineCheckModal = () => this.setState({ isGenuineCheckModalOpened: false }) + handleCloseGenuineCheckModal = (cb?: Function) => + this.setState(state => ({ ...state, isGenuineCheckModalOpened: false }), () => cb && cb()) - handleGenuineCheck = async isGenuine => { - await new Promise(r => setTimeout(r, 1e3)) // let's wait a bit before closing modal - this.handleCloseGenuineCheckModal() - this.props.updateGenuineCheck({ - isDeviceGenuine: isGenuine, + handleGenuineCheck = isGenuine => { + this.handleCloseGenuineCheckModal(() => { + this.props.updateGenuineCheck({ + isDeviceGenuine: isGenuine, + }) }) } diff --git a/src/components/TriggerOnMount/index.js b/src/components/TriggerOnMount/index.js new file mode 100644 index 00000000..36923b0e --- /dev/null +++ b/src/components/TriggerOnMount/index.js @@ -0,0 +1,15 @@ +// @flow +import { PureComponent } from 'react' + +type Props = { + callback: () => void, +} + +class TriggerOnMount extends PureComponent { + componentDidMount() { + const { callback } = this.props + callback() + } +} + +export default TriggerOnMount diff --git a/src/components/ManagerPage/EnsureDashboard.js b/src/components/Workflow/EnsureDashboard.js similarity index 100% rename from src/components/ManagerPage/EnsureDashboard.js rename to src/components/Workflow/EnsureDashboard.js diff --git a/src/components/ManagerPage/EnsureDevice.js b/src/components/Workflow/EnsureDevice.js similarity index 100% rename from src/components/ManagerPage/EnsureDevice.js rename to src/components/Workflow/EnsureDevice.js diff --git a/src/components/ManagerPage/EnsureGenuine.js b/src/components/Workflow/EnsureGenuine.js similarity index 94% rename from src/components/ManagerPage/EnsureGenuine.js rename to src/components/Workflow/EnsureGenuine.js index 1391e163..edef0e2a 100644 --- a/src/components/ManagerPage/EnsureGenuine.js +++ b/src/components/Workflow/EnsureGenuine.js @@ -2,7 +2,6 @@ import { PureComponent } from 'react' import isEqual from 'lodash/isEqual' -import type { Node } from 'react' import type { Device } from 'types/common' import getIsGenuine from 'commands/getIsGenuine' @@ -20,7 +19,7 @@ type DeviceInfos = { type Props = { device: ?Device, infos: ?DeviceInfos, - children: (isGenuine: ?boolean, error: ?Error) => Node, + children: (isGenuine: ?boolean, error: ?Error) => *, } type State = { diff --git a/src/components/Workflow/WorkflowDefault.js b/src/components/Workflow/WorkflowDefault.js new file mode 100644 index 00000000..2810ea97 --- /dev/null +++ b/src/components/Workflow/WorkflowDefault.js @@ -0,0 +1,172 @@ +// @flow +/* eslint-disable react/jsx-no-literals */ + +import React from 'react' +import { Trans, translate } from 'react-i18next' +import styled from 'styled-components' +import isNull from 'lodash/isNull' +import type { Device } from 'types/common' + +import Box from 'components/base/Box' +import Spinner from 'components/base/Spinner' + +import IconCheck from 'icons/Check' +import IconExclamationCircle from 'icons/ExclamationCircle' +import IconUsb from 'icons/Usb' +import IconHome from 'icons/Home' + +const Step = styled(Box).attrs({ + borderRadius: 1, + justifyContent: 'center', + fontSize: 4, +})` + border: 1px solid + ${p => + p.validated + ? p.theme.colors.wallet + : p.hasErrors + ? p.theme.colors.alertRed + : p.theme.colors.fog}; +` + +const StepIcon = styled(Box).attrs({ + alignItems: 'center', + justifyContent: 'center', +})` + width: 64px; +` + +const StepContent = styled(Box).attrs({ + color: 'dark', + horizontal: true, + alignItems: 'center', +})` + height: 60px; + line-height: 1.2; + + strong { + font-weight: 600; + } +` + +const WrapperIconCurrency = styled(Box).attrs({ + alignItems: 'center', + justifyContent: 'center', +})` + border: 1px solid ${p => p.theme.colors[p.color]}; + border-radius: 8px; + height: 24px; + width: 24px; +` + +const StepCheck = ({ checked, hasErrors }: { checked: boolean, hasErrors?: boolean }) => ( + + {checked ? ( + + + + ) : hasErrors ? ( + + + + ) : ( + + )} + +) + +StepCheck.defaultProps = { + hasErrors: false, +} + +type DeviceInfo = { + targetId: number | string, + version: string, + final: boolean, + mcu: boolean, +} + +type Error = { + message: string, + stack: string, +} + +type Props = { + // t: T, + device: ?Device, + deviceInfo: ?DeviceInfo, + errors: { + dashboardError: ?Error, + genuineError: ?Error, + }, + isGenuine: boolean, +} + +const WorkflowDefault = ({ device, deviceInfo, errors, isGenuine }: Props) => ( + + + + + + + + + Connect your Ledger device to your computer and enter your{' '} + PIN code on your device + + + + + + + + + + + + + + + + {'Go to the '} + {'dashboard'} + {' on your device'} + + + + + + + {/* GENUINE CHECK */} + {/* ------------- */} + + + + + + + + + + + {'Confirm '} + {'authentication'} + {' on your device'} + + + + + + +) + +export default translate()(WorkflowDefault) diff --git a/src/components/ManagerPage/WorkflowDefault.js b/src/components/Workflow/WorkflowWithIcon.js similarity index 97% rename from src/components/ManagerPage/WorkflowDefault.js rename to src/components/Workflow/WorkflowWithIcon.js index 65805901..41460d0d 100644 --- a/src/components/ManagerPage/WorkflowDefault.js +++ b/src/components/Workflow/WorkflowWithIcon.js @@ -105,7 +105,7 @@ type Props = { isGenuine: boolean, } -const WorkflowDefault = ({ device, deviceInfo, errors, isGenuine, t }: Props) => ( +const WorkflowWithIcon = ({ device, deviceInfo, errors, isGenuine, t }: Props) => ( ) -export default translate()(WorkflowDefault) +export default translate()(WorkflowWithIcon) diff --git a/src/components/ManagerPage/Workflow.js b/src/components/Workflow/index.js similarity index 79% rename from src/components/ManagerPage/Workflow.js rename to src/components/Workflow/index.js index e52f701a..da3ad61a 100644 --- a/src/components/ManagerPage/Workflow.js +++ b/src/components/Workflow/index.js @@ -31,9 +31,10 @@ type Props = { genuineError: ?Error, }, ) => Node, - renderMcuUpdate: (deviceInfo: DeviceInfo) => Node, - renderFinalUpdate: (deviceInfo: DeviceInfo) => Node, - renderDashboard: (device: Device, deviceInfo: DeviceInfo) => Node, + renderMcuUpdate?: (deviceInfo: DeviceInfo) => Node, + renderFinalUpdate?: (deviceInfo: DeviceInfo) => Node, + renderDashboard?: (device: Device, deviceInfo: DeviceInfo, isGenuine: boolean) => Node, + onGenuineCheck?: (isGenuine: boolean) => void, renderError?: (dashboardError: ?Error, genuineError: ?Error) => Node, } type State = {} @@ -46,6 +47,7 @@ class Workflow extends PureComponent { renderMcuUpdate, renderError, renderDefault, + onGenuineCheck, } = this.props return ( @@ -63,16 +65,18 @@ class Workflow extends PureComponent { }) } - if (deviceInfo && deviceInfo.mcu) { + if (deviceInfo && deviceInfo.mcu && renderMcuUpdate) { return renderMcuUpdate(deviceInfo) } - if (deviceInfo && deviceInfo.final) { + if (deviceInfo && deviceInfo.final && renderFinalUpdate) { return renderFinalUpdate(deviceInfo) } if (isGenuine && deviceInfo && device && !dashboardError && !genuineError) { - return renderDashboard(device, deviceInfo) + if (onGenuineCheck) onGenuineCheck(isGenuine) + + if (renderDashboard) return renderDashboard(device, deviceInfo, isGenuine) } return renderDefault(device, deviceInfo, isGenuine, { diff --git a/src/components/modals/Debug.js b/src/components/modals/Debug.js index d1cb2905..a18abcb0 100644 --- a/src/components/modals/Debug.js +++ b/src/components/modals/Debug.js @@ -7,7 +7,7 @@ import Modal, { ModalBody, ModalTitle, ModalContent } from 'components/base/Moda import Button from 'components/base/Button' import Box from 'components/base/Box' import Input from 'components/base/Input' -import EnsureDevice from 'components/ManagerPage/EnsureDevice' +import EnsureDevice from 'components/Workflow/EnsureDevice' import { getDerivations } from 'helpers/derivations' import getAddress from 'commands/getAddress' import testInterval from 'commands/testInterval'