From ba93180baf2fb18e91596b9d90f98343beeb8cbc Mon Sep 17 00:00:00 2001 From: Thibaut Boustany Date: Wed, 22 Aug 2018 15:54:40 +0200 Subject: [PATCH 1/2] Restore merging master into develop This reverts commit 915d2ae7d2afe611dc23ed062ca6eb23951c6bf4. --- package.json | 4 +- src/components/ExchangePage/index.js | 19 ++++ src/components/QRCodeCameraPickerCanvas.js | 2 +- src/components/RecipientAddress/index.js | 4 +- .../AddAccounts/steps/04-step-finish.js | 2 +- .../modals/Send/fields/RecipientField.js | 34 +++++-- src/config/errors.js | 1 + src/config/urls.js | 5 +- static/i18n/en/app.json | 7 +- static/i18n/en/errors.json | 3 + static/images/logos/exchanges/genesis.svg | 6 ++ static/images/logos/exchanges/luno.svg | 14 +++ static/images/logos/exchanges/shapeshift.svg | 93 +++++++++++++++++++ yarn.lock | 6 +- 14 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 static/images/logos/exchanges/genesis.svg create mode 100644 static/images/logos/exchanges/luno.svg create mode 100644 static/images/logos/exchanges/shapeshift.svg diff --git a/package.json b/package.json index 6cea84ba..eeeac8c0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "productName": "Ledger Live", "description": "Ledger Live - Desktop", "repository": "https://github.com/LedgerHQ/ledger-live-desktop", - "version": "1.1.6", + "version": "1.1.7", "author": "Ledger", "license": "MIT", "scripts": { @@ -39,7 +39,7 @@ "@ledgerhq/hw-transport": "^4.13.0", "@ledgerhq/hw-transport-node-hid": "4.22.0", "@ledgerhq/ledger-core": "2.0.0-rc.6", - "@ledgerhq/live-common": "3.0.0", + "@ledgerhq/live-common": "3.0.2", "animated": "^0.2.2", "async": "^2.6.1", "axios": "^0.18.0", diff --git a/src/components/ExchangePage/index.js b/src/components/ExchangePage/index.js index 6f40ae6c..9e612a78 100644 --- a/src/components/ExchangePage/index.js +++ b/src/components/ExchangePage/index.js @@ -5,6 +5,7 @@ import { translate } from 'react-i18next' import type { T } from 'types/common' import { urls } from 'config/urls' +import { i } from 'helpers/staticPath' import TrackPage from 'analytics/TrackPage' import Box from 'components/base/Box' @@ -51,6 +52,24 @@ const cards = [ url: urls.paybis, logo: , }, + { + key: 'luno', + id: 'luno', + url: urls.luno, + logo: Luno, + }, + { + key: 'shapeshift', + id: 'shapeshift', + url: urls.shapeshift, + logo: Shapeshift, + }, + { + key: 'genesis', + id: 'genesis', + url: urls.genesis, + logo: Genesis, + }, ] class ExchangePage extends PureComponent { diff --git a/src/components/QRCodeCameraPickerCanvas.js b/src/components/QRCodeCameraPickerCanvas.js index b2f6643e..c4340e72 100644 --- a/src/components/QRCodeCameraPickerCanvas.js +++ b/src/components/QRCodeCameraPickerCanvas.js @@ -155,7 +155,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 c037a150..f083cfa7 100644 --- a/src/components/modals/Send/fields/RecipientField.js +++ b/src/components/modals/Send/fields/RecipientField.js @@ -9,6 +9,8 @@ import Box from 'components/base/Box' 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' import { InvalidAddress } from 'config/errors' type Props = { @@ -22,11 +24,12 @@ type Props = { 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() @@ -41,7 +44,9 @@ class RecipientField extends Component< } componentWillUnmount() { this.syncId++ + this.isUnmounted = true } + isUnmounted = false syncId = 0 async resync() { const { account, bridge, transaction } = this.props @@ -50,18 +55,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 } @@ -72,11 +90,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 ( @@ -86,7 +106,7 @@ class RecipientField extends Component< /> + + + + + diff --git a/static/images/logos/exchanges/luno.svg b/static/images/logos/exchanges/luno.svg new file mode 100644 index 00000000..e2ee1781 --- /dev/null +++ b/static/images/logos/exchanges/luno.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/static/images/logos/exchanges/shapeshift.svg b/static/images/logos/exchanges/shapeshift.svg new file mode 100644 index 00000000..5efd76eb --- /dev/null +++ b/static/images/logos/exchanges/shapeshift.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/yarn.lock b/yarn.lock index ff1b4421..23aa34ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1542,9 +1542,9 @@ npm "^5.7.1" prebuild-install "^2.2.2" -"@ledgerhq/live-common@3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-3.0.0.tgz#abbd88e351c7d0ffffabf7e8502f5b2fbecdc150" +"@ledgerhq/live-common@3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@ledgerhq/live-common/-/live-common-3.0.2.tgz#1ee5fcc6044c5a049c067978d81892f79789863c" dependencies: axios "^0.18.0" bignumber.js "^7.2.1" From 6f1dd5786e76d8289b574a514122b485a7248dd3 Mon Sep 17 00:00:00 2001 From: Thibaut Boustany Date: Wed, 22 Aug 2018 15:56:57 +0200 Subject: [PATCH 2/2] Fix merge --- src/components/modals/Send/fields/RecipientField.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/modals/Send/fields/RecipientField.js b/src/components/modals/Send/fields/RecipientField.js index f083cfa7..4fef7245 100644 --- a/src/components/modals/Send/fields/RecipientField.js +++ b/src/components/modals/Send/fields/RecipientField.js @@ -11,7 +11,6 @@ import RecipientAddress from 'components/RecipientAddress' import { track } from 'analytics/segment' import { createCustomErrorClass } from 'helpers/errors' import { CantScanQRCode } from 'config/errors' -import { InvalidAddress } from 'config/errors' type Props = { t: T, @@ -22,6 +21,8 @@ type Props = { autoFocus?: boolean, } +const InvalidAddress = createCustomErrorClass('InvalidAddress') + class RecipientField extends Component< Props, { isValid: boolean, warning: ?Error, QRCodeRefusedReason: ?Error },