// @flow /* eslint-disable react/jsx-no-literals */ // FIXME import React, { PureComponent, Fragment } from 'react' import { translate } from 'react-i18next' import isEqual from 'lodash/isEqual' import isEmpty from 'lodash/isEmpty' import invariant from 'invariant' import logger from 'logger' import type { Device, T } from 'types/common' import type { LedgerScriptParams } from 'helpers/common' import getLatestFirmwareForDevice from 'commands/getLatestFirmwareForDevice' import installOsuFirmware from 'commands/installOsuFirmware' import installFinalFirmware from 'commands/installFinalFirmware' import installMcu from 'commands/installMcu' import DisclaimerModal from 'components/modals/UpdateFirmware/Disclaimer' import UpdateModal from 'components/modals/UpdateFirmware' import type { DeviceInfo } from 'helpers/devices/getDeviceInfo' import Tooltip from 'components/base/Tooltip' import Box, { Card } from 'components/base/Box' import Text from 'components/base/Text' import NanoS from 'icons/device/NanoS' import CheckFull from 'icons/CheckFull' import { PreventDeviceChangeRecheck } from 'components/EnsureDevice' import UpdateFirmwareButton from './UpdateFirmwareButton' export const getCleanVersion = (input: string): string => input.endsWith('-osu') ? input.replace('-osu', '') : input export type ModalStatus = 'closed' | 'disclaimer' | 'install' | 'error' | 'success' type Props = { t: T, device: Device, deviceInfo: DeviceInfo, } type State = { latestFirmware: ?LedgerScriptParams & ?{ shouldUpdateMcu: boolean }, modal: ModalStatus, } class FirmwareUpdate extends PureComponent { state = { latestFirmware: null, modal: 'closed', } componentDidMount() { this.fetchLatestFirmware() } componentDidUpdate() { if (isEmpty(this.state.latestFirmware)) { this.fetchLatestFirmware() } } componentWillUnmount() { this._unmounting = true } _unmounting = false fetchLatestFirmware = async () => { const { deviceInfo } = this.props const latestFirmware = await getLatestFirmwareForDevice.send(deviceInfo).toPromise() if ( !isEmpty(latestFirmware) && !isEqual(this.state.latestFirmware, latestFirmware) && !this._unmounting ) { this.setState({ latestFirmware }) } } installOsuFirmware = async () => { try { const { latestFirmware } = this.state const { deviceInfo, device: { path: devicePath }, } = this.props invariant(latestFirmware, 'did not find a new firmware or firmware is not set') this.setState({ modal: 'install' }) const { success } = await installOsuFirmware .send({ devicePath, firmware: latestFirmware, targetId: deviceInfo.targetId }) .toPromise() return success } catch (err) { logger.log(err) throw err } } installFinalFirmware = async () => { try { const { device } = this.props const { success } = await installFinalFirmware.send({ devicePath: device.path }).toPromise() return success } catch (err) { logger.log(err) throw err } } flashMCU = async () => { const { device } = this.props await installMcu.send({ devicePath: device.path }).toPromise() } handleCloseModal = () => this.setState({ modal: 'closed' }) handleDisclaimerModal = () => this.setState({ modal: 'disclaimer' }) handleInstallModal = () => this.setState({ modal: 'install' }) render() { const { deviceInfo, t } = this.props const { latestFirmware, modal } = this.state return ( Ledger Nano S t('app:manager.yourDeviceIsGenuine')}> {t('app:manager.firmware.installed', { version: deviceInfo.fullVersion, })} {modal !== 'closed' ? : null} {latestFirmware && ( )} ) } } export default translate()(FirmwareUpdate)