design complete

feature/default_network_editable
brunobar79 6 years ago
parent 94a89790dc
commit 71ef4d85da
  1. 10
      app/_locales/en/messages.json
  2. 18
      app/images/webcam.svg
  3. 40
      ui/app/components/modals/qr-scanner/index.scss
  4. 72
      ui/app/components/modals/qr-scanner/qr-scanner.component.js
  5. 6
      ui/app/components/modals/qr-scanner/qr-scanner.container.js
  6. 8
      ui/app/components/send/to-autocomplete/to-autocomplete.js
  7. 12
      ui/app/css/itcss/components/send.scss
  8. 45
      ui/lib/webcam-utils.js

@ -656,8 +656,11 @@
"notStarted": { "notStarted": {
"message": "Not Started" "message": "Not Started"
}, },
"noWebcamFoundTitle": {
"message": "Webcam not found"
},
"noWebcamFound": { "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": { "oldUI": {
"message": "Old UI" "message": "Old UI"
@ -1101,8 +1104,11 @@
"unknownQrCode": { "unknownQrCode": {
"message": "Error: We couldn't identify that QR code" "message": "Error: We couldn't identify that QR code"
}, },
"unknownCameraErrorTitle": {
"message": "Ooops! Something went wrong...."
},
"unknownCameraError": { "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": { "unlock": {
"message": "Unlock" "message": "Unlock"

@ -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>

After

Width:  |  Height:  |  Size: 1020 B

@ -39,9 +39,45 @@
padding: 15px; padding: 15px;
} }
&__status.error { &__image {
padding: 60px 45px 80px; font-size: 1.5rem;
font-weight: 500;
padding: 16px 0 0;
text-align: center;
}
&__error {
text-align: center;
font-size: 16px; 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;
} }
} }

@ -9,6 +9,7 @@ export default class QrScanner extends Component {
static propTypes = { static propTypes = {
hideModal: PropTypes.func.isRequired, hideModal: PropTypes.func.isRequired,
qrCodeDetected: PropTypes.func, qrCodeDetected: PropTypes.func,
scanQrCode: PropTypes.func,
error: PropTypes.bool, error: PropTypes.bool,
errorType: PropTypes.string, errorType: PropTypes.string,
} }
@ -20,18 +21,9 @@ export default class QrScanner extends Component {
constructor (props, context) { constructor (props, context) {
super(props) 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 = { this.state = {
ready: false, ready: false,
msg: initialMsg, msg: context.t('accessingYourCamera'),
} }
this.codeReader = null this.codeReader = null
this.permissionChecker = null this.permissionChecker = null
@ -118,11 +110,22 @@ export default class QrScanner extends Component {
stopAndClose = () => { stopAndClose = () => {
this.codeReader.reset() if (this.codeReader) {
this.codeReader.reset()
}
this.setState({ ready: false }) this.setState({ ready: false })
this.props.hideModal() this.props.hideModal()
} }
tryAgain = () => {
// close the modal
this.stopAndClose()
// wait for the animation and try again
setTimeout(_ => {
this.props.scanQrCode()
}, 1000)
}
renderVideo () { renderVideo () {
return ( return (
<div className={'qr-scanner__content__video-wrapper'}> <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 () { render () {
const { t } = this.context const { t } = this.context
if (this.props.error) {
return this.renderErrorModal()
}
return ( return (
<div className="qr-scanner"> <div className="qr-scanner">
<div className="qr-scanner__close" onClick={this.stopAndClose}></div>
<div className="qr-scanner__title"> <div className="qr-scanner__title">
{ `${t('scanQrCode')}` } { `${t('scanQrCode')}` }
</div> </div>
<div className="qr-scanner__content"> <div className="qr-scanner__content">
{ !this.props.error ? this.renderVideo() : null} { this.renderVideo() }
</div> </div>
<div className={`qr-scanner__status ${this.props.error ? 'error' : ''}`}> <div className={'qr-scanner__status'}>
{this.state.msg} {this.state.msg}
</div> </div>
</div> </div>

@ -1,7 +1,10 @@
import { connect } from 'react-redux' import { connect } from 'react-redux'
import QrScanner from './qr-scanner.component' 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 => { const mapStateToProps = state => {
return { return {
@ -14,6 +17,7 @@ const mapDispatchToProps = dispatch => {
return { return {
hideModal: () => dispatch(hideModal()), hideModal: () => dispatch(hideModal()),
qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), qrCodeDetected: (data) => dispatch(qrCodeDetected(data)),
scanQrCode: () => dispatch(showQrScanner(SEND_ROUTE)),
} }
} }

@ -4,6 +4,7 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits const inherits = require('util').inherits
const AccountListItem = require('../account-list-item/account-list-item.component').default const AccountListItem = require('../account-list-item/account-list-item.component').default
const connect = require('react-redux').connect const connect = require('react-redux').connect
const Tooltip = require('../../tooltip')
ToAutoComplete.contextTypes = { ToAutoComplete.contextTypes = {
t: PropTypes.func, t: PropTypes.func,
@ -109,10 +110,13 @@ ToAutoComplete.prototype.render = function () {
borderColor: inError ? 'red' : null, 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' }, style: { color: '#33333' },
onClick: () => this.props.scanQrCode(), onClick: () => this.props.scanQrCode(),
}), })),
!to && h(`i.fa.fa-caret-down.fa-lg.send-v2__to-autocomplete__down-caret`, { !to && h(`i.fa.fa-caret-down.fa-lg.send-v2__to-autocomplete__down-caret`, {
style: { color: '#dedede' }, style: { color: '#dedede' },
onClick: () => this.handleInputEvent(), onClick: () => this.handleInputEvent(),

@ -629,13 +629,19 @@
&__qr-code { &__qr-code {
position: absolute; position: absolute;
top: 21px; top: 13px;
left: 13px; right: 33px;
cursor: pointer; cursor: pointer;
padding: 8px 5px 5px;
border-radius: 4px;
}
&__qr-code:hover {
background: #f1f1f1;
} }
&__input.with-qr { &__input.with-qr {
padding-left: 40px; padding-right: 65px;
} }
} }

@ -8,28 +8,29 @@ class WebcamUtils {
static checkStatus () { static checkStatus () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const isPopup = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP reject({type: 'UNKNOWN_ERROR'})
const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1 // const isPopup = getEnvironmentType(window.location.href) === ENVIRONMENT_TYPE_POPUP
const isBrave = !!window.chrome.ipcRenderer // const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
const isFirefoxOrBrave = isFirefox || isBrave // const isBrave = !!window.chrome.ipcRenderer
try { // const isFirefoxOrBrave = isFirefox || isBrave
DetectRTC.load(_ => { // try {
if (DetectRTC.hasWebcam) { // DetectRTC.load(_ => {
let environmentReady = true // if (DetectRTC.hasWebcam) {
if ((isFirefoxOrBrave && isPopup) || (isPopup && !DetectRTC.isWebsiteHasWebcamPermissions)) { // let environmentReady = true
environmentReady = false // if ((isFirefoxOrBrave && isPopup) || (isPopup && !DetectRTC.isWebsiteHasWebcamPermissions)) {
} // environmentReady = false
resolve({ // }
permissions: DetectRTC.isWebsiteHasWebcamPermissions, // resolve({
environmentReady, // permissions: DetectRTC.isWebsiteHasWebcamPermissions,
}) // environmentReady,
} else { // })
reject({type: 'NO_WEBCAM_FOUND'}) // } else {
} // reject({type: 'NO_WEBCAM_FOUND'})
}) // }
} catch (e) { // })
reject({type: 'UNKNOWN_ERROR'}) // } catch (e) {
} // reject({type: 'UNKNOWN_ERROR'})
// }
}) })
} }
} }

Loading…
Cancel
Save