import React, { useState, useEffect } from 'react'; import intl from 'react-intl-universal'; import styled from 'styled-components'; import { Alert, Select, Modal } from 'antd'; import { BrowserCodeReader } from '@zxing/browser'; import { BrowserMultiFormatReader, DecodeHintType, BarcodeFormat } from '@zxing/library'; import { Result } from '@zxing/library'; import _ from 'lodash'; import { InfoCircleTwoTone } from '@ant-design/icons'; const StyledScanQRCode = styled.span` display: block; `; const StyledModal = styled(Modal)` width: 400px !important; height: 400px !important; .ant-modal-close { top: 20px !important; right: 20px !important; } .ant-modal-body { border-bottom-left-radius: 24px; border-bottom-right-radius: 24px; } `; const QRPreview = styled.video` width: 100%; `; type ScanBarcodeProps = { loadWithCameraOpen: boolean; onScan: Function; id: string; }; const ScanBarcode = (props: ScanBarcodeProps) => { const { loadWithCameraOpen, onScan, id, ...otherProps } = props; const [visible, setVisible] = useState(loadWithCameraOpen); const [error, setError] = useState(false); // Use these states to debug video errors on mobile // Note: iOS chrome/brave/firefox does not support accessing camera, will throw error // iOS users can use safari // todo only show scanner with safari //const [mobileError, setMobileError] = useState(false); //const [mobileErrorMsg, setMobileErrorMsg] = useState(false); const [activeCodeReader, setActiveCodeReader] = useState(); const [lixiValue, setLixiValue] = useState(undefined); const [errorMsg, setErrorMsg] = useState(); const [videoInputDevices, setVideoInputDevices] = useState(); const setupCodeReader = () => { var hints = new Map(); const formats = [BarcodeFormat.UPC_A]; hints.set(DecodeHintType.ASSUME_GS1, true); hints.set(DecodeHintType.TRY_HARDER, true); hints.set(DecodeHintType.POSSIBLE_FORMATS, formats); const codeReader = new BrowserMultiFormatReader(hints); setActiveCodeReader(codeReader); }; const setupVideoSource = () => { BrowserCodeReader.listVideoInputDevices().then(videoInputDevices => { if (videoInputDevices.length >= 1) { setVideoInputDevices(videoInputDevices); } }); }; const scanForBarcode = async videoSource => { try { activeCodeReader?.reset(); const previewElem = document.querySelector('#test-area-qr-code-webcam-' + id); await activeCodeReader!.decodeFromVideoDevice(videoSource, previewElem as any, (content: Result, controls) => { if (!_.isNil(content) && content.getText()) { const result = content.getText(); setLixiValue(result); onScan(result); } }); } catch (err) { console.log(intl.get('general.QRScannerError')); console.log(err); console.log(JSON.stringify((err as any).message)); setErrorMsg(JSON.stringify((err as any).message)); //setMobileErrorMsg(JSON.stringify(err.message)); setError(err as any); activeCodeReader?.reset(); } }; useEffect(() => { setupCodeReader(); setupVideoSource(); }, []); useEffect(() => { if (!visible) { setError(false); // Stop the camera if user closes modal activeCodeReader && activeCodeReader.reset(); setLixiValue(undefined); } }, [visible]); const onChangeVideoSource = value => { scanForBarcode(value); }; return ( <> setVisible(!visible)}> {intl.get('general.scanBarcode')}

{intl.get('general.scanBarcode')}

{intl.get('general.chooseCameraTip')}
} open={visible} onCancel={() => setVisible(false)} destroyOnClose={true} footer={ <>

{lixiValue}

} > {visible ? (
{error ? ( <> ) : ( <> )}
) : null}
); }; export default ScanBarcode;