From da9c37e2e5458181e8ebd1587d7350f1172c2903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Wed, 4 Jul 2018 22:05:26 +0200 Subject: [PATCH] Add HookDeviceChange + FreezeDeviceChangeEvents --- src/components/ManagerPage/AppsList.js | 2 + .../ManagerPage/HookDeviceChange.js | 69 +++++++++++++++++++ src/components/ManagerPage/index.js | 39 ++++++++--- src/components/modals/UpdateFirmware/index.js | 2 + 4 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 src/components/ManagerPage/HookDeviceChange.js diff --git a/src/components/ManagerPage/AppsList.js b/src/components/ManagerPage/AppsList.js index 22390ec3..257e6d72 100644 --- a/src/components/ManagerPage/AppsList.js +++ b/src/components/ManagerPage/AppsList.js @@ -34,6 +34,7 @@ import Update from 'icons/Update' import Trash from 'icons/Trash' import CheckCircle from 'icons/CheckCircle' +import { FreezeDeviceChangeEvents } from './HookDeviceChange' import ManagerApp, { Container as FakeManagerAppContainer } from './ManagerApp' import AppSearchBar from './AppSearchBar' @@ -170,6 +171,7 @@ class AppsList extends PureComponent { isOpened={status !== 'idle' && status !== 'loading'} render={() => ( + {status === 'busy' || status === 'idle' ? ( diff --git a/src/components/ManagerPage/HookDeviceChange.js b/src/components/ManagerPage/HookDeviceChange.js new file mode 100644 index 00000000..3f29e95c --- /dev/null +++ b/src/components/ManagerPage/HookDeviceChange.js @@ -0,0 +1,69 @@ +// @flow + +import { PureComponent } from 'react' +import { createStructuredSelector } from 'reselect' +import { connect } from 'react-redux' +import { getCurrentDevice } from 'reducers/devices' +import type { Device } from 'types/common' + +const hookDeviceChangeInstances = [] +let frozen = 0 +export class FreezeDeviceChangeEvents extends PureComponent<{}> { + componentDidMount() { + frozen++ + } + componentWillUnmount() { + frozen-- + if (!frozen) { + hookDeviceChangeInstances.forEach(i => i.onUnfreeze()) + } + } + render() { + return null + } +} + +/* eslint-disable react/no-multi-comp */ +class HookDeviceChange extends PureComponent<{ + device: ?Device, + onDeviceDisconnected: () => void, + onDeviceChanges: Device => void, +}> { + componentDidMount() { + const { device, onDeviceDisconnected } = this.props + if (!device && !frozen) { + onDeviceDisconnected() + } + hookDeviceChangeInstances.push(this) + } + componentDidUpdate(prevProps) { + const { device, onDeviceDisconnected, onDeviceChanges } = this.props + if (!device) { + if (frozen) { + this.onUnfreeze = onDeviceDisconnected + } else { + onDeviceDisconnected() + } + } else if (device !== prevProps.device) { + if (frozen) { + this.onUnfreeze = () => onDeviceChanges(device) + } else { + onDeviceChanges(device) + } + } + } + componentWillUnmount() { + const i = hookDeviceChangeInstances.indexOf(this) + if (i !== -1) hookDeviceChangeInstances.splice(i, 1) + } + onUnfreeze = () => {} + render() { + return null + } +} + +export default connect( + createStructuredSelector({ + device: getCurrentDevice, + }), +)(HookDeviceChange) diff --git a/src/components/ManagerPage/index.js b/src/components/ManagerPage/index.js index 3e07cbc7..7a755bbd 100644 --- a/src/components/ManagerPage/index.js +++ b/src/components/ManagerPage/index.js @@ -1,6 +1,6 @@ // @flow -import React, { PureComponent } from 'react' +import React, { PureComponent, Fragment } from 'react' import invariant from 'invariant' import { openURL } from 'helpers/linking' import { urls } from 'config/support' @@ -11,6 +11,7 @@ import type { DeviceInfo } from 'helpers/devices/getDeviceInfo' import Dashboard from './Dashboard' import ManagerGenuineCheck from './ManagerGenuineCheck' +import HookDeviceChange from './HookDeviceChange' type Props = {} @@ -20,12 +21,14 @@ type State = { deviceInfo: ?DeviceInfo, } +const INITIAL_STATE = { + isGenuine: null, + device: null, + deviceInfo: null, +} + class ManagerPage extends PureComponent { - state = { - isGenuine: null, - device: null, - deviceInfo: null, - } + state = INITIAL_STATE // prettier-ignore handleSuccessGenuine = ({ device, deviceInfo }: { device: Device, deviceInfo: DeviceInfo }) => { // eslint-disable-line react/no-unused-prop-types @@ -36,6 +39,14 @@ class ManagerPage extends PureComponent { openURL(urls.managerHelpRequest) } + onDeviceChanges = () => { + this.setState(INITIAL_STATE) + } + + onDeviceDisconnected = () => { + this.setState(INITIAL_STATE) + } + render() { const { isGenuine, device, deviceInfo } = this.state @@ -47,11 +58,17 @@ class ManagerPage extends PureComponent { invariant(deviceInfo, 'Inexistant device infos for genuine device') return ( - + + + + ) } } diff --git a/src/components/modals/UpdateFirmware/index.js b/src/components/modals/UpdateFirmware/index.js index 91c9875d..5d085176 100644 --- a/src/components/modals/UpdateFirmware/index.js +++ b/src/components/modals/UpdateFirmware/index.js @@ -12,6 +12,7 @@ import type { StepProps as DefaultStepProps, Step } from 'components/base/Steppe import type { ModalStatus } from 'components/ManagerPage/FirmwareUpdate' import type { LedgerScriptParams } from 'helpers/common' +import { FreezeDeviceChangeEvents } from '../../ManagerPage/HookDeviceChange' import StepFullFirmwareInstall from './steps/01-step-install-full-firmware' import StepFlashMcu from './steps/02-step-flash-mcu' import StepConfirmation, { StepConfirmFooter } from './steps/03-step-confirmation' @@ -136,6 +137,7 @@ class UpdateModal extends PureComponent { steps={this.STEPS} {...additionalProps} > + )}