import React, { memo, useEffect, useState } from 'react'; import { StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native'; import { Camera as RNCamera, useCodeScanner, useCameraDevice, type Code as ICameraResults, type CodeScannerFrame, } from 'react-native-vision-camera'; type Props = { style?: StyleProp | undefined; children: any; NoCameraDeviceError?: React.ReactNode | React.Component | Function; shouldScan?: boolean; onBarcodesDetected: (result: { code: string[] }) => void; }; const BarcodeScanner = ({ style, NoCameraDeviceError, onBarcodesDetected, children, ...props }: Props) => { const [hasPermission, setHasPermission] = useState(false); const device = useCameraDevice('back'); const codeScanner = useCodeScanner({ codeTypes: [ 'code-128', 'code-39', 'code-93', 'codabar', 'ean-13', 'ean-8', 'itf', 'upc-e', 'qr', 'pdf-417', 'aztec', 'data-matrix', ], onCodeScanned: (barcodes: ICameraResults[], _frame: CodeScannerFrame) => { let data: any[] = []; barcodes.forEach((barcode) => { if (!!barcode.value) data.push(barcode.value); }); if (!data.length) return; onBarcodesDetected({ code: data }); }, }); useEffect(() => { (async () => { if (RNCamera.getCameraPermissionStatus() !== 'granted') { const status = await RNCamera.requestCameraPermission(); setHasPermission(status === 'granted'); } else { setHasPermission(true); } })(); }, []); if (device == null) { if (typeof NoCameraDeviceError === 'function') return NoCameraDeviceError(); if (React.isValidElement(NoCameraDeviceError)) return NoCameraDeviceError; return null; } return ( {hasPermission && ( )} {children} ); }; export default memo(BarcodeScanner); const styles = StyleSheet.create({ cameraStyle: { flex: 1, width: '100%' }, });