diff --git a/src/components/QRCodeCameraPickerCanvas.js b/src/components/QRCodeCameraPickerCanvas.js index 271f2c4e..5081c2a5 100644 --- a/src/components/QRCodeCameraPickerCanvas.js +++ b/src/components/QRCodeCameraPickerCanvas.js @@ -156,7 +156,7 @@ export default class QRCodeCameraPickerCanvas extends Component< .catch(e => { if (this.unmounted) return this.setState({ - message: String(e.message || e), + message: String(e.message || e.name || e), }) }) } diff --git a/src/components/RecipientAddress/index.js b/src/components/RecipientAddress/index.js index 24f7895d..e825d2d4 100644 --- a/src/components/RecipientAddress/index.js +++ b/src/components/RecipientAddress/index.js @@ -47,7 +47,7 @@ const BackgroundLayer = styled(Box)` type Props = { value: string, // return false if it can't be changed (invalid info) - onChange: (string, ?{ amount?: BigNumber, currency?: CryptoCurrency }) => ?boolean, + onChange: (string, ?{ amount?: BigNumber, currency?: CryptoCurrency }) => Promise, withQrCode: boolean, } @@ -76,6 +76,8 @@ class RecipientAddress extends PureComponent { handleOnPick = (code: string) => { const { address, ...rest } = decodeURIScheme(code) + // $FlowFixMe + Object.assign(rest, { fromQRCode: true }) if (this.props.onChange(address, rest) !== false) { this.setState({ qrReaderOpened: false }) } diff --git a/src/components/modals/AddAccounts/steps/04-step-finish.js b/src/components/modals/AddAccounts/steps/04-step-finish.js index 6170af8e..312c4aea 100644 --- a/src/components/modals/AddAccounts/steps/04-step-finish.js +++ b/src/components/modals/AddAccounts/steps/04-step-finish.js @@ -52,7 +52,7 @@ export default StepFinish export const StepFinishFooter = ({ onGoStep1, t }: StepProps) => ( - diff --git a/src/components/modals/Send/fields/RecipientField.js b/src/components/modals/Send/fields/RecipientField.js index 769e1483..4fef7245 100644 --- a/src/components/modals/Send/fields/RecipientField.js +++ b/src/components/modals/Send/fields/RecipientField.js @@ -10,6 +10,7 @@ import LabelWithExternalIcon from 'components/base/LabelWithExternalIcon' import RecipientAddress from 'components/RecipientAddress' import { track } from 'analytics/segment' import { createCustomErrorClass } from 'helpers/errors' +import { CantScanQRCode } from 'config/errors' type Props = { t: T, @@ -24,11 +25,12 @@ const InvalidAddress = createCustomErrorClass('InvalidAddress') class RecipientField extends Component< Props, - { isValid: boolean, warning: ?Error }, + { isValid: boolean, warning: ?Error, QRCodeRefusedReason: ?Error }, > { state = { isValid: true, warning: null, + QRCodeRefusedReason: null, } componentDidMount() { this.resync() @@ -43,7 +45,9 @@ class RecipientField extends Component< } componentWillUnmount() { this.syncId++ + this.isUnmounted = true } + isUnmounted = false syncId = 0 async resync() { const { account, bridge, transaction } = this.props @@ -52,18 +56,31 @@ class RecipientField extends Component< const isValid = await bridge.isRecipientValid(account.currency, recipient) const warning = await bridge.getRecipientWarning(account.currency, recipient) if (syncId !== this.syncId) return + if (this.isUnmounted) return this.setState({ isValid, warning }) } - onChange = (recipient: string, maybeExtra: ?Object) => { + onChange = async (recipient: string, maybeExtra: ?Object) => { const { bridge, account, transaction, onChangeTransaction } = this.props - const { amount, currency } = maybeExtra || {} + const { QRCodeRefusedReason } = this.state + const { amount, currency, fromQRCode } = maybeExtra || {} if (currency && currency.scheme !== account.currency.scheme) return false let t = transaction if (amount) { t = bridge.editTransactionAmount(account, t, amount) } - t = bridge.editTransactionRecipient(account, t, recipient) + const warning = fromQRCode + ? await bridge.getRecipientWarning(account.currency, recipient) + : null + if (this.isUnmounted) return false + if (warning) { + // clear the input if field has warning AND has a warning + t = bridge.editTransactionRecipient(account, t, '') + this.setState({ QRCodeRefusedReason: new CantScanQRCode() }) + } else { + t = bridge.editTransactionRecipient(account, t, recipient) + if (QRCodeRefusedReason) this.setState({ QRCodeRefusedReason: null }) + } onChangeTransaction(t) return true } @@ -74,11 +91,13 @@ class RecipientField extends Component< } render() { const { bridge, account, transaction, t, autoFocus } = this.props - const { isValid, warning } = this.state + const { isValid, warning, QRCodeRefusedReason } = this.state const value = bridge.getTransactionRecipient(account, transaction) const error = - !value || isValid ? null : new InvalidAddress(null, { currencyName: account.currency.name }) + !value || isValid + ? QRCodeRefusedReason + : new InvalidAddress(null, { currencyName: account.currency.name }) return ( @@ -88,7 +107,7 @@ class RecipientField extends Component< />