Browse Source

fixes #1114 plus some other little bugs (#1162)

master
NastiaS 7 years ago
committed by Gaëtan Renaudeau
parent
commit
212b1a062d
  1. 14
      src/components/IsUnlocked.js
  2. 8
      src/components/Onboarding/steps/SetPassword.js
  3. 15
      src/components/SelectExchange.js
  4. 15
      src/components/SettingsPage/DisablePasswordModal.js
  5. 14
      src/components/SettingsPage/PasswordForm.js
  6. 11
      src/components/SettingsPage/PasswordModal.js
  7. 52
      src/components/modals/AccountSettingRenderBody.js
  8. 14
      src/components/modals/ReleaseNotes/ReleaseNotesBody.js
  9. 25
      src/components/modals/Send/steps/04-step-confirmation.js
  10. 17
      static/i18n/en/app.json
  11. 20
      static/i18n/en/errors.json

14
src/components/IsUnlocked.js

@ -20,11 +20,15 @@ import hardReset from 'helpers/hardReset'
import { fetchAccounts } from 'actions/accounts'
import { isLocked, unlock } from 'reducers/application'
import { createCustomErrorClass } from 'helpers/errors'
import Box from 'components/base/Box'
import InputPassword from 'components/base/InputPassword'
import Button from './base/Button/index'
import ConfirmModal from './base/Modal/ConfirmModal'
const PasswordIncorrectError = createCustomErrorClass('PasswordIncorrect')
type InputValue = {
password: string,
}
@ -39,7 +43,7 @@ type Props = {
}
type State = {
inputValue: InputValue,
incorrectPassword: boolean,
incorrectPassword: ?Error,
isHardResetting: boolean,
isHardResetModalOpened: boolean,
}
@ -58,7 +62,7 @@ const defaultState = {
inputValue: {
password: '',
},
incorrectPassword: false,
incorrectPassword: null,
isHardResetting: false,
isHardResetModalOpened: false,
}
@ -104,7 +108,7 @@ class IsUnlocked extends Component<Props, State> {
...prev.inputValue,
[key]: value,
},
incorrectPassword: false,
incorrectPassword: null,
}))
handleSubmit = async (e: SyntheticEvent<HTMLFormElement>) => {
@ -122,7 +126,7 @@ class IsUnlocked extends Component<Props, State> {
...defaultState,
})
} else {
this.setState({ incorrectPassword: true })
this.setState({ incorrectPassword: new PasswordIncorrectError() })
}
}
@ -177,7 +181,7 @@ class IsUnlocked extends Component<Props, State> {
type="password"
onChange={this.handleChangeInput('password')}
value={inputValue.password}
error={incorrectPassword && t('app:password.errorMessageIncorrectPassword')}
error={incorrectPassword}
/>
</Box>
<Button type="button" mt={3} small onClick={this.handleOpenHardResetModal}>

8
src/components/Onboarding/steps/SetPassword.js

@ -28,14 +28,12 @@ type State = {
currentPassword: string,
newPassword: string,
confirmPassword: string,
incorrectPassword: boolean,
}
const INITIAL_STATE = {
currentPassword: '',
newPassword: '',
confirmPassword: '',
incorrectPassword: false,
}
class SetPassword extends PureComponent<StepProps, State> {
@ -59,9 +57,6 @@ class SetPassword extends PureComponent<StepProps, State> {
}
handleInputChange = (key: string) => (value: string) => {
if (this.state.incorrectPassword) {
this.setState({ incorrectPassword: false })
}
this.setState({ [key]: value })
}
@ -74,7 +69,7 @@ class SetPassword extends PureComponent<StepProps, State> {
render() {
const { nextStep, prevStep, t, settings, onboarding } = this.props
const { newPassword, currentPassword, incorrectPassword, confirmPassword } = this.state
const { newPassword, currentPassword, confirmPassword } = this.state
const isPasswordEnabled = settings.password.isEnabled === true
@ -119,7 +114,6 @@ class SetPassword extends PureComponent<StepProps, State> {
newPassword={newPassword}
currentPassword={currentPassword}
confirmPassword={confirmPassword}
incorrectPassword={incorrectPassword}
isValid={this.isValid}
onChange={this.handleInputChange}
t={t}

15
src/components/SelectExchange.js

@ -8,7 +8,8 @@ import logger from 'logger'
import Track from 'analytics/Track'
import Select from 'components/base/Select'
import Text from 'components/base/Text'
import Box from 'components/base/Box'
import TranslatedError from 'components/TranslatedError'
import CounterValues from 'helpers/countervalues'
import type { T } from 'types/common'
@ -101,9 +102,15 @@ class SelectExchange extends Component<
const value = options.find(e => e.id === exchangeId)
return error ? (
<Text ff="Open Sans|SemiBold" color="dark" fontSize={4}>
{t('app:common.error.load')}
</Text>
<Box
style={{ wordWrap: 'break-word', width: 250 }}
color="alertRed"
ff="Open Sans|SemiBold"
fontSize={3}
textAlign="center"
>
<TranslatedError error={error} />
</Box>
) : (
<Fragment>
{exchanges ? (

15
src/components/SettingsPage/DisablePasswordModal.js

@ -2,6 +2,7 @@
import React, { PureComponent } from 'react'
import bcrypt from 'bcryptjs'
import { createCustomErrorClass } from 'helpers/errors'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
@ -11,6 +12,8 @@ import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'compone
import type { T } from 'types/common'
const PasswordIncorrectError = createCustomErrorClass('PasswordIncorrect')
type Props = {
t: T,
onClose: Function,
@ -21,12 +24,12 @@ type Props = {
type State = {
currentPassword: string,
incorrectPassword: boolean,
incorrectPassword: ?Error,
}
const INITIAL_STATE = {
currentPassword: '',
incorrectPassword: false,
incorrectPassword: null,
}
// TODO: combine with the refactored password form
@ -42,7 +45,7 @@ class DisablePasswordModal extends PureComponent<Props, State> {
const { isPasswordEnabled, currentPasswordHash, onChangePassword } = this.props
if (isPasswordEnabled) {
if (!bcrypt.compareSync(currentPassword, currentPasswordHash)) {
this.setState({ incorrectPassword: true })
this.setState({ incorrectPassword: new PasswordIncorrectError() })
return
}
onChangePassword('')
@ -53,7 +56,7 @@ class DisablePasswordModal extends PureComponent<Props, State> {
handleInputChange = (key: string) => (value: string) => {
if (this.state.incorrectPassword) {
this.setState({ incorrectPassword: false })
this.setState({ incorrectPassword: null })
}
this.setState({ [key]: value })
}
@ -87,9 +90,7 @@ class DisablePasswordModal extends PureComponent<Props, State> {
id="password"
onChange={this.handleInputChange('currentPassword')}
value={currentPassword}
error={
incorrectPassword && t('app:password.errorMessageIncorrectPassword')
}
error={incorrectPassword}
/>
</Box>
)}

14
src/components/SettingsPage/PasswordForm.js

@ -6,15 +6,19 @@ import Box from 'components/base/Box'
import InputPassword from 'components/base/InputPassword'
import Label from 'components/base/Label'
import { createCustomErrorClass } from 'helpers/errors'
import type { T } from 'types/common'
const PasswordsDontMatchError = createCustomErrorClass('PasswordsDontMatch')
type Props = {
t: T,
isPasswordEnabled: boolean,
currentPassword: string,
newPassword: string,
confirmPassword: string,
incorrectPassword: boolean,
incorrectPassword?: ?Error,
onSubmit: Function,
isValid: () => boolean,
onChange: Function,
@ -47,7 +51,7 @@ class PasswordForm extends PureComponent<Props> {
id="currentPassword"
onChange={onChange('currentPassword')}
value={currentPassword}
error={incorrectPassword && t('app:password.errorMessageIncorrectPassword')}
error={incorrectPassword}
/>
</Box>
)}
@ -70,11 +74,7 @@ class PasswordForm extends PureComponent<Props> {
id="confirmPassword"
onChange={onChange('confirmPassword')}
value={confirmPassword}
error={
!isValid() &&
confirmPassword.length > 0 &&
t('app:password.errorMessageNotMatchingPassword')
}
error={!isValid() && confirmPassword.length > 0 && new PasswordsDontMatchError()}
/>
</Box>
</Box>

11
src/components/SettingsPage/PasswordModal.js

@ -5,12 +5,15 @@ import bcrypt from 'bcryptjs'
import type { T } from 'types/common'
import { createCustomErrorClass } from 'helpers/errors'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'components/base/Modal'
import PasswordForm from './PasswordForm'
const PasswordIncorrectError = createCustomErrorClass('PasswordIncorrect')
type Props = {
t: T,
onClose: () => void,
@ -23,14 +26,14 @@ type State = {
currentPassword: string,
newPassword: string,
confirmPassword: string,
incorrectPassword: boolean,
incorrectPassword: ?Error,
}
const INITIAL_STATE = {
currentPassword: '',
newPassword: '',
confirmPassword: '',
incorrectPassword: false,
incorrectPassword: null,
}
class PasswordModal extends PureComponent<Props, State> {
@ -49,7 +52,7 @@ class PasswordModal extends PureComponent<Props, State> {
const { isPasswordEnabled, currentPasswordHash, onChangePassword } = this.props
if (isPasswordEnabled) {
if (!bcrypt.compareSync(currentPassword, currentPasswordHash)) {
this.setState({ incorrectPassword: true })
this.setState({ incorrectPassword: new PasswordIncorrectError() })
return
}
onChangePassword(newPassword)
@ -60,7 +63,7 @@ class PasswordModal extends PureComponent<Props, State> {
handleInputChange = (key: string) => (value: string) => {
if (this.state.incorrectPassword) {
this.setState({ incorrectPassword: false })
this.setState({ incorrectPassword: null })
}
this.setState({ [key]: value })
}

52
src/components/modals/AccountSettingRenderBody.js

@ -17,6 +17,8 @@ import { setDataModal } from 'reducers/modals'
import { getBridgeForCurrency } from 'bridge'
import { createCustomErrorClass } from 'helpers/errors'
import TrackPage from 'analytics/TrackPage'
import Spoiler from 'components/base/Spoiler'
import CryptoCurrencyIcon from 'components/CryptoCurrencyIcon'
@ -34,11 +36,14 @@ import {
ConfirmModal,
} from 'components/base/Modal'
const AccountNameRequiredError = createCustomErrorClass('AccountNameRequired')
const EnpointConfigError = createCustomErrorClass('EnpointConfig')
type State = {
accountName: ?string,
accountUnit: ?Unit,
endpointConfig: ?string,
accountNameError: boolean,
accountNameError: ?Error,
endpointConfigError: ?Error,
isRemoveAccountModalOpen: boolean,
}
@ -67,7 +72,7 @@ const defaultState = {
accountName: null,
accountUnit: null,
endpointConfig: null,
accountNameError: false,
accountNameError: null,
endpointConfigError: null,
isRemoveAccountModalOpen: false,
}
@ -116,7 +121,7 @@ class HelperComp extends PureComponent<Props, State> {
}
} catch (endpointConfigError) {
if (handleChangeEndpointConfig_id === this.handleChangeEndpointConfig_id) {
this.setState({ endpointConfigError })
this.setState({ endpointConfigError: new EnpointConfigError() })
}
}
}
@ -133,18 +138,24 @@ class HelperComp extends PureComponent<Props, State> {
const { updateAccount, setDataModal } = this.props
const { accountName, accountUnit, endpointConfig, endpointConfigError } = this.state
const name = validateNameEdition(account, accountName)
account = {
...account,
unit: accountUnit || account.unit,
name,
}
if (endpointConfig && !endpointConfigError) {
account.endpointConfig = endpointConfig
if (!account.name.length) {
this.setState({ accountNameError: new AccountNameRequiredError() })
} else if (!endpointConfigError) {
const name = validateNameEdition(account, accountName)
account = {
...account,
unit: accountUnit || account.unit,
name,
}
if (endpointConfig && !endpointConfigError) {
account.endpointConfig = endpointConfig
}
updateAccount(account)
setDataModal(MODAL_SETTINGS_ACCOUNT, { account })
onClose()
}
updateAccount(account)
setDataModal(MODAL_SETTINGS_ACCOUNT, { account })
onClose()
}
handleFocus = (e: any, name: string) => {
@ -152,7 +163,10 @@ class HelperComp extends PureComponent<Props, State> {
switch (name) {
case 'accountName':
this.setState({ accountNameError: false })
this.setState({ accountNameError: null })
break
case 'endpointConfig':
this.setState({ endpointConfigError: null })
break
default:
break
@ -214,7 +228,7 @@ class HelperComp extends PureComponent<Props, State> {
maxLength={MAX_ACCOUNT_NAME_SIZE}
onChange={this.handleChangeName}
onFocus={e => this.handleFocus(e, 'accountName')}
error={accountNameError && new Error(t('app:account.settings.accountName.error'))}
error={accountNameError}
/>
</Box>
</Container>
@ -250,11 +264,7 @@ class HelperComp extends PureComponent<Props, State> {
}
onChange={this.handleChangeEndpointConfig}
onFocus={e => this.handleFocus(e, 'endpointConfig')}
error={
endpointConfigError
? new Error(t('app:account.settings.endpointConfig.error'))
: null
}
error={endpointConfigError}
/>
</Box>
</Container>

14
src/components/modals/ReleaseNotes/ReleaseNotesBody.js

@ -11,8 +11,9 @@ import GrowScroll from 'components/base/GrowScroll'
import Text from 'components/base/Text'
import Spinner from 'components/base/Spinner'
import GradientBox from 'components/GradientBox'
import TranslatedError from 'components/TranslatedError'
import TrackPage from 'analytics/TrackPage'
import Markdow, { Notes } from 'components/base/Markdown'
import Markdown, { Notes } from 'components/base/Markdown'
import { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal'
import type { T } from 'types/common'
@ -79,14 +80,21 @@ class ReleaseNotesBody extends PureComponent<Props, State> {
return notes.map(note => (
<Notes mb={6} key={note.tag_name}>
<Title>{t('app:releaseNotes.version', { versionNb: note.tag_name })}</Title>
<Markdow>{note.body}</Markdow>
<Markdown>{note.body}</Markdown>
</Notes>
))
} else if (error) {
return (
<Notes>
<Title>{t('app:releaseNotes.version', { versionNb: version })}</Title>
<Markdow>{t('app:common.error.load')}</Markdow>
<Box
style={{ wordWrap: 'break-word' }}
color="alertRed"
ff="Open Sans|SemiBold"
fontSize={3}
>
<TranslatedError error={error} />
</Box>
</Notes>
)
}

25
src/components/modals/Send/steps/04-step-confirmation.js

@ -49,23 +49,28 @@ export default function StepConfirmation({ t, optimisticOperation, error }: Step
: error
? colors.alertRed
: colors.grey
const tPrefix = optimisticOperation
? 'app:send.steps.confirmation.success'
: error
? 'app:send.steps.confirmation.error'
: 'app:send.steps.confirmation.pending'
const translatedErrTitle = error ? <TranslatedError error={error} /> || '' : ''
const translatedErrDesc = error ? <TranslatedError error={error} field="description" /> || '' : ''
return (
<Container>
<TrackPage category="Send Flow" name="Step 4" />
<span style={{ color: iconColor }}>
<Icon size={43} />
</span>
<Title>{translatedErrTitle || t(`${tPrefix}.title`)}</Title>
<Title>
{error ? (
<TranslatedError error={error} />
) : optimisticOperation ? (
t('app:send.steps.confirmation.success.title')
) : (
t('app:send.steps.confirmation.pending.title')
)}
</Title>
<Text style={{ userSelect: 'text' }} color="smoke">
{optimisticOperation ? multiline(t(`${tPrefix}.text`)) : error ? translatedErrDesc : null}
{optimisticOperation ? (
multiline(t('app:send.steps.confirmation.success.text'))
) : error ? (
<TranslatedError error={error} field="description" />
) : null}
</Text>
</Container>
)
@ -109,7 +114,7 @@ export function StepConfirmationFooter({
transitionTo('amount')
}}
>
{t('app:send.steps.confirmation.error.cta')}
{t('app:common.retry')}
</Button>
) : null}
</Fragment>

17
static/i18n/en/app.json

@ -51,9 +51,6 @@
"error": "Synchronization error",
"refresh": "Refresh",
"ago": "Synced {{time}}"
},
"error": {
"load": "Unable to load"
}
},
"buttons": {
@ -97,8 +94,7 @@
"advancedLogs": "Advanced logs",
"accountName": {
"title": "Account name",
"desc": "Describe this account",
"error": "An account name is required"
"desc": "Describe this account"
},
"unit": {
"title": "Unit",
@ -106,8 +102,7 @@
},
"endpointConfig": {
"title": "Node",
"desc": "The API node to use",
"error": "Invalid endpoint"
"desc": "The API node to use"
}
}
},
@ -339,10 +334,10 @@
"confirmation": {
"title": "Confirmation",
"success": {
"title": "Transaction sent",
"text":
"The transaction has been signed and sent to the network. Your account balance will update once the blockchain has confirmed the transaction.",
"cta": "View operation details"
},
"error": {
"cta": "Retry"
}
}
}
@ -452,8 +447,6 @@
}
},
"password": {
"errorMessageIncorrectPassword": "The password you entered is incorrect",
"errorMessageNotMatchingPassword": "Passwords don't match",
"inputFields": {
"newPassword": {
"label": "New password"

20
static/i18n/en/errors.json

@ -3,6 +3,10 @@
"title": "{{message}}",
"description": "Something went wrong. Please retry or contact us."
},
"AccountNameRequired": {
"title": "An account name is required",
"description": "Please provide with an account name"
},
"BtcUnmatchedApp": {
"title": "That's the wrong app",
"description": "Open the ‘{{managerAppName}}’ app on your device"
@ -31,6 +35,10 @@
"title": "Oops, device was disconnected",
"description": "The connection to the device was lost, so please try again."
},
"EnpointConfig": {
"title": "Invalid endpoint",
"description": "Please provide with a valid endpoint"
},
"FeeEstimationFailed": {
"title": "Sorry, fee estimation failed",
"description": "Try setting a custom fee (status: {{status}})"
@ -93,6 +101,18 @@
"title": "Oops, not enough balance",
"description": "Make sure the account to debit has sufficient balance"
},
"PasswordsDontMatch": {
"title": "Passwords don't match",
"description": "Please try again"
},
"PasswordIncorrect": {
"title": "The password you entered is incorrect",
"description": "Please try again"
},
"SelectExchangesLoadError": {
"title": "Unable to load",
"description": "Can't load the exchanges"
},
"TimeoutError": {
"title": "Oops, a time out occurred",
"description": "It took too long for the server to respond."

Loading…
Cancel
Save