1import { PermissionStatus, createPermissionHook, UnavailabilityError, } from 'expo-modules-core'; 2import * as React from 'react'; 3import { Platform } from 'react-native'; 4import ExpoBarCodeScannerModule from './ExpoBarCodeScannerModule'; 5import ExpoBarCodeScannerView from './ExpoBarCodeScannerView'; 6const { BarCodeType, Type } = ExpoBarCodeScannerModule; 7const EVENT_THROTTLE_MS = 500; 8export class BarCodeScanner extends React.Component { 9 lastEvents = {}; 10 lastEventsTimes = {}; 11 static Constants = { 12 BarCodeType, 13 Type, 14 }; 15 static ConversionTables = { 16 type: Type, 17 }; 18 static defaultProps = { 19 type: Type.back, 20 barCodeTypes: Object.values(BarCodeType), 21 }; 22 // @needsAudit 23 /** 24 * Checks user's permissions for accessing the camera. 25 * @return Return a promise that fulfills to an object of type [`PermissionResponse`](#permissionresponse). 26 */ 27 static async getPermissionsAsync() { 28 return ExpoBarCodeScannerModule.getPermissionsAsync(); 29 } 30 // @needsAudit 31 /** 32 * Asks the user to grant permissions for accessing the camera. 33 * 34 * On iOS this will require apps to specify the `NSCameraUsageDescription` entry in the `Info.plist`. 35 * @return Return a promise that fulfills to an object of type [`PermissionResponse`](#permissionresponse). 36 */ 37 static async requestPermissionsAsync() { 38 return ExpoBarCodeScannerModule.requestPermissionsAsync(); 39 } 40 // @needsAudit 41 /** 42 * Check or request permissions for the barcode scanner. 43 * This uses both `requestPermissionAsync` and `getPermissionsAsync` to interact with the permissions. 44 * 45 * @example 46 * ```ts 47 * const [permissionResponse, requestPermission] = BarCodeScanner.usePermissions(); 48 * ``` 49 */ 50 static usePermissions = createPermissionHook({ 51 getMethod: BarCodeScanner.getPermissionsAsync, 52 requestMethod: BarCodeScanner.requestPermissionsAsync, 53 }); 54 // @needsAudit 55 /** 56 * Scan bar codes from the image given by the URL. 57 * @param url URL to get the image from. 58 * @param barCodeTypes An array of bar code types. Defaults to all supported bar code types on 59 * the platform. 60 * > __Note:__ Only QR codes are supported on iOS. 61 * @return A possibly empty array of objects of the `BarCodeScannerResult` shape, where the type 62 * refers to the bar code type that was scanned and the data is the information encoded in the bar 63 * code. 64 */ 65 static async scanFromURLAsync(url, barCodeTypes = Object.values(BarCodeType)) { 66 if (!ExpoBarCodeScannerModule.scanFromURLAsync) { 67 throw new UnavailabilityError('expo-barcode-scanner', 'scanFromURLAsync'); 68 } 69 if (Array.isArray(barCodeTypes) && !barCodeTypes.length) { 70 throw new Error('No barCodeTypes specified; provide at least one barCodeType for scanner'); 71 } 72 if (Platform.OS === 'ios') { 73 if (Array.isArray(barCodeTypes) && !barCodeTypes.includes(BarCodeType.qr)) { 74 // Only QR type is supported on iOS, fail if one tries to use other types 75 throw new Error('Only QR type is supported by scanFromURLAsync() on iOS'); 76 } 77 // on iOS use only supported QR type 78 return await ExpoBarCodeScannerModule.scanFromURLAsync(url, [BarCodeType.qr]); 79 } 80 // On other platforms, if barCodeTypes is not provided, use all available types 81 return await ExpoBarCodeScannerModule.scanFromURLAsync(url, barCodeTypes); 82 } 83 render() { 84 const nativeProps = this.convertNativeProps(this.props); 85 const { onBarCodeScanned } = this.props; 86 return (React.createElement(ExpoBarCodeScannerView, { ...nativeProps, onBarCodeScanned: this.onObjectDetected(onBarCodeScanned) })); 87 } 88 /** 89 * @hidden 90 */ 91 onObjectDetected = (callback) => ({ nativeEvent }) => { 92 const { type } = nativeEvent; 93 if (this.lastEvents[type] && 94 this.lastEventsTimes[type] && 95 JSON.stringify(nativeEvent) === this.lastEvents[type] && 96 Date.now() - this.lastEventsTimes[type] < EVENT_THROTTLE_MS) { 97 return; 98 } 99 if (callback) { 100 callback(nativeEvent); 101 this.lastEventsTimes[type] = new Date(); 102 this.lastEvents[type] = JSON.stringify(nativeEvent); 103 } 104 }; 105 /** 106 * @hidden 107 */ 108 convertNativeProps(props) { 109 const nativeProps = {}; 110 for (const [key, value] of Object.entries(props)) { 111 if (typeof value === 'string' && BarCodeScanner.ConversionTables[key]) { 112 nativeProps[key] = BarCodeScanner.ConversionTables[key][value]; 113 } 114 else { 115 nativeProps[key] = value; 116 } 117 } 118 return nativeProps; 119 } 120} 121export { PermissionStatus }; 122export const { Constants, getPermissionsAsync, requestPermissionsAsync, scanFromURLAsync } = BarCodeScanner; 123//# sourceMappingURL=BarCodeScanner.js.map