diff options
author | brunobar79 <brunobar79@gmail.com> | 2018-08-04 06:57:23 +0800 |
---|---|---|
committer | brunobar79 <brunobar79@gmail.com> | 2018-08-04 06:57:23 +0800 |
commit | 71ef4d85da50c50f767e20623fd30c014ba16ecf (patch) | |
tree | d10e0de00e43bde10f59c741a38df93cffd95806 | |
parent | 94a89790dcca3003fde59e8385b8c3d32f36d466 (diff) | |
download | tangerine-wallet-browser-71ef4d85da50c50f767e20623fd30c014ba16ecf.tar.gz tangerine-wallet-browser-71ef4d85da50c50f767e20623fd30c014ba16ecf.tar.zst tangerine-wallet-browser-71ef4d85da50c50f767e20623fd30c014ba16ecf.zip |
design complete
-rw-r--r-- | app/_locales/en/messages.json | 10 | ||||
-rw-r--r-- | app/images/webcam.svg | 18 | ||||
-rw-r--r-- | ui/app/components/modals/qr-scanner/index.scss | 40 | ||||
-rw-r--r-- | ui/app/components/modals/qr-scanner/qr-scanner.component.js | 72 | ||||
-rw-r--r-- | ui/app/components/modals/qr-scanner/qr-scanner.container.js | 6 | ||||
-rw-r--r-- | ui/app/components/send/to-autocomplete/to-autocomplete.js | 8 | ||||
-rw-r--r-- | ui/app/css/itcss/components/send.scss | 12 | ||||
-rw-r--r-- | ui/lib/webcam-utils.js | 45 |
8 files changed, 166 insertions, 45 deletions
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index ec96f5b08..db050e766 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -656,8 +656,11 @@ "notStarted": { "message": "Not Started" }, + "noWebcamFoundTitle": { + "message": "Webcam not found" + }, "noWebcamFound": { - "message": "We couldn't find any webcam available on your computer. Make sure the device is connected and configured correctly." + "message": "Your computer's webcam was not found. Please try again." }, "oldUI": { "message": "Old UI" @@ -1101,8 +1104,11 @@ "unknownQrCode": { "message": "Error: We couldn't identify that QR code" }, + "unknownCameraErrorTitle": { + "message": "Ooops! Something went wrong...." + }, "unknownCameraError": { - "message": "Ooops! Something went wrong while trying to access you camera. Please try again..." + "message": "There was an error while trying to access you camera. Please try again..." }, "unlock": { "message": "Unlock" diff --git a/app/images/webcam.svg b/app/images/webcam.svg new file mode 100644 index 000000000..4b9b58148 --- /dev/null +++ b/app/images/webcam.svg @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg width="53px" height="53px" viewBox="0 0 53 53" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 50.2 (55047) - http://www.bohemiancoding.com/sketch --> + <title>webcam</title> + <desc>Created with Sketch.</desc> + <defs></defs> + <g id="QR-Code-Scan" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Group-4-Copy" transform="translate(-482.000000, -218.000000)"> + <g id="webcam" transform="translate(482.000000, 218.000000)"> + <circle id="Oval" fill="#D5ECFA" cx="26.5" cy="26.5" r="26.5"></circle> + <g id="Group" transform="translate(14.000000, 19.000000)" fill="#259DE5"> + <rect id="Rectangle" x="0" y="0" width="18" height="16"></rect> + <polygon id="Triangle" points="19 6.57142857 26 3 26 13 19 9.42857143"></polygon> + </g> + </g> + </g> + </g> +</svg>
\ No newline at end of file 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 ( <div className={'qr-scanner__content__video-wrapper'}> @@ -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 ( + <div className="qr-scanner"> + <div className="qr-scanner__close" onClick={this.stopAndClose}></div> + + <div className="qr-scanner__image"> + <img src={'images/webcam.svg'} width={70} height={70} /> + </div> + <div className="qr-scanner__title"> + { title } + </div> + <div className={'qr-scanner__error'}> + {msg} + </div> + <div className={'qr-scanner__footer'}> + <button className="btn-default btn--large" onClick={this.stopAndClose}> + CANCEL + </button> + <button className="btn-primary btn--large" onClick={this.tryAgain}> + TRY AGAIN + </button> + </div> + </div> + ) + } + render () { const { t } = this.context + if (this.props.error) { + return this.renderErrorModal() + } + return ( <div className="qr-scanner"> + <div className="qr-scanner__close" onClick={this.stopAndClose}></div> <div className="qr-scanner__title"> { `${t('scanQrCode')}` } </div> <div className="qr-scanner__content"> - { !this.props.error ? this.renderVideo() : null} + { this.renderVideo() } </div> - <div className={`qr-scanner__status ${this.props.error ? 'error' : ''}`}> + <div className={'qr-scanner__status'}> {this.state.msg} </div> </div> 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)), } } diff --git a/ui/app/components/send/to-autocomplete/to-autocomplete.js b/ui/app/components/send/to-autocomplete/to-autocomplete.js index 14e30e84c..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, @@ -109,10 +110,13 @@ ToAutoComplete.prototype.render = function () { borderColor: inError ? 'red' : null, }, }), - qrScanner && h(`i.fa.fa-qrcode.fa-lg.send-v2__to-autocomplete__qr-code`, { + 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(), diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index ad6199f02..806ac8536 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -629,13 +629,19 @@ &__qr-code { position: absolute; - top: 21px; - left: 13px; + top: 13px; + right: 33px; cursor: pointer; + padding: 8px 5px 5px; + border-radius: 4px; + } + + &__qr-code:hover { + background: #f1f1f1; } &__input.with-qr { - padding-left: 40px; + padding-right: 65px; } } diff --git a/ui/lib/webcam-utils.js b/ui/lib/webcam-utils.js index 9b507cd99..b1609ff4a 100644 --- a/ui/lib/webcam-utils.js +++ b/ui/lib/webcam-utils.js @@ -8,28 +8,29 @@ class WebcamUtils { static checkStatus () { return new Promise((resolve, reject) => { - const isPopup = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP - const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1 - const isBrave = !!window.chrome.ipcRenderer - const isFirefoxOrBrave = isFirefox || isBrave - try { - DetectRTC.load(_ => { - if (DetectRTC.hasWebcam) { - let environmentReady = true - if ((isFirefoxOrBrave && isPopup) || (isPopup && !DetectRTC.isWebsiteHasWebcamPermissions)) { - environmentReady = false - } - resolve({ - permissions: DetectRTC.isWebsiteHasWebcamPermissions, - environmentReady, - }) - } else { - reject({type: 'NO_WEBCAM_FOUND'}) - } - }) - } catch (e) { - reject({type: 'UNKNOWN_ERROR'}) - } + reject({type: 'UNKNOWN_ERROR'}) + // const isPopup = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP + // const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1 + // const isBrave = !!window.chrome.ipcRenderer + // const isFirefoxOrBrave = isFirefox || isBrave + // try { + // DetectRTC.load(_ => { + // if (DetectRTC.hasWebcam) { + // let environmentReady = true + // if ((isFirefoxOrBrave && isPopup) || (isPopup && !DetectRTC.isWebsiteHasWebcamPermissions)) { + // environmentReady = false + // } + // resolve({ + // permissions: DetectRTC.isWebsiteHasWebcamPermissions, + // environmentReady, + // }) + // } else { + // reject({type: 'NO_WEBCAM_FOUND'}) + // } + // }) + // } catch (e) { + // reject({type: 'UNKNOWN_ERROR'}) + // } }) } } |