Browse Source

Merge branch 'polish/manager-modals' into fix/circular-ref-error

master
Gaëtan Renaudeau 7 years ago
parent
commit
fbf3ff0d13
  1. 78
      src/components/ManagerPage/AppsList.js
  2. 15
      src/helpers/apps/installApp.js
  3. 14
      src/helpers/apps/uninstallApp.js
  4. 1
      src/icons/Trash.js
  5. 4
      static/i18n/en/errors.yml

78
src/components/ManagerPage/AppsList.js

@ -1,7 +1,7 @@
// @flow
/* eslint-disable react/jsx-no-literals */ // FIXME
import React, { PureComponent } from 'react'
import React, { PureComponent, Fragment } from 'react'
import styled from 'styled-components'
import { translate } from 'react-i18next'
@ -11,17 +11,18 @@ import type { LedgerScriptParams } from 'helpers/common'
import listApps from 'commands/listApps'
import installApp from 'commands/installApp'
import uninstallApp from 'commands/uninstallApp'
import TranslatedError from 'components/TranslatedError'
import Box from 'components/base/Box'
import Modal, { ModalBody } from 'components/base/Modal'
import Modal, { ModalBody, ModalFooter, ModalTitle, ModalContent } from 'components/base/Modal'
import Tooltip from 'components/base/Tooltip'
import Text from 'components/base/Text'
import Progress from 'components/base/Progress'
import Spinner from 'components/base/Spinner'
import Button from 'components/base/Button'
import TranslatedError from 'components/TranslatedError'
import ExclamationCircle from 'icons/ExclamationCircle'
import ExclamationCircleThin from 'icons/ExclamationCircleThin'
import Update from 'icons/Update'
import Trash from 'icons/Trash'
import CheckCircle from 'icons/CheckCircle'
@ -133,41 +134,80 @@ class AppsList extends PureComponent<Props, State> {
<Modal
isOpened={status !== 'idle' && status !== 'loading'}
render={() => (
<ModalBody p={6} align="center" justify="center" style={{ height: 300 }}>
<ModalBody align="center" justify="center" style={{ height: 300 }}>
{status === 'busy' || status === 'idle' ? (
<Box align="center" justify="center" flow={3}>
{mode === 'installing' ? <Update size={30} /> : <Trash size={30} />}
<Fragment>
<ModalTitle>
{mode === 'installing' ? (
<Box color="grey">
<Update size={30} />
</Box>
) : (
<Box color="grey">
<Trash size={30} />
</Box>
)}
</ModalTitle>
<ModalContent>
<Text ff="Museo Sans|Regular" fontSize={6} color="dark">
{t(`app:manager.apps.${mode}`, { app })}
</Text>
<Box my={5} style={{ width: 250 }}>
<Box mt={6}>
<Progress style={{ width: '100%' }} infinite />
</Box>
</Box>
</ModalContent>
</Fragment>
) : status === 'error' ? (
<Box align="center" justify="center" flow={3}>
<Fragment>
<ModalContent grow align="center" justify="center" mt={3}>
<Box color="alertRed">
<ExclamationCircleThin size={44} />
</Box>
<Box
color="black"
mt={4}
fontSize={6}
ff="Museo Sans|Regular"
textAlign="center"
style={{ maxWidth: 350 }}
>
<TranslatedError error={error} />
<Button primary onClick={this.handleCloseModal}>
close
</Button>
</Box>
</ModalContent>
<ModalFooter horizontal justifyContent="flex-end" style={{ width: '100%' }}>
<Button primary padded onClick={this.handleCloseModal}>
{t('app:common.close')}
</Button>
</ModalFooter>
</Fragment>
) : status === 'success' ? (
<Box align="center" justify="center" flow={3}>
<Fragment>
<ModalContent grow align="center" justify="center" mt={3}>
<Box color="positiveGreen">
<CheckCircle size={30} />
<CheckCircle size={44} />
</Box>
<Text ff="Museo Sans|Regular" fontSize={6} color="dark">
<Box
color="black"
mt={4}
fontSize={6}
ff="Museo Sans|Regular"
textAlign="center"
style={{ maxWidth: 350 }}
>
{t(
`app:manager.apps.${
mode === 'installing' ? 'installSuccess' : 'uninstallSuccess'
}`,
{ app },
)}
</Text>
<Button primary onClick={this.handleCloseModal}>
close
</Button>
</Box>
</ModalContent>
<ModalFooter horizontal justifyContent="flex-end" style={{ width: '100%' }}>
<Button primary padded onClick={this.handleCloseModal}>
{t('app:common.close')}
</Button>
</ModalFooter>
</Fragment>
) : null}
</ModalBody>
)}

15
src/helpers/apps/installApp.js

@ -7,6 +7,19 @@ import { createDeviceSocket } from 'helpers/socket'
import type { LedgerScriptParams } from 'helpers/common'
import createCustomErrorClass from '../createCustomErrorClass'
const CannotInstall = createCustomErrorClass('CannotInstall')
function remapError(promise) {
return promise.catch((e: Error) => {
if (e.message.endsWith('6982')) {
throw new CannotInstall()
}
throw e
})
}
/**
* Install an app on the device
*/
@ -21,5 +34,5 @@ export default async function installApp(
firmwareKey: app.firmware_key,
}
const url = `${BASE_SOCKET_URL_SECURE}/install?${qs.stringify(params)}`
return createDeviceSocket(transport, url).toPromise()
return remapError(createDeviceSocket(transport, url).toPromise())
}

14
src/helpers/apps/uninstallApp.js

@ -6,6 +6,18 @@ import { BASE_SOCKET_URL_SECURE } from 'config/constants'
import { createDeviceSocket } from 'helpers/socket'
import type { LedgerScriptParams } from 'helpers/common'
import createCustomErrorClass from '../createCustomErrorClass'
const CannotUninstall = createCustomErrorClass('CannotUninstall')
function remapError(promise) {
return promise.catch((e: Error) => {
if (e.message.endsWith('6a83')) {
throw new CannotUninstall()
}
throw e
})
}
/**
* Install an app on the device
@ -22,5 +34,5 @@ export default async function uninstallApp(
firmwareKey: app.delete_key,
}
const url = `${BASE_SOCKET_URL_SECURE}/install?${qs.stringify(params)}`
return createDeviceSocket(transport, url).toPromise()
return remapError(createDeviceSocket(transport, url).toPromise())
}

1
src/icons/Trash.js

@ -5,6 +5,7 @@ import React from 'react'
const path = (
<g transform="translate(670.57 190.38)">
<path
fill="currentColor"
d="m-658.54-187.18h3.2002a0.80037 0.80037 0 0 1 0 1.5993h-0.80049v10.4a2.3999 2.3999 0 0 1-2.3999 2.3999h-8.0001a2.3999 2.3999 0 0 1-2.3999-2.3999v-10.4h-0.79878a0.80037 0.80037 0 1 1 0-1.5993h3.1991v-0.80049a2.3999 2.3999 0 0 1 2.3999-2.3999h3.2003a2.3999 2.3999 0 0 1 2.3999 2.3999zm-1.5993 0v-0.80049a0.80037 0.80037 0 0 0-0.80049-0.80049h-3.2003a0.80037 0.80037 0 0 0-0.79878 0.80049v0.80049zm0.80049 1.5993a0.84357 0.84357 0 0 1-1e-3 0h-6.3995a0.84357 0.84357 0 0 1-2e-3 0h-1.5976v10.4c0 0.44224 0.35825 0.79877 0.79878 0.79877h8.0001a0.80037 0.80037 0 0 0 0.8005-0.79877v-10.4zm-5.6004 3.2003a0.80037 0.80037 0 1 1 1.5993 0v4.7997a0.80037 0.80037 0 0 1-1.5993 0zm3.1992 0a0.80049 0.80049 0 1 1 1.601 0v4.7997a0.80049 0.80049 0 0 1-1.601 0z"
strokeWidth="1.2"
/>

4
static/i18n/en/errors.yml

@ -16,8 +16,10 @@ NoAddressesFound: 'No accounts found'
UserRefusedOnDevice: Transaction have been aborted
WebsocketConnectionError: An error occurred with the socket connection
WebsocketConnectionFailed: Failed to establish a socket connection
DeviceSocketFail: Device socket failure
DeviceSocketFail: 'Device socket failure ({{message}})'
DeviceSocketNoBulkStatus: Device socket failure (bulk)
DeviceSocketNoHandler: Device socket failure (handler {{query}})
LatestMCUInstalledError: The latest MCU is already installed on the Device
HardResetFail: Hard reset failure
CannotUninstall: Cannot uninstall app
CannotInstall: Cannot install app

Loading…
Cancel
Save