Browse Source

Merge pull request #680 from meriadec/manager-errors

Manager errors
master
Gaëtan Renaudeau 7 years ago
committed by GitHub
parent
commit
573bc6a209
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 91
      src/components/ManagerPage/AppSearchBar.js
  2. 33
      src/components/ManagerPage/AppsList.js
  3. 14
      src/components/ManagerPage/Dashboard.js
  4. 4
      src/components/ManagerPage/UpdateFirmwareButton.js
  5. 20
      src/helpers/apps/installApp.js
  6. 14
      src/helpers/apps/uninstallApp.js
  7. 10
      static/i18n/en/errors.yml

91
src/components/ManagerPage/AppSearchBar.js

@ -1,14 +1,12 @@
// @flow
import React, { PureComponent } from 'react'
import styled from 'styled-components'
import { color, fontSize, space } from 'styled-system'
import fontFamily from 'styles/styled/fontFamily'
import type { LedgerScriptParams } from 'helpers/common'
import React, { PureComponent, Fragment } from 'react'
import { ff } from 'styles/helpers'
import type { LedgerScriptParams } from 'helpers/common'
import Box from 'components/base/Box'
import Space from 'components/base/Space'
import Input from 'components/base/Input'
import Search from 'components/base/Search'
import SearchIcon from 'icons/Search'
@ -24,53 +22,13 @@ type State = {
focused: boolean,
}
const SearchBarWrapper = styled(Box).attrs({
horizontal: true,
borderRadius: 4,
})`
height: 42px;
width: 100%;
margin: 0 0 20px 0;
background-color: white;
padding: 0 13px;
${p =>
p.focused
? `
border: 1px solid #6490f1;
`
: 'border: 1px solid white;'};
`
const Input = styled.input.attrs({
ff: 'Open Sans|SemiBold',
color: 'dark',
mx: 3,
fontSize: 4,
})`
${space};
${fontFamily};
${fontSize};
${color};
border: 0;
flex: 1;
outline: none;
background: transparent;
&::placeholder {
color: ${p => p.theme.colors.fog};
${() => ff('Open Sans|Regular')};
}
`
class AppSearchBar extends PureComponent<Props, State> {
state = {
query: '',
focused: false,
}
handleChange = (e: any) => this.setState({ query: e.target.value })
handleChange = (query: string) => this.setState({ query })
handleFocus = (bool: boolean) => () => this.setState({ focused: bool })
@ -88,20 +46,29 @@ class AppSearchBar extends PureComponent<Props, State> {
const color = focused ? 'black' : 'grey'
return (
<Box>
<SearchBarWrapper align="center" focused={focused}>
<SearchIcon size={16} style={{ color }} />
<Input
innerRef={c => (this.input = c)}
type="text"
value={query}
onChange={this.handleChange}
onFocus={this.handleFocus(true)}
onBlur={this.handleFocus(false)}
placeholder={'Search app'}
/>
{!!query && <CrossIcon size={16} cursor="pointer" onClick={this.reset} />}
</SearchBarWrapper>
<Fragment>
<Input
innerRef={c => (this.input = c)}
type="text"
value={query}
onChange={this.handleChange}
onFocus={this.handleFocus(true)}
onBlur={this.handleFocus(false)}
placeholder={'Search app'}
renderLeft={
<Box pl={3} justify="center">
<SearchIcon size={16} style={{ color }} />
</Box>
}
renderRight={
query ? (
<Box justify="center" cursor="pointer" onClick={this.reset} px={3}>
<CrossIcon size={16} />
</Box>
) : null
}
/>
<Space of={30} />
<Search
fuseOptions={{
threshold: 0.5,
@ -111,7 +78,7 @@ class AppSearchBar extends PureComponent<Props, State> {
items={list}
render={items => children(items)}
/>
</Box>
</Fragment>
)
}
}

33
src/components/ManagerPage/AppsList.js

@ -21,7 +21,7 @@ import Spinner from 'components/base/Spinner'
import Button from 'components/base/Button'
import TranslatedError from 'components/TranslatedError'
import ExclamationCircle from 'icons/ExclamationCircle'
import IconInfoCircle from 'icons/InfoCircle'
import ExclamationCircleThin from 'icons/ExclamationCircleThin'
import Update from 'icons/Update'
import Trash from 'icons/Trash'
@ -37,8 +37,6 @@ const List = styled(Box).attrs({
flex-wrap: wrap;
`
let CACHED_APPS = null
const ICONS_FALLBACK = {
bitcoin_testnet: 'bitcoin',
}
@ -85,8 +83,7 @@ class AppsList extends PureComponent<Props, State> {
async fetchAppList() {
try {
const { targetId, version } = this.props
const appsList = CACHED_APPS || (await listApps.send({ targetId, version }).toPromise())
CACHED_APPS = appsList
const appsList = await listApps.send({ targetId, version }).toPromise()
if (!this._unmounted) {
this.setState({ appsList, status: 'idle', appsLoaded: true })
}
@ -249,19 +246,19 @@ class AppsList extends PureComponent<Props, State> {
return (
<Box flow={6}>
<Box>
<Box mb={4} color="dark" ff="Museo Sans" fontSize={5} flow={2} horizontal>
<span>{t('app:manager.apps.all')}</span>
<span>
<Tooltip
render={() => (
<Box ff="Open Sans|SemiBold" fontSize={2}>
{t('app:manager.apps.help')}
</Box>
)}
>
<ExclamationCircle size={12} />
</Tooltip>
</span>
<Box mb={4} color="dark" ff="Museo Sans" fontSize={5} flow={2} horizontal align="center">
<span style={{ lineHeight: 1 }}>{t('app:manager.apps.all')}</span>
<Tooltip
render={() => (
<Box ff="Open Sans|SemiBold" fontSize={2}>
{t('app:manager.apps.help')}
</Box>
)}
>
<Box color="grey">
<IconInfoCircle size={12} />
</Box>
</Tooltip>
</Box>
{this.renderList()}
</Box>

14
src/components/ManagerPage/Dashboard.js

@ -2,7 +2,6 @@
import React from 'react'
import { translate } from 'react-i18next'
import { EXPERIMENTAL_FIRMWARE_UPDATE } from 'config/constants'
import type { T, Device } from 'types/common'
import Box from 'components/base/Box'
@ -35,15 +34,10 @@ const Dashboard = ({ device, deviceInfo, t }: Props) => (
</Text>
</Box>
<Box mt={5}>
{EXPERIMENTAL_FIRMWARE_UPDATE ? (
<FirmwareUpdate
infos={{
targetId: deviceInfo.targetId,
version: deviceInfo.version,
}}
device={device}
/>
) : null}
<FirmwareUpdate
infos={{ targetId: deviceInfo.targetId, version: deviceInfo.version }}
device={device}
/>
</Box>
<Box mt={5}>
<AppsList device={device} targetId={deviceInfo.targetId} version={deviceInfo.version} />

4
src/components/ManagerPage/UpdateFirmwareButton.js

@ -4,6 +4,8 @@ import { translate } from 'react-i18next'
import type { T } from 'types/common'
import { EXPERIMENTAL_FIRMWARE_UPDATE } from 'config/constants'
import Button from 'components/base/Button'
import Text from 'components/base/Text'
import { getCleanVersion } from 'components/ManagerPage/FirmwareUpdate'
@ -25,7 +27,7 @@ const UpdateFirmwareButton = ({ t, firmware, installFirmware }: Props) =>
<Text ff="Open Sans|Regular" fontSize={4} style={{ marginLeft: 'auto', marginRight: 15 }}>
{t('app:manager.firmware.latest', { version: getCleanVersion(firmware.name) })}
</Text>
<Button primary onClick={installFirmware}>
<Button primary onClick={installFirmware} disabled={!EXPERIMENTAL_FIRMWARE_UPDATE}>
{t('app:manager.firmware.update')}
</Button>
</Fragment>

20
src/helpers/apps/installApp.js

@ -9,14 +9,26 @@ import type { LedgerScriptParams } from 'helpers/common'
import createCustomErrorClass from '../createCustomErrorClass'
const CannotInstall = createCustomErrorClass('CannotInstall')
const ManagerUnexpectedError = createCustomErrorClass('ManagerUnexpected')
const ManagerNotEnoughSpaceError = createCustomErrorClass('ManagerNotEnoughSpace')
const ManagerDeviceLockedError = createCustomErrorClass('ManagerDeviceLocked')
const ManagerAppAlreadyInstalledError = createCustomErrorClass('ManagerAppAlreadyInstalled')
const ManagerAppRelyOnBTCError = createCustomErrorClass('ManagerAppRelyOnBTC')
function remapError(promise) {
return promise.catch((e: Error) => {
if (e.message.endsWith('6982')) {
throw new CannotInstall()
switch (true) {
case e.message.endsWith('6982'):
throw new ManagerDeviceLockedError()
case e.message.endsWith('6a84') || e.message.endsWith('6a85'):
throw new ManagerNotEnoughSpaceError()
case e.message.endsWith('6a80') || e.message.endsWith('6a81'):
throw new ManagerAppAlreadyInstalledError()
case e.message.endsWith('6a83'):
throw new ManagerAppRelyOnBTCError()
default:
throw new ManagerUnexpectedError(e.message, { msg: e.message })
}
throw e
})
}

14
src/helpers/apps/uninstallApp.js

@ -8,14 +8,20 @@ import { createDeviceSocket } from 'helpers/socket'
import type { LedgerScriptParams } from 'helpers/common'
import createCustomErrorClass from '../createCustomErrorClass'
const CannotUninstall = createCustomErrorClass('CannotUninstall')
const ManagerUnexpectedError = createCustomErrorClass('ManagerUnexpectedError')
const ManagerDeviceLockedError = createCustomErrorClass('ManagerDeviceLocked')
const ManagerUninstallBTCDep = createCustomErrorClass('ManagerUninstallBTCDep')
function remapError(promise) {
return promise.catch((e: Error) => {
if (e.message.endsWith('6a83')) {
throw new CannotUninstall()
switch (true) {
case e.message.endsWith('6982'):
throw new ManagerDeviceLockedError()
case e.message.endsWith('6a83'):
throw new ManagerUninstallBTCDep()
default:
throw new ManagerUnexpectedError(e.message, { msg: e.message })
}
throw e
})
}

10
static/i18n/en/errors.yml

@ -21,5 +21,11 @@ DeviceSocketNoBulkStatus: Oops, device connection failed. Please try again [bulk
DeviceSocketNoHandler: Oops, device connection failed (handler {{query}}). Please try again.
LatestMCUInstalledError: MCU on device already up to date.
HardResetFail: Reset failed. Please try again.
CannotUninstall: Cannot uninstall app.
CannotInstall: Not enough room left on your device. Please uninstall some apps and try again.
ManagerAPIsFail: Our services are currently unavailable. Please try again later.
ManagerUnexpected: Unexpected error occurred ({{msg}}). Please try again later.
ManagerNotEnoughSpace: Not enough room left on your device. Please uninstall some apps and try again.
ManagerDeviceLocked: Device is locked
ManagerAppAlreadyInstalled: App is already installed
ManagerAppRelyOnBTC: You must install Bitcoin application first
ManagerUninstallBTCDep: You must uninstall other altcoins first

Loading…
Cancel
Save