From 4339f04e80be74dd318e03f75fcf3410e923d30d Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 30 Jul 2018 17:50:05 -0400 Subject: use existing modals --- ui/app/components/modals/modal.js | 13 ++ ui/app/components/modals/qr-scanner/index.js | 2 + .../modals/qr-scanner/qr-scanner.component.js | 133 +++++++++++++++++++++ .../modals/qr-scanner/qr-scanner.container.js | 13 ++ 4 files changed, 161 insertions(+) create mode 100644 ui/app/components/modals/qr-scanner/index.js create mode 100644 ui/app/components/modals/qr-scanner/qr-scanner.component.js create mode 100644 ui/app/components/modals/qr-scanner/qr-scanner.container.js (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index f59825ed1..5dda50e52 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -21,6 +21,7 @@ const CustomizeGasModal = require('../customize-gas-modal') const NotifcationModal = require('./notification-modal') const ConfirmResetAccount = require('./confirm-reset-account') const ConfirmRemoveAccount = require('./confirm-remove-account') +const QRScanner = require('./qr-scanner') const TransactionConfirmed = require('./transaction-confirmed') const WelcomeBeta = require('./welcome-beta') const Notification = require('./notification') @@ -346,6 +347,18 @@ const MODALS = { borderRadius: '8px', }, }, + QR_SCANNER: { + contents: h(QRScanner), + mobileModalStyle: { + ...modalContainerMobileStyle, + }, + laptopModalStyle: { + ...modalContainerLaptopStyle, + }, + contentStyle: { + borderRadius: '8px', + }, + }, DEFAULT: { contents: [], diff --git a/ui/app/components/modals/qr-scanner/index.js b/ui/app/components/modals/qr-scanner/index.js new file mode 100644 index 000000000..470dee1f4 --- /dev/null +++ b/ui/app/components/modals/qr-scanner/index.js @@ -0,0 +1,2 @@ +import QrScanner from './qr-scanner.container' +module.exports = QrScanner diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js new file mode 100644 index 000000000..0e7709332 --- /dev/null +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -0,0 +1,133 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { BrowserQRCodeReader } from '@zxing/library' +import adapter from 'webrtc-adapter' // eslint-disable-line import/no-nodejs-modules, no-unused-vars +import Spinner from '../../spinner' + +export default class QrScanner extends Component { + static propTypes = { + hideModal: PropTypes.func.isRequired, + qrCodeDetected: PropTypes.func, + } + + static contextTypes = { + t: PropTypes.func, + } + + constructor (props, context) { + super(props) + this.state = { + ready: false, + msg: context.t('accessingYourCamera'), + } + this.scanning = false + this.codeReader = null + } + + componentDidMount () { + console.log('[QR-SCANNER]: componentDidUpdate', this.scanning) + if (!this.scanning) { + this.scanning = true + console.log('[QR-SCANNER]: componentDidUpdate - about to call initCamera') + this.initCamera() + } + } + + initCamera () { + console.log('[QR-SCANNER]: initCamera') + this.codeReader = new BrowserQRCodeReader() + this.codeReader.getVideoInputDevices() + .then(videoInputDevices => { + console.log('[QR-SCANNER]: initCamera::getVideoInputDevices', videoInputDevices) + setTimeout(_ => { + this.setState({ + ready: true, + msg: this.context.t('scanInstructions')}) + console.log('[QR-SCANNER]: initCamera::ready') + }, 2000) + + console.log('[QR-SCANNER]: initCamera::started decoding...') + this.codeReader.decodeFromInputVideoDevice(videoInputDevices[0].deviceId, 'video') + .then(content => { + console.log('[QR-SCANNER]: initCamera::decodeFromInputVideoDevice callback', content) + this.codeReader.reset() + const result = this.parseContent(content.text) + if (result.type !== 'unknown') { + this.props.qrCodeDetected(result) + this.stopAndClose() + } else { + this.setState({msg: this.context.t('unknownQrCode')}) + } + }) + .catch(err => { + console.error('QR-SCANNER: decodeFromInputVideoDevice threw an exception: ', err) + }) + }).catch(err => { + console.error('QR-SCANNER: getVideoInputDevices threw an exception: ', err) + }) + } + + 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} + } + + + stopAndClose = () => { + this.codeReader.reset() + this.scanning = false + this.setState({ ready: false }) + this.props.hideModal() + } + + render () { + const { t } = this.context + + return ( +
+
+
+ { `${t('scanQrCode')}?` } +
+
+
+
+
+
+
+ {this.state.msg} +
+
+ ) + } +} diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.container.js b/ui/app/components/modals/qr-scanner/qr-scanner.container.js new file mode 100644 index 000000000..198d5ff81 --- /dev/null +++ b/ui/app/components/modals/qr-scanner/qr-scanner.container.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux' +import QrScanner from './qr-scanner.component' + +const { hideModal, qrCodeDetected } = require('../../../actions') + +const mapDispatchToProps = dispatch => { + return { + hideModal: () => dispatch(hideModal()), + qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), + } +} + +export default connect(null, mapDispatchToProps)(QrScanner) -- cgit From d2368d6fe07a127f2c9320020183d27fcb870230 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 30 Jul 2018 18:34:00 -0400 Subject: clean up css --- ui/app/components/modals/index.scss | 2 + ui/app/components/modals/qr-scanner/index.scss | 42 +++++++++++++++++++++ .../modals/qr-scanner/qr-scanner.component.js | 44 +++++++--------------- 3 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 ui/app/components/modals/qr-scanner/index.scss (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/index.scss b/ui/app/components/modals/index.scss index e198cca44..0acccf172 100644 --- a/ui/app/components/modals/index.scss +++ b/ui/app/components/modals/index.scss @@ -1,5 +1,7 @@ @import './customize-gas/index'; +@import './qr-scanner/index'; + .modal-container { width: 100%; height: 100%; diff --git a/ui/app/components/modals/qr-scanner/index.scss b/ui/app/components/modals/qr-scanner/index.scss new file mode 100644 index 000000000..f43830086 --- /dev/null +++ b/ui/app/components/modals/qr-scanner/index.scss @@ -0,0 +1,42 @@ +.qr-scanner { + width: 100%; + height: 100%; + background-color: #fff; + display: flex; + flex-flow: column; + border-radius: 8px; + + &__title { + font-size: 1.5rem; + font-weight: 500; + padding: 16px 0; + text-align: center; + } + + &__content { + padding-left: 20px; + padding-right: 20px; + + &__video-wrapper { + overflow: hidden; + width: 100%; + height: 275px; + display: flex; + align-items: center; + justify-content: center; + + video { + transform: scaleX(-1); + width: auto; + height: 275px; + } + } + } + + &__status { + text-align: center; + font-size: 12px; + padding: 15px; + } +} + diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index 0e7709332..998967776 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -93,39 +93,23 @@ export default class QrScanner extends Component { const { t } = this.context return ( -
-
-
- { `${t('scanQrCode')}?` } -
-
-
+
+ { `${t('scanQrCode')}?` } +
+
+
+
+ display: this.state.ready ? 'block' : 'none', + }} + /> + { !this.state.ready ? : null}
-
- {this.state.msg} +
+ {this.state.msg}
) -- cgit From 34617a21c30afcca54a5ac884e361d41d39a4699 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 30 Jul 2018 18:36:37 -0400 Subject: copy --- ui/app/components/modals/qr-scanner/index.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/index.scss b/ui/app/components/modals/qr-scanner/index.scss index f43830086..314e94069 100644 --- a/ui/app/components/modals/qr-scanner/index.scss +++ b/ui/app/components/modals/qr-scanner/index.scss @@ -35,7 +35,7 @@ &__status { text-align: center; - font-size: 12px; + font-size: 14px; padding: 15px; } } -- cgit From b673a7a7fc66f1582ddb7cd94b32548a58a87670 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 30 Jul 2018 18:40:00 -0400 Subject: kill camera stream when unmouting --- ui/app/components/modals/qr-scanner/qr-scanner.component.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index 998967776..580774635 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -33,6 +33,10 @@ export default class QrScanner extends Component { } } + componentWillUnmount () { + this.codeReader.reset() + } + initCamera () { console.log('[QR-SCANNER]: initCamera') this.codeReader = new BrowserQRCodeReader() @@ -50,7 +54,6 @@ export default class QrScanner extends Component { this.codeReader.decodeFromInputVideoDevice(videoInputDevices[0].deviceId, 'video') .then(content => { console.log('[QR-SCANNER]: initCamera::decodeFromInputVideoDevice callback', content) - this.codeReader.reset() const result = this.parseContent(content.text) if (result.type !== 'unknown') { this.props.qrCodeDetected(result) -- cgit From edb154749d468299166e41e56d23beb781817cbc Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Mon, 30 Jul 2018 22:57:05 -0400 Subject: send to fullscreen if no permission from popup --- .../modals/qr-scanner/qr-scanner.component.js | 38 +++++++++++++++------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index 580774635..395008fca 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -3,6 +3,11 @@ import PropTypes from 'prop-types' import { BrowserQRCodeReader } from '@zxing/library' import adapter from 'webrtc-adapter' // eslint-disable-line import/no-nodejs-modules, no-unused-vars import Spinner from '../../spinner' +const { ENVIRONMENT_TYPE_POPUP } = require('../../../../../app/scripts/lib/enums') +const { getEnvironmentType } = require('../../../../../app/scripts/lib/util') +const { + SEND_ROUTE, +} = require('../../../routes') export default class QrScanner extends Component { static propTypes = { @@ -22,13 +27,14 @@ export default class QrScanner extends Component { } this.scanning = false this.codeReader = null + this.notAllowed = false } componentDidMount () { - console.log('[QR-SCANNER]: componentDidUpdate', this.scanning) + if (!this.scanning) { this.scanning = true - console.log('[QR-SCANNER]: componentDidUpdate - about to call initCamera') + this.initCamera() } } @@ -38,22 +44,23 @@ export default class QrScanner extends Component { } initCamera () { - console.log('[QR-SCANNER]: initCamera') + this.codeReader = new BrowserQRCodeReader() this.codeReader.getVideoInputDevices() .then(videoInputDevices => { - console.log('[QR-SCANNER]: initCamera::getVideoInputDevices', videoInputDevices) + setTimeout(_ => { - this.setState({ - ready: true, - msg: this.context.t('scanInstructions')}) - console.log('[QR-SCANNER]: initCamera::ready') + if (!this.notAllowed) { + this.setState({ + ready: true, + msg: this.context.t('scanInstructions')}) + } }, 2000) - console.log('[QR-SCANNER]: initCamera::started decoding...') + this.codeReader.decodeFromInputVideoDevice(videoInputDevices[0].deviceId, 'video') .then(content => { - console.log('[QR-SCANNER]: initCamera::decodeFromInputVideoDevice callback', content) + const result = this.parseContent(content.text) if (result.type !== 'unknown') { this.props.qrCodeDetected(result) @@ -63,6 +70,14 @@ export default class QrScanner extends Component { } }) .catch(err => { + this.notAllowed = true + if (err && err.name === 'NotAllowedError') { + if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP) { + global.platform.openExtensionInBrowser(`${SEND_ROUTE}`, `scan=true`) + } else { + this.setState({msg: this.context.t('youNeedToAllowCameraAccess')}) + } + } console.error('QR-SCANNER: decodeFromInputVideoDevice threw an exception: ', err) }) }).catch(err => { @@ -75,7 +90,8 @@ export default class QrScanner extends Component { let values = {} // Here we could add more cases - // To parse other codes (transactions for ex.) + // To parse other type of links + // For ex. EIP-681 (https://eips.ethereum.org/EIPS/eip-681) if (content.split('ethereum:').length > 1) { type = 'address' -- cgit From 710b4e294f66fe6e623fa145cc99be5b79c8210e Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Tue, 31 Jul 2018 18:30:40 -0400 Subject: added crossbrowser support and error handling --- ui/app/components/modals/qr-scanner/index.scss | 5 + .../modals/qr-scanner/qr-scanner.component.js | 108 ++++++++++++--------- .../modals/qr-scanner/qr-scanner.container.js | 9 +- 3 files changed, 76 insertions(+), 46 deletions(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/index.scss b/ui/app/components/modals/qr-scanner/index.scss index 314e94069..df65cfbbb 100644 --- a/ui/app/components/modals/qr-scanner/index.scss +++ b/ui/app/components/modals/qr-scanner/index.scss @@ -38,5 +38,10 @@ font-size: 14px; padding: 15px; } + + &__status.error { + padding: 60px 45px 80px; + font-size: 16px; + } } diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index 395008fca..29ce45184 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -3,16 +3,14 @@ import PropTypes from 'prop-types' import { BrowserQRCodeReader } from '@zxing/library' import adapter from 'webrtc-adapter' // eslint-disable-line import/no-nodejs-modules, no-unused-vars import Spinner from '../../spinner' -const { ENVIRONMENT_TYPE_POPUP } = require('../../../../../app/scripts/lib/enums') -const { getEnvironmentType } = require('../../../../../app/scripts/lib/util') -const { - SEND_ROUTE, -} = require('../../../routes') +import WebcamUtils from '../../../../lib/webcam-utils' export default class QrScanner extends Component { static propTypes = { hideModal: PropTypes.func.isRequired, qrCodeDetected: PropTypes.func, + error: PropTypes.bool, + errorType: PropTypes.string, } static contextTypes = { @@ -21,46 +19,65 @@ export default class QrScanner extends Component { constructor (props, context) { super(props) + + let initialMsg = context.t('accessingYourCamera') + if (props.error) { + if (props.errorType === 'NO_WEBCAM_FOUND') { + initialMsg = context.t('noWebcamFound') + } else { + initialMsg = context.t('unknownCameraError') + } + } + this.state = { ready: false, - msg: context.t('accessingYourCamera'), + msg: initialMsg, } - this.scanning = false this.codeReader = null + this.permissionChecker = null this.notAllowed = false } componentDidMount () { + this.initCamera() + } - if (!this.scanning) { - this.scanning = true - - this.initCamera() + async checkPermisisions () { + const { permissions } = await WebcamUtils.checkStatus() + if (permissions) { + clearTimeout(this.permissionChecker) + // Let the video stream load first... + setTimeout(_ => { + this.setState({ + ready: true, + msg: this.context.t('scanInstructions'), + }) + }, 2000) + + } else { + // Keep checking for permissions + this.permissionChecker = setTimeout(_ => { + console.log('[QR-SCANNER]: time to check again!') + this.checkPermisisions() + }, 1000) } } componentWillUnmount () { - this.codeReader.reset() + clearTimeout(this.permissionChecker) + if (this.codeReader) { + this.codeReader.reset() + } } initCamera () { - this.codeReader = new BrowserQRCodeReader() this.codeReader.getVideoInputDevices() .then(videoInputDevices => { - - setTimeout(_ => { - if (!this.notAllowed) { - this.setState({ - ready: true, - msg: this.context.t('scanInstructions')}) - } - }, 2000) - - - this.codeReader.decodeFromInputVideoDevice(videoInputDevices[0].deviceId, 'video') + clearTimeout(this.permissionChecker) + this.checkPermisisions() + this.codeReader.decodeFromInputVideoDevice(undefined, 'video') .then(content => { - const result = this.parseContent(content.text) if (result.type !== 'unknown') { this.props.qrCodeDetected(result) @@ -70,18 +87,14 @@ export default class QrScanner extends Component { } }) .catch(err => { - this.notAllowed = true if (err && err.name === 'NotAllowedError') { - if (getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP) { - global.platform.openExtensionInBrowser(`${SEND_ROUTE}`, `scan=true`) - } else { - this.setState({msg: this.context.t('youNeedToAllowCameraAccess')}) - } + this.setState({msg: this.context.t('youNeedToAllowCameraAccess')}) + clearTimeout(this.permissionChecker) + this.checkPermisisions() } - console.error('QR-SCANNER: decodeFromInputVideoDevice threw an exception: ', err) }) }).catch(err => { - console.error('QR-SCANNER: getVideoInputDevices threw an exception: ', err) + console.error('[QR-SCANNER]: getVideoInputDevices threw an exception: ', err) }) } @@ -103,31 +116,36 @@ export default class QrScanner extends Component { stopAndClose = () => { this.codeReader.reset() - this.scanning = false this.setState({ ready: false }) this.props.hideModal() } + renderVideo () { + return ( +
+
+ ) + } + render () { const { t } = this.context return (
- { `${t('scanQrCode')}?` } + { `${t('scanQrCode')}` }
-
-
+ { !this.props.error ? this.renderVideo() : null}
-
+
{this.state.msg}
diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.container.js b/ui/app/components/modals/qr-scanner/qr-scanner.container.js index 198d5ff81..d50abe0ae 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.container.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.container.js @@ -3,6 +3,13 @@ import QrScanner from './qr-scanner.component' const { hideModal, qrCodeDetected } = require('../../../actions') +const mapStateToProps = state => { + return { + error: state.appState.modal.modalState.props.error, + errorType: state.appState.modal.modalState.props.errorType, + } +} + const mapDispatchToProps = dispatch => { return { hideModal: () => dispatch(hideModal()), @@ -10,4 +17,4 @@ const mapDispatchToProps = dispatch => { } } -export default connect(null, mapDispatchToProps)(QrScanner) +export default connect(mapStateToProps, mapDispatchToProps)(QrScanner) -- cgit From caa9e202cf4bac328759695e05d1bda5997ef6e7 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Tue, 31 Jul 2018 18:32:14 -0400 Subject: lint --- ui/app/components/modals/qr-scanner/qr-scanner.component.js | 2 -- 1 file changed, 2 deletions(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index 29ce45184..d8091ecee 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -53,11 +53,9 @@ export default class QrScanner extends Component { msg: this.context.t('scanInstructions'), }) }, 2000) - } else { // Keep checking for permissions this.permissionChecker = setTimeout(_ => { - console.log('[QR-SCANNER]: time to check again!') this.checkPermisisions() }, 1000) } -- cgit From 94a89790dcca3003fde59e8385b8c3d32f36d466 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Tue, 31 Jul 2018 18:58:54 -0400 Subject: fix --- ui/app/components/modals/qr-scanner/qr-scanner.component.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index d8091ecee..e6ba146d6 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -35,7 +35,7 @@ export default class QrScanner extends Component { } this.codeReader = null this.permissionChecker = null - this.notAllowed = false + this.needsToReinit = false } componentDidMount () { @@ -52,6 +52,10 @@ export default class QrScanner extends Component { ready: true, msg: this.context.t('scanInstructions'), }) + if (this.needsToReinit) { + this.initCamera() + this.needsToReinit = false + } }, 2000) } else { // Keep checking for permissions @@ -88,6 +92,7 @@ export default class QrScanner extends Component { if (err && err.name === 'NotAllowedError') { this.setState({msg: this.context.t('youNeedToAllowCameraAccess')}) clearTimeout(this.permissionChecker) + this.needsToReinit = true this.checkPermisisions() } }) -- cgit From 71ef4d85da50c50f767e20623fd30c014ba16ecf Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Fri, 3 Aug 2018 18:57:23 -0400 Subject: design complete --- ui/app/components/modals/qr-scanner/index.scss | 40 +++++++++++- .../modals/qr-scanner/qr-scanner.component.js | 72 ++++++++++++++++++---- .../modals/qr-scanner/qr-scanner.container.js | 6 +- 3 files changed, 102 insertions(+), 16 deletions(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/index.scss b/ui/app/components/modals/qr-scanner/index.scss index df65cfbbb..6fa81d51f 100644 --- a/ui/app/components/modals/qr-scanner/index.scss +++ b/ui/app/components/modals/qr-scanner/index.scss @@ -39,9 +39,45 @@ padding: 15px; } - &__status.error { - padding: 60px 45px 80px; + &__image { + font-size: 1.5rem; + font-weight: 500; + padding: 16px 0 0; + text-align: center; + } + + &__error { + text-align: center; font-size: 16px; + padding: 15px; + } + + &__footer { + padding: 20px; + flex-direction: row; + display: flex; + + button { + margin-right: 15px; + } + + button:last-of-type { + margin-right: 0; + background-color: #009eec; + border: none; + color: #fff; + } + } + + &__close::after { + content: '\00D7'; + font-size: 35px; + color: #9b9b9b; + position: absolute; + top: 4px; + right: 20px; + cursor: pointer; + font-weight: 300; } } diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index e6ba146d6..5ca19ccd8 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -9,6 +9,7 @@ export default class QrScanner extends Component { static propTypes = { hideModal: PropTypes.func.isRequired, qrCodeDetected: PropTypes.func, + scanQrCode: PropTypes.func, error: PropTypes.bool, errorType: PropTypes.string, } @@ -20,18 +21,9 @@ export default class QrScanner extends Component { constructor (props, context) { super(props) - let initialMsg = context.t('accessingYourCamera') - if (props.error) { - if (props.errorType === 'NO_WEBCAM_FOUND') { - initialMsg = context.t('noWebcamFound') - } else { - initialMsg = context.t('unknownCameraError') - } - } - this.state = { ready: false, - msg: initialMsg, + msg: context.t('accessingYourCamera'), } this.codeReader = null this.permissionChecker = null @@ -118,11 +110,22 @@ export default class QrScanner extends Component { stopAndClose = () => { - this.codeReader.reset() + if (this.codeReader) { + this.codeReader.reset() + } this.setState({ ready: false }) this.props.hideModal() } + tryAgain = () => { + // close the modal + this.stopAndClose() + // wait for the animation and try again + setTimeout(_ => { + this.props.scanQrCode() + }, 1000) + } + renderVideo () { return (
@@ -137,18 +140,61 @@ export default class QrScanner extends Component { ) } + renderErrorModal () { + let title, msg + + if (this.props.error) { + if (this.props.errorType === 'NO_WEBCAM_FOUND') { + title = this.context.t('noWebcamFoundTitle') + msg = this.context.t('noWebcamFound') + } else { + title = this.context.t('unknownCameraErrorTitle') + msg = this.context.t('unknownCameraError') + } + } + + return ( +
+
+ +
+ +
+
+ { title } +
+
+ {msg} +
+
+ + +
+
+ ) + } + render () { const { t } = this.context + if (this.props.error) { + return this.renderErrorModal() + } + return (
+
{ `${t('scanQrCode')}` }
- { !this.props.error ? this.renderVideo() : null} + { this.renderVideo() }
-
+
{this.state.msg}
diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.container.js b/ui/app/components/modals/qr-scanner/qr-scanner.container.js index d50abe0ae..d0a35e03b 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.container.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.container.js @@ -1,7 +1,10 @@ import { connect } from 'react-redux' import QrScanner from './qr-scanner.component' -const { hideModal, qrCodeDetected } = require('../../../actions') +const { hideModal, qrCodeDetected, showQrScanner } = require('../../../actions') +import { + SEND_ROUTE, +} from '../../../routes' const mapStateToProps = state => { return { @@ -14,6 +17,7 @@ const mapDispatchToProps = dispatch => { return { hideModal: () => dispatch(hideModal()), qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), + scanQrCode: () => dispatch(showQrScanner(SEND_ROUTE)), } } -- cgit From af97ba103cea6e9f5e114d916f920b28d96d4e8a Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Fri, 3 Aug 2018 19:36:01 -0400 Subject: clear qr code data before scanning --- ui/app/components/modals/qr-scanner/qr-scanner.component.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index 5ca19ccd8..b18d51351 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -28,6 +28,9 @@ export default class QrScanner extends Component { this.codeReader = null this.permissionChecker = null this.needsToReinit = false + + // Clear pre-existing qr code data before scanning + this.props.qrCodeDetected(null) } componentDidMount () { -- cgit From c6b7e460b536a6fcff4e4328b1007f677720b585 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Wed, 8 Aug 2018 03:00:39 -0400 Subject: code review changes --- .../modals/qr-scanner/qr-scanner.component.js | 25 +++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index b18d51351..cf03c9097 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -4,6 +4,7 @@ import { BrowserQRCodeReader } from '@zxing/library' import adapter from 'webrtc-adapter' // eslint-disable-line import/no-nodejs-modules, no-unused-vars import Spinner from '../../spinner' import WebcamUtils from '../../../../lib/webcam-utils' +import PageContainerFooter from '../../page-container/page-container-footer/page-container-footer.component'; export default class QrScanner extends Component { static propTypes = { @@ -104,9 +105,19 @@ export default class QrScanner extends Component { // To parse other type of links // For ex. EIP-681 (https://eips.ethereum.org/EIPS/eip-681) + + // Ethereum address links - fox ex. ethereum:0x.....1111 if (content.split('ethereum:').length > 1) { + type = 'address' values = {'address': content.split('ethereum:')[1] } + + // Regular ethereum addresses - fox ex. 0x.....1111 + } else if (content.substring(0, 2).toLowerCase() === '0x') { + + type = 'address' + values = {'address': content } + } return {type, values} } @@ -169,14 +180,12 @@ export default class QrScanner extends Component {
{msg}
-
- - -
+
) } -- cgit From cbbd0d3c75ce16cc04d263aaf18bd62ca4513596 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Wed, 8 Aug 2018 03:21:37 -0400 Subject: lint --- ui/app/components/modals/qr-scanner/qr-scanner.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index cf03c9097..ee204e173 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -4,7 +4,7 @@ import { BrowserQRCodeReader } from '@zxing/library' import adapter from 'webrtc-adapter' // eslint-disable-line import/no-nodejs-modules, no-unused-vars import Spinner from '../../spinner' import WebcamUtils from '../../../../lib/webcam-utils' -import PageContainerFooter from '../../page-container/page-container-footer/page-container-footer.component'; +import PageContainerFooter from '../../page-container/page-container-footer/page-container-footer.component' export default class QrScanner extends Component { static propTypes = { -- cgit From f269021dc3ea78c6359b9db50db30fdd549020b7 Mon Sep 17 00:00:00 2001 From: brunobar79 Date: Wed, 8 Aug 2018 12:22:48 -0400 Subject: add submit button type --- ui/app/components/modals/qr-scanner/qr-scanner.component.js | 1 + 1 file changed, 1 insertion(+) (limited to 'ui/app/components/modals') diff --git a/ui/app/components/modals/qr-scanner/qr-scanner.component.js b/ui/app/components/modals/qr-scanner/qr-scanner.component.js index ee204e173..cb8d07d83 100644 --- a/ui/app/components/modals/qr-scanner/qr-scanner.component.js +++ b/ui/app/components/modals/qr-scanner/qr-scanner.component.js @@ -185,6 +185,7 @@ export default class QrScanner extends Component { onSubmit={this.tryAgain} cancelText={this.context.t('cancel')} submitText={this.context.t('tryAgain')} + submitButtonType="confirm" />
) -- cgit