155 lines
3.6 KiB
155 lines
3.6 KiB
// @flow
|
|
|
|
import React, { PureComponent, Fragment } from 'react'
|
|
import styled from 'styled-components'
|
|
import { connect } from 'react-redux'
|
|
import { timeout } from 'rxjs/operators/timeout'
|
|
|
|
import { DEVICE_INFOS_TIMEOUT } from 'config/constants'
|
|
import { i } from 'helpers/staticPath'
|
|
import { getCurrentDevice } from 'reducers/devices'
|
|
import { createCancelablePolling } from 'helpers/promise'
|
|
import getDeviceInfo from 'commands/getDeviceInfo'
|
|
|
|
import Box from 'components/base/Box'
|
|
import Text from 'components/base/Text'
|
|
import Progress from 'components/base/Progress'
|
|
|
|
import type { Device } from 'types/common'
|
|
|
|
import type { StepProps } from '../'
|
|
|
|
const Container = styled(Box).attrs({
|
|
alignItems: 'center',
|
|
fontSize: 4,
|
|
color: 'dark',
|
|
})``
|
|
|
|
const Title = styled(Box).attrs({
|
|
ff: 'Museo Sans|Regular',
|
|
fontSize: 5,
|
|
mb: 3,
|
|
})``
|
|
|
|
const Bullet = styled.span`
|
|
font-weight: 600;
|
|
color: #142533;
|
|
`
|
|
|
|
const Separator = styled(Box).attrs({
|
|
color: 'fog',
|
|
})`
|
|
height: 1px;
|
|
width: 100%;
|
|
background-color: currentColor;
|
|
`
|
|
|
|
const mapStateToProps = state => ({
|
|
device: getCurrentDevice(state),
|
|
})
|
|
|
|
type Props = StepProps & { device?: Device }
|
|
|
|
type State = {
|
|
installing: boolean,
|
|
}
|
|
|
|
class StepFlashMcu extends PureComponent<Props, State> {
|
|
state = {
|
|
installing: false,
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.install()
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this._unsubConnect()
|
|
}
|
|
|
|
waitForDeviceInBootloader = () => {
|
|
const { unsubscribe, promise } = createCancelablePolling(async () => {
|
|
const { device } = this.props
|
|
if (!device) {
|
|
throw new Error('No device')
|
|
}
|
|
const deviceInfo = await getDeviceInfo
|
|
.send({ devicePath: device.path })
|
|
.pipe(timeout(DEVICE_INFOS_TIMEOUT))
|
|
.toPromise()
|
|
if (!deviceInfo.isBootloader) {
|
|
throw new Error('Device is not in bootloader')
|
|
}
|
|
return { device, deviceInfo }
|
|
})
|
|
this._unsubConnect = unsubscribe
|
|
return promise
|
|
}
|
|
|
|
install = async () => {
|
|
await this.waitForDeviceInBootloader()
|
|
const { flashMcu, installFinalFirmware, transitionTo } = this.props
|
|
this.setState({ installing: true })
|
|
await flashMcu()
|
|
const finalSuccess = await installFinalFirmware()
|
|
|
|
if (finalSuccess) {
|
|
transitionTo('finish')
|
|
}
|
|
}
|
|
|
|
renderBody = () => {
|
|
const { installing } = this.state
|
|
const { t } = this.props
|
|
|
|
if (installing) {
|
|
return (
|
|
<Box mx={7}>
|
|
<Progress infinite style={{ width: '100%' }} />
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Fragment>
|
|
<Box mx={7}>
|
|
<Text ff="Open Sans|Regular" align="center" color="smoke">
|
|
<Bullet>{'1.'}</Bullet>
|
|
{t('app:manager.modal.mcuFirst')}
|
|
</Text>
|
|
<img
|
|
src={i('logos/unplugDevice.png')}
|
|
style={{ width: '100%', maxWidth: 368, marginTop: 30 }}
|
|
alt={t('app:manager.modal.mcuFirst')}
|
|
/>
|
|
</Box>
|
|
<Separator my={6} />
|
|
<Box mx={7}>
|
|
<Text ff="Open Sans|Regular" align="center" color="smoke">
|
|
<Bullet>{'2.'}</Bullet>
|
|
{t('app:manager.modal.mcuSecond')}
|
|
</Text>
|
|
<img
|
|
src={i('logos/bootloaderMode.png')}
|
|
style={{ width: '100%', maxWidth: 368, marginTop: 30 }}
|
|
alt={t('app:manager.modal.mcuFirst')}
|
|
/>
|
|
</Box>
|
|
</Fragment>
|
|
)
|
|
}
|
|
|
|
_unsubConnect: *
|
|
|
|
render() {
|
|
const { t } = this.props
|
|
return (
|
|
<Container>
|
|
<Title>{t('app:manager.modal.mcuTitle')}</Title>
|
|
{this.renderBody()}
|
|
</Container>
|
|
)
|
|
}
|
|
}
|
|
|
|
export default connect(mapStateToProps)(StepFlashMcu)
|
|
|