diff options
author | Bruno Barbieri <bruno.barbieri@consensys.net> | 2018-08-11 01:40:06 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-11 01:40:06 +0800 |
commit | e2be22a4b722df608cb764042cc8ade6664414d8 (patch) | |
tree | 6a0c48ea06401ea8e06c14630edc7c0157f6e25c /ui/app/components/send | |
parent | be1d5a7dd959f061b52f475bf8500b943ade786c (diff) | |
parent | d0ccc59e459ecb41742b6e55a1875dfa2a2f9f87 (diff) | |
download | tangerine-wallet-browser-e2be22a4b722df608cb764042cc8ade6664414d8.tar tangerine-wallet-browser-e2be22a4b722df608cb764042cc8ade6664414d8.tar.gz tangerine-wallet-browser-e2be22a4b722df608cb764042cc8ade6664414d8.tar.bz2 tangerine-wallet-browser-e2be22a4b722df608cb764042cc8ade6664414d8.tar.lz tangerine-wallet-browser-e2be22a4b722df608cb764042cc8ade6664414d8.tar.xz tangerine-wallet-browser-e2be22a4b722df608cb764042cc8ade6664414d8.tar.zst tangerine-wallet-browser-e2be22a4b722df608cb764042cc8ade6664414d8.zip |
Merge pull request #4897 from MetaMask/qr-code-scan
QR Code Scanner
Diffstat (limited to 'ui/app/components/send')
7 files changed, 68 insertions, 4 deletions
diff --git a/ui/app/components/send/send-content/send-content.component.js b/ui/app/components/send/send-content/send-content.component.js index 7a0b1a18e..df7bcb7cc 100644 --- a/ui/app/components/send/send-content/send-content.component.js +++ b/ui/app/components/send/send-content/send-content.component.js @@ -11,6 +11,7 @@ export default class SendContent extends Component { static propTypes = { updateGas: PropTypes.func, + scanQrCode: PropTypes.func, }; render () { @@ -18,7 +19,10 @@ export default class SendContent extends Component { <PageContainerContent> <div className="send-v2__form"> <SendFromRow /> - <SendToRow updateGas={(updateData) => this.props.updateGas(updateData)} /> + <SendToRow + updateGas={(updateData) => this.props.updateGas(updateData)} + scanQrCode={ _ => this.props.scanQrCode()} + /> <SendAmountRow updateGas={(updateData) => this.props.updateGas(updateData)} /> <SendGasRow /> <SendHexDataRow /> diff --git a/ui/app/components/send/send-content/send-to-row/send-to-row.component.js b/ui/app/components/send/send-content/send-to-row/send-to-row.component.js index 892ad5d67..1163dcffc 100644 --- a/ui/app/components/send/send-content/send-to-row/send-to-row.component.js +++ b/ui/app/components/send/send-content/send-to-row/send-to-row.component.js @@ -17,6 +17,7 @@ export default class SendToRow extends Component { updateGas: PropTypes.func, updateSendTo: PropTypes.func, updateSendToError: PropTypes.func, + scanQrCode: PropTypes.func, }; static contextTypes = { @@ -51,6 +52,7 @@ export default class SendToRow extends Component { showError={inError} > <EnsInput + scanQrCode={_ => this.props.scanQrCode()} accounts={toAccounts} closeDropdown={() => closeToDropdown()} dropdownOpen={toDropdownOpen} diff --git a/ui/app/components/send/send.component.js b/ui/app/components/send/send.component.js index 6f1b20c55..0d8ffd179 100644 --- a/ui/app/components/send/send.component.js +++ b/ui/app/components/send/send.component.js @@ -38,12 +38,30 @@ export default class SendTransactionScreen extends PersistentForm { updateAndSetGasTotal: PropTypes.func, updateSendErrors: PropTypes.func, updateSendTokenBalance: PropTypes.func, + scanQrCode: PropTypes.func, + qrCodeDetected: PropTypes.func, + qrCodeData: PropTypes.object, }; static contextTypes = { t: PropTypes.func, }; + componentWillReceiveProps (nextProps) { + if (nextProps.qrCodeData) { + if (nextProps.qrCodeData.type === 'address') { + const scannedAddress = nextProps.qrCodeData.values.address.toLowerCase() + const currentAddress = this.props.to && this.props.to.toLowerCase() + if (currentAddress !== scannedAddress) { + this.props.updateSendTo(scannedAddress) + this.updateGas({ to: scannedAddress }) + // Clean up QR code data after handling + this.props.qrCodeDetected(null) + } + } + } + } + updateGas ({ to: updatedToAddress, amount: value } = {}) { const { amount, @@ -158,6 +176,16 @@ export default class SendTransactionScreen extends PersistentForm { address, }) this.updateGas() + + // Show QR Scanner modal if ?scan=true + if (window.location.search === '?scan=true') { + this.props.scanQrCode() + + // Clear the queryString param after showing the modal + const cleanUrl = location.href.split('?')[0] + history.pushState({}, null, `${cleanUrl}`) + window.location.hash = '#send' + } } componentWillUnmount () { @@ -170,7 +198,10 @@ export default class SendTransactionScreen extends PersistentForm { return ( <div className="page-container"> <SendHeader history={history}/> - <SendContent updateGas={(updateData) => this.updateGas(updateData)}/> + <SendContent + updateGas={(updateData) => this.updateGas(updateData)} + scanQrCode={_ => this.props.scanQrCode()} + /> <SendFooter history={history}/> </div> ) diff --git a/ui/app/components/send/send.container.js b/ui/app/components/send/send.container.js index 44ebd2792..41735de64 100644 --- a/ui/app/components/send/send.container.js +++ b/ui/app/components/send/send.container.js @@ -21,11 +21,15 @@ import { getSendFromObject, getSendTo, getTokenBalance, + getQrCodeData, } from './send.selectors' import { + updateSendTo, updateSendTokenBalance, updateGasData, setGasTotal, + showQrScanner, + qrCodeDetected, } from '../../actions' import { resetSendState, @@ -35,6 +39,10 @@ import { calcGasTotal, } from './send.utils.js' +import { + SEND_ROUTE, +} from '../../routes' + module.exports = compose( withRouter, connect(mapStateToProps, mapDispatchToProps) @@ -60,6 +68,7 @@ function mapStateToProps (state) { tokenBalance: getTokenBalance(state), tokenContract: getSelectedTokenContract(state), tokenToFiatRate: getSelectedTokenToFiatRate(state), + qrCodeData: getQrCodeData(state), } } @@ -89,5 +98,8 @@ function mapDispatchToProps (dispatch) { }, updateSendErrors: newError => dispatch(updateSendErrors(newError)), resetSendState: () => dispatch(resetSendState()), + scanQrCode: () => dispatch(showQrScanner(SEND_ROUTE)), + qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), + updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)), } } diff --git a/ui/app/components/send/send.selectors.js b/ui/app/components/send/send.selectors.js index cf07eafe1..ab3f6d34b 100644 --- a/ui/app/components/send/send.selectors.js +++ b/ui/app/components/send/send.selectors.js @@ -46,6 +46,7 @@ const selectors = { getTokenExchangeRate, getUnapprovedTxs, transactionsSelector, + getQrCodeData, } module.exports = selectors @@ -282,3 +283,7 @@ function transactionsSelector (state) { : txsToRender .sort((a, b) => b.time - a.time) } + +function getQrCodeData (state) { + return state.appState.qrCodeData +} diff --git a/ui/app/components/send/tests/send-container.test.js b/ui/app/components/send/tests/send-container.test.js index 7a9120d24..57e332780 100644 --- a/ui/app/components/send/tests/send-container.test.js +++ b/ui/app/components/send/tests/send-container.test.js @@ -44,6 +44,7 @@ proxyquire('../send.container.js', { getSendEditingTransactionId: (s) => `mockEditingTransactionId:${s}`, getSendFromObject: (s) => `mockFrom:${s}`, getTokenBalance: (s) => `mockTokenBalance:${s}`, + getQrCodeData: (s) => `mockQrCodeData:${s}`, }, '../../actions': actionSpies, '../../ducks/send.duck': duckActionSpies, @@ -76,6 +77,7 @@ describe('send container', () => { tokenBalance: 'mockTokenBalance:mockState', tokenContract: 'mockTokenContract:mockState', tokenToFiatRate: 'mockTokenToFiatRate:mockState', + qrCodeData: 'mockQrCodeData:mockState', }) }) diff --git a/ui/app/components/send/to-autocomplete/to-autocomplete.js b/ui/app/components/send/to-autocomplete/to-autocomplete.js index 80cfa7a85..49ebf49d9 100644 --- a/ui/app/components/send/to-autocomplete/to-autocomplete.js +++ b/ui/app/components/send/to-autocomplete/to-autocomplete.js @@ -4,6 +4,7 @@ const h = require('react-hyperscript') const inherits = require('util').inherits const AccountListItem = require('../account-list-item/account-list-item.component').default const connect = require('react-redux').connect +const Tooltip = require('../../tooltip') ToAutoComplete.contextTypes = { t: PropTypes.func, @@ -94,11 +95,12 @@ ToAutoComplete.prototype.render = function () { dropdownOpen, onChange, inError, + qrScanner, } = this.props return h('div.send-v2__to-autocomplete', {}, [ - h('input.send-v2__to-autocomplete__input', { + h(`input.send-v2__to-autocomplete__input${qrScanner ? '.with-qr' : ''}`, { placeholder: this.context.t('recipientAddress'), className: inError ? `send-v2__error-border` : '', value: to, @@ -108,7 +110,13 @@ ToAutoComplete.prototype.render = function () { borderColor: inError ? 'red' : null, }, }), - + qrScanner && h(Tooltip, { + title: this.context.t('scanQrCode'), + position: 'bottom', + }, h(`i.fa.fa-qrcode.fa-lg.send-v2__to-autocomplete__qr-code`, { + style: { color: '#33333' }, + onClick: () => this.props.scanQrCode(), + })), !to && h(`i.fa.fa-caret-down.fa-lg.send-v2__to-autocomplete__down-caret`, { style: { color: '#dedede' }, onClick: () => this.handleInputEvent(), |