diff options
author | brunobar79 <brunobar79@gmail.com> | 2018-07-25 08:32:20 +0800 |
---|---|---|
committer | brunobar79 <brunobar79@gmail.com> | 2018-07-25 08:32:20 +0800 |
commit | 74fd6d1d1227d7a9e49623b73ee85985d79a1e46 (patch) | |
tree | 0329696b64e9f300c05919729d87dbb0dbd99655 /ui | |
parent | d5929e5c42e230fc0a52337f86b5850e68516563 (diff) | |
download | tangerine-wallet-browser-74fd6d1d1227d7a9e49623b73ee85985d79a1e46.tar tangerine-wallet-browser-74fd6d1d1227d7a9e49623b73ee85985d79a1e46.tar.gz tangerine-wallet-browser-74fd6d1d1227d7a9e49623b73ee85985d79a1e46.tar.bz2 tangerine-wallet-browser-74fd6d1d1227d7a9e49623b73ee85985d79a1e46.tar.lz tangerine-wallet-browser-74fd6d1d1227d7a9e49623b73ee85985d79a1e46.tar.xz tangerine-wallet-browser-74fd6d1d1227d7a9e49623b73ee85985d79a1e46.tar.zst tangerine-wallet-browser-74fd6d1d1227d7a9e49623b73ee85985d79a1e46.zip |
working without injection
Diffstat (limited to 'ui')
-rw-r--r-- | ui/app/actions.js | 41 | ||||
-rw-r--r-- | ui/app/app.js | 7 | ||||
-rw-r--r-- | ui/app/components/qr-scanner/index.js | 2 | ||||
-rw-r--r-- | ui/app/components/qr-scanner/qr-scanner.component.js | 152 | ||||
-rw-r--r-- | ui/app/components/send/send.component.js | 20 | ||||
-rw-r--r-- | ui/app/components/send/send.container.js | 2 | ||||
-rw-r--r-- | ui/app/components/send/send.selectors.js | 5 | ||||
-rw-r--r-- | ui/app/reducers/app.js | 20 | ||||
-rw-r--r-- | ui/app/selectors.js | 1 |
9 files changed, 229 insertions, 21 deletions
diff --git a/ui/app/actions.js b/ui/app/actions.js index 9aba6853d..dd0e78b6a 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -31,6 +31,12 @@ var actions = { ALERT_CLOSE: 'UI_ALERT_CLOSE', showAlert: showAlert, hideAlert: hideAlert, + QR_SCANNER_OPEN: 'UI_QR_SCANNER_OPEN', + QR_SCANNER_CLOSE: 'UI_QR_SCANNER_CLOSE', + QR_CODE_DETECTED: 'UI_QR_CODE_DETECTED', + showQrScanner, + hideQrScanner, + qrCodeDetected, // network dropdown open NETWORK_DROPDOWN_OPEN: 'UI_NETWORK_DROPDOWN_OPEN', NETWORK_DROPDOWN_CLOSE: 'UI_NETWORK_DROPDOWN_CLOSE', @@ -1752,6 +1758,25 @@ function hideAlert () { } } +function showQrScanner () { + return { + type: actions.QR_SCANNER_OPEN, + } +} + +function qrCodeDetected (qrCodeData) { + return { + type: actions.QR_CODE_DETECTED, + value: qrCodeData, + } +} + +function hideQrScanner () { + return { + type: actions.QR_SCANNER_CLOSE, + } +} + function showLoadingIndication (message) { return { @@ -2197,21 +2222,7 @@ function clearPendingTokens () { } function scanQrCode () { - log.debug(`background.scanQrCode`) return (dispatch, getState) => { - dispatch(actions.showLoadingIndication()) - return new Promise((resolve, reject) => { - background.scanQrCode((err, data) => { - log.debug(`background.scanQrCode resolved!`, err, data) - if (err) { - log.error(err) - dispatch(actions.displayWarning(err.message)) - return reject(err) - } - - dispatch(actions.hideLoadingIndication()) - return resolve(data) - }) - }) + dispatch(actions.showQrScanner()) } } diff --git a/ui/app/app.js b/ui/app/app.js index dbb6146d1..9363d21d1 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -39,6 +39,8 @@ const Modal = require('./components/modals/index').Modal // Global Alert const Alert = require('./components/alert') +const QrScanner = require('./components/qr-scanner') + const AppHeader = require('./components/app-header') import UnlockPage from './components/pages/unlock-page' @@ -132,6 +134,8 @@ class App extends Component { // global alert h(Alert, {visible: this.props.alertOpen, msg: alertMessage}), + h(QrScanner, {visible: this.props.qrScannerOpen}), + h(AppHeader), // sidebar @@ -270,6 +274,7 @@ App.propTypes = { currentView: PropTypes.object, sidebarOpen: PropTypes.bool, alertOpen: PropTypes.bool, + qrScannerOpen: PropTypes.bool, hideSidebar: PropTypes.func, isMascara: PropTypes.bool, isOnboarding: PropTypes.bool, @@ -306,6 +311,7 @@ function mapStateToProps (state) { networkDropdownOpen, sidebarOpen, alertOpen, + qrScannerOpen, alertMessage, isLoading, loadingMessage, @@ -333,6 +339,7 @@ function mapStateToProps (state) { networkDropdownOpen, sidebarOpen, alertOpen, + qrScannerOpen, alertMessage, isLoading, loadingMessage, diff --git a/ui/app/components/qr-scanner/index.js b/ui/app/components/qr-scanner/index.js new file mode 100644 index 000000000..f459f6702 --- /dev/null +++ b/ui/app/components/qr-scanner/index.js @@ -0,0 +1,2 @@ +import QrScanner from './qr-scanner.component' +module.exports = QrScanner diff --git a/ui/app/components/qr-scanner/qr-scanner.component.js b/ui/app/components/qr-scanner/qr-scanner.component.js new file mode 100644 index 000000000..cc07e53a2 --- /dev/null +++ b/ui/app/components/qr-scanner/qr-scanner.component.js @@ -0,0 +1,152 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import {connect} from 'react-redux' +import { hideQrScanner, qrCodeDetected} from '../../actions' +import Instascan from 'instascan' + +class QrScanner extends Component { + static propTypes = { + visible: PropTypes.bool, + hideQrScanner: PropTypes.func, + qrCodeDetected: PropTypes.func, + } + constructor (props) { + super(props) + this.state = { + msg: 'Place the QR code in front of your camera so we can read it...', + } + this.scanning = false + } + + parseContent (content) { + let type = 'unknown' + let values = {} + + // Here we could add more cases + // To parse other codes (transactions for ex.) + + if (content.split('ethereum:').length > 1) { + type = 'address' + values = {'address': content.split('ethereum:')[1] } + } + return {type, values} + } + + componentDidUpdate () { + if (this.props.visible && this.camera && !this.scanning) { + const scanner = new Instascan.Scanner({ + video: this.camera, + backgroundScan: false, + continuous: true, + }) + scanner.addListener('scan', (content) => { + scanner.stop().then(_ => { + const result = this.parseContent(content) + if (result.type !== 'unknown') { + console.log('QR-SCANNER: CODE DETECTED', result) + this.props.qrCodeDetected(result) + this.props.hideQrScanner() + } else { + this.setState({msg: 'Error: We couldn\'t identify that QR code'}) + } + }) + }) + Instascan.Camera.getCameras().then((cameras) => { + if (cameras.length > 0) { + scanner.start(cameras[0]) + console.log('QR-SCANNER: started scanning with camera', cameras[0]) + } else { + console.log('QR-SCANNER: no cameras found') + } + }).catch(function (e) { + console.error(e) + }) + this.scanning = true + } + } + + render () { + const { visible } = this.props + + if (!visible) { + return null + } + + return ( + <div className={'qr-code-modal-wrapper'}> + <div className={'qr-scanner'} + style={{ + position: 'fixed', + top: '50%', + left: '50%', + zIndex: 1050, + minWidth: '320px', + minHeight: '400px', + maxWidth: '300px', + maxHeight: '300px', + transform: 'translate(-50%, -50%)', + backgroundColor: '#ffffff', + padding: '15px', + }} + > + <h3 style={{ + textAlign: 'center', + marginBottom: '20px', + }}> + Scan QR code + </h3> + <div + className={'qr-code-video-wrapper'} + style={{ + overflow: 'hidden', + width: '100%', + height: '275px', + }}> + <video + style={{ + width: 'auto', + height: '275px', + marginLeft: '-15%', + }} + ref={(cam) => { + this.camera = cam + }} + /> + </div> + <div className={'qr-code-help'} style={{textAlign: 'center', fontSize: '12px', padding: '15px'}}> + {this.state.msg} + </div> + </div> + <div + className={'qr-code-modal-overlay'} + style={{ + position: 'fixed', + top: '0', + right: '0', + bottom: '0', + left: '0', + zIndex: '1040', + backgroundColor: 'rgba(0, 0, 0, 0.5)', + animationFillMode: 'forwards', + animationDuration: '0.3s', + animationName: 'anim_171532470906313', + animationTimingFunction: 'ease-out', + }} + onClick={_ => this.props.hideQrScanner() } + /> + </div> + ) + } +} + +function mapDispatchToProps (dispatch) { + return { + hideQrScanner: () => dispatch(hideQrScanner()), + qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), + } +} +function mapStateToProps (state) { + return {} +} + +export default connect(mapStateToProps, mapDispatchToProps)(QrScanner) diff --git a/ui/app/components/send/send.component.js b/ui/app/components/send/send.component.js index 6c439cd21..fb7eef329 100644 --- a/ui/app/components/send/send.component.js +++ b/ui/app/components/send/send.component.js @@ -39,16 +39,26 @@ export default class SendTransactionScreen extends PersistentForm { updateSendErrors: PropTypes.func, updateSendTokenBalance: PropTypes.func, scanQrCode: PropTypes.func, + qrCodeData: PropTypes.object, }; static contextTypes = { t: PropTypes.func, }; - scanQrCode = async () => { - const scannedAddress = await this.props.scanQrCode() - this.props.updateSendTo(scannedAddress) - this.updateGas({ to: scannedAddress }) + 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 }) + + // Here we should clear props.qrCodeData + } + } + } } updateGas ({ to: updatedToAddress, amount: value } = {}) { @@ -179,7 +189,7 @@ export default class SendTransactionScreen extends PersistentForm { <SendHeader history={history}/> <SendContent updateGas={(updateData) => this.updateGas(updateData)} - scanQrCode={_ => this.scanQrCode()} + 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 417941601..67a441a9d 100644 --- a/ui/app/components/send/send.container.js +++ b/ui/app/components/send/send.container.js @@ -21,6 +21,7 @@ import { getSendFromObject, getSendTo, getTokenBalance, + getQrCodeData, } from './send.selectors' import { updateSendTo, @@ -62,6 +63,7 @@ function mapStateToProps (state) { tokenBalance: getTokenBalance(state), tokenContract: getSelectedTokenContract(state), tokenToFiatRate: getSelectedTokenToFiatRate(state), + qrCodeData: getQrCodeData(state), } } diff --git a/ui/app/components/send/send.selectors.js b/ui/app/components/send/send.selectors.js index cf07eafe1..4e81d1f9e 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 +}
\ No newline at end of file diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js index 50d8bcba7..9775638a7 100644 --- a/ui/app/reducers/app.js +++ b/ui/app/reducers/app.js @@ -50,7 +50,9 @@ function reduceApp (state, action) { }, sidebarOpen: false, alertOpen: false, + qrScannerOpen: false, alertMessage: null, + qrCodeData: null, networkDropdownOpen: false, currentView: seedWords ? seedConfView : defaultView, accountDetail: { @@ -90,7 +92,7 @@ function reduceApp (state, action) { sidebarOpen: false, }) - // sidebar methods + // alert methods case actions.ALERT_OPEN: return extend(appState, { alertOpen: true, @@ -102,6 +104,22 @@ function reduceApp (state, action) { alertOpen: false, alertMessage: null, }) + // qr scanner methods + case actions.QR_SCANNER_OPEN: + return extend(appState, { + qrScannerOpen: true, + }) + + case actions.QR_SCANNER_CLOSE: + return extend(appState, { + qrScannerOpen: false, + }) + + case actions.QR_CODE_DETECTED: + return extend(appState, { + qrCodeData: action.value, + }) + // modal methods: case actions.MODAL_OPEN: diff --git a/ui/app/selectors.js b/ui/app/selectors.js index d86462275..14d9dcd1d 100644 --- a/ui/app/selectors.js +++ b/ui/app/selectors.js @@ -194,3 +194,4 @@ function getTotalUnapprovedCount ({ metamask }) { return Object.keys(unapprovedTxs).length + unapprovedMsgCount + unapprovedPersonalMsgCount + unapprovedTypedMessagesCount } + |