mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
design complete
This commit is contained in:
parent
94a89790dc
commit
71ef4d85da
@ -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"
|
||||||
|
18
app/images/webcam.svg
Normal file
18
app/images/webcam.svg
Normal file
@ -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 = () => {
|
||||||
|
if (this.codeReader) {
|
||||||
this.codeReader.reset()
|
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 {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
renderErrorModal () {
|
||||||
const { t } = this.context
|
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 (
|
return (
|
||||||
<div className="qr-scanner">
|
<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">
|
<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
|
|
||||||
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'})
|
||||||
|
// }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user