Fix the media stream not being stopped; mirror the QR camera (#2165)
Co-authored-by: katspaugh <--replace-all> Co-authored-by: Fernando <fernando.greco@gmail.com>
This commit is contained in:
parent
b8de127c42
commit
82d8ab357d
|
@ -21,6 +21,6 @@ jobs:
|
||||||
path-to-signatures: 'signatures/version1/cla.json'
|
path-to-signatures: 'signatures/version1/cla.json'
|
||||||
path-to-cla-document: 'https://github.com/gnosis/safe-react/blob/master/GNOSISCLA.md'
|
path-to-cla-document: 'https://github.com/gnosis/safe-react/blob/master/GNOSISCLA.md'
|
||||||
branch: 'cla-signatures'
|
branch: 'cla-signatures'
|
||||||
allowlist: lukasschor,mikheevm,rmeissner,germartinez,fernandomg,Agupane,nicosampler,matextrem,gabitoesmiapodo,davidalbela,alongoni,Uxio0,dasanra,miguelmota,francovenica,tschubotz,luarx,giacomolicari,gnosis-info,bot*
|
allowlist: lukasschor,mikheevm,rmeissner,germartinez,fernandomg,Agupane,nicosampler,matextrem,gabitoesmiapodo,davidalbela,alongoni,Uxio0,dasanra,miguelmota,francovenica,tschubotz,luarx,giacomolicari,gnosis-info,bot*,katspaugh
|
||||||
empty-commit-flag: false
|
empty-commit-flag: false
|
||||||
blockchain-storage-flag: false
|
blockchain-storage-flag: false
|
||||||
|
|
|
@ -27,7 +27,7 @@ export const ScanQRWrapper = ({ handleScan }: Props): ReactElement => {
|
||||||
setQrModalOpen(false)
|
setQrModalOpen(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onScanFinished = (value) => {
|
const onScanFinished = (value: string) => {
|
||||||
handleScan(value, closeQrModal)
|
handleScan(value, closeQrModal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import { Loader } from '@gnosis.pm/safe-react-components'
|
|
||||||
import IconButton from '@material-ui/core/IconButton'
|
import IconButton from '@material-ui/core/IconButton'
|
||||||
import { makeStyles } from '@material-ui/core/styles'
|
import { makeStyles } from '@material-ui/core/styles'
|
||||||
import Close from '@material-ui/icons/Close'
|
import Close from '@material-ui/icons/Close'
|
||||||
|
@ -6,7 +5,6 @@ import * as React from 'react'
|
||||||
import QrReader from 'react-qr-reader'
|
import QrReader from 'react-qr-reader'
|
||||||
|
|
||||||
import { styles } from './style'
|
import { styles } from './style'
|
||||||
import { checkWebcam } from './utils'
|
|
||||||
|
|
||||||
import Modal from 'src/components/Modal'
|
import Modal from 'src/components/Modal'
|
||||||
import Block from 'src/components/layout/Block'
|
import Block from 'src/components/layout/Block'
|
||||||
|
@ -27,45 +25,39 @@ type Props = {
|
||||||
|
|
||||||
export const ScanQRModal = ({ isOpen, onClose, onScan }: Props): React.ReactElement => {
|
export const ScanQRModal = ({ isOpen, onClose, onScan }: Props): React.ReactElement => {
|
||||||
const classes = useStyles()
|
const classes = useStyles()
|
||||||
const [useWebcam, setUseWebcam] = useState<boolean | null>(null)
|
|
||||||
const [fileUploadModalOpen, setFileUploadModalOpen] = useState<boolean>(false)
|
const [fileUploadModalOpen, setFileUploadModalOpen] = useState<boolean>(false)
|
||||||
const [error, setError] = useState<string | null>(null)
|
const [error, setError] = useState<string | null>(null)
|
||||||
|
const [cameraBlocked, setCameraBlocked] = useState<boolean>(false)
|
||||||
const scannerRef: any = React.createRef()
|
const scannerRef: any = React.createRef()
|
||||||
const openImageDialog = React.useCallback(() => {
|
const openImageDialog = React.useCallback(() => {
|
||||||
scannerRef.current.openImageDialog()
|
scannerRef.current.openImageDialog()
|
||||||
}, [scannerRef])
|
}, [scannerRef])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
checkWebcam(
|
if (!fileUploadModalOpen && cameraBlocked && !error) {
|
||||||
() => {
|
|
||||||
setUseWebcam(true)
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
setUseWebcam(false)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (useWebcam === false && !fileUploadModalOpen && !error) {
|
|
||||||
setFileUploadModalOpen(true)
|
setFileUploadModalOpen(true)
|
||||||
openImageDialog()
|
openImageDialog()
|
||||||
}
|
}
|
||||||
}, [useWebcam, openImageDialog, fileUploadModalOpen, setFileUploadModalOpen, error])
|
}, [cameraBlocked, openImageDialog, fileUploadModalOpen, setFileUploadModalOpen, error])
|
||||||
|
|
||||||
|
const onFileScannedResolve = (error: Error | null, successData: string | null) => {
|
||||||
|
if (error) {
|
||||||
|
console.error('QR code error', error)
|
||||||
|
|
||||||
|
if (error.name === 'NotAllowedError' || error.name === 'PermissionDismissedError') {
|
||||||
|
setCameraBlocked(true)
|
||||||
|
setFileUploadModalOpen(false)
|
||||||
|
} else {
|
||||||
|
setError('The QR could not be read')
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const onFileScannedResolve = (error: string | null, successData: string | null) => {
|
|
||||||
if (successData) {
|
if (successData) {
|
||||||
onScan(successData)
|
onScan(successData)
|
||||||
|
} else if (cameraBlocked) {
|
||||||
|
setError('The QR could not be read')
|
||||||
}
|
}
|
||||||
if (error) {
|
|
||||||
console.error('Error uploading file', error)
|
|
||||||
setError(`The QR could not be read`)
|
|
||||||
}
|
|
||||||
if (!useWebcam) {
|
|
||||||
setError(`The QR could not be read`)
|
|
||||||
}
|
|
||||||
|
|
||||||
setFileUploadModalOpen(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -80,20 +72,19 @@ export const ScanQRModal = ({ isOpen, onClose, onScan }: Props): React.ReactElem
|
||||||
</Row>
|
</Row>
|
||||||
<Hairline />
|
<Hairline />
|
||||||
<Col className={classes.detailsContainer} layout="column" middle="xs">
|
<Col className={classes.detailsContainer} layout="column" middle="xs">
|
||||||
|
{error && (
|
||||||
|
<Block padding="md" margin="md">
|
||||||
{error}
|
{error}
|
||||||
{useWebcam === null ? (
|
|
||||||
<Block className={classes.loaderContainer} justify="center">
|
|
||||||
<Loader size="md" />
|
|
||||||
</Block>
|
</Block>
|
||||||
) : (
|
)}
|
||||||
<QrReader
|
<QrReader
|
||||||
legacyMode={!useWebcam}
|
legacyMode={cameraBlocked}
|
||||||
onError={(err) => onFileScannedResolve(err, null)}
|
onError={(err: Error) => onFileScannedResolve(err, null)}
|
||||||
onScan={(data) => onFileScannedResolve(null, data)}
|
onScan={(data: string) => onFileScannedResolve(null, data)}
|
||||||
ref={scannerRef}
|
ref={scannerRef}
|
||||||
style={{ width: '400px', height: '400px' }}
|
style={{ width: '400px', height: '400px' }}
|
||||||
|
facingMode="user"
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</Col>
|
</Col>
|
||||||
<Hairline />
|
<Hairline />
|
||||||
<Row align="center" className={classes.buttonRow}>
|
<Row align="center" className={classes.buttonRow}>
|
||||||
|
@ -105,7 +96,7 @@ export const ScanQRModal = ({ isOpen, onClose, onScan }: Props): React.ReactElem
|
||||||
color="primary"
|
color="primary"
|
||||||
minWidth={154}
|
minWidth={154}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setUseWebcam(false)
|
setCameraBlocked(true)
|
||||||
setError(null)
|
setError(null)
|
||||||
setFileUploadModalOpen(false)
|
setFileUploadModalOpen(false)
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -19,7 +19,7 @@ export const styles = createStyles({
|
||||||
},
|
},
|
||||||
detailsContainer: {
|
detailsContainer: {
|
||||||
backgroundColor: background,
|
backgroundColor: background,
|
||||||
maxHeight: '420px',
|
maxHeight: '450px',
|
||||||
},
|
},
|
||||||
buttonRow: {
|
buttonRow: {
|
||||||
height: '84px',
|
height: '84px',
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
const navigatorCp: any = navigator
|
|
||||||
|
|
||||||
navigatorCp.getMedia =
|
|
||||||
navigatorCp.getUserMedia || // use the proper vendor prefix
|
|
||||||
navigatorCp.webkitGetUserMedia ||
|
|
||||||
navigatorCp.mozGetUserMedia ||
|
|
||||||
navigatorCp.msGetUserMedia
|
|
||||||
|
|
||||||
export const checkWebcam = (success, err) =>
|
|
||||||
navigatorCp.getMedia(
|
|
||||||
{ video: true },
|
|
||||||
() => {
|
|
||||||
success()
|
|
||||||
},
|
|
||||||
() => {
|
|
||||||
err()
|
|
||||||
},
|
|
||||||
)
|
|
Loading…
Reference in New Issue