@blackbox-vision/react-qr-reader
Advanced tools
Comparing version 4.0.0-0 to 4.0.0-1
@@ -8,50 +8,29 @@ 'use strict'; | ||
const getDeviceId = async (videoInputDevices, facingMode) => { | ||
const devices = []; | ||
const isMediaDevicesSupported = () => { | ||
const isMediaDevicesSupported = typeof navigator !== 'undefined' && !!navigator.mediaDevices; | ||
for (let videoInputDevice of videoInputDevices) { | ||
try { | ||
var _settings; | ||
if (!isMediaDevicesSupported) { | ||
console.warn(`[ReactQrReader]: MediaDevices API has no support for your browser. You can fix this by running "npm i webrtc-adapter"`); | ||
} | ||
const stream = await navigator.mediaDevices.getUserMedia({ | ||
video: { | ||
deviceId: { | ||
exact: videoInputDevice.deviceId | ||
} | ||
} | ||
}); | ||
const [track] = stream.getVideoTracks(); | ||
let settings = null; | ||
return isMediaDevicesSupported; | ||
}; | ||
const isValidType = (value, name, type) => { | ||
const isValid = typeof value === type; | ||
if (!!track) { | ||
settings = track.getSettings(); | ||
track.getCapabilities(); | ||
track.stop(); | ||
} | ||
devices.push({ | ||
deviceId: videoInputDevice.deviceId, | ||
facingMode: ((_settings = settings) === null || _settings === void 0 ? void 0 : _settings.facingMode) || facingMode, | ||
hasStreamingSupport: true | ||
}); | ||
} catch (err) { | ||
devices.push({ | ||
deviceId: videoInputDevice.deviceId, | ||
facingMode: null, | ||
hasStreamingSupport: false | ||
}); | ||
} | ||
if (!isValid) { | ||
console.warn(`[ReactQrReader]: Expected "${name}" to be a of type "${type}".`); | ||
} | ||
const [device] = devices.filter(device => device.hasStreamingSupport && device.facingMode === facingMode); | ||
return isValid; | ||
}; | ||
const isValidValue = (value, name, values) => { | ||
const hasValue = values.find(v => v === value); | ||
if (!device) { | ||
throw new Error('No video input devices found'); | ||
if (!hasValue) { | ||
console.warn(`[ReactQrReader]: Expected "${name}" to have one of the following values: "${JSON.stringify(values)}".`); | ||
} | ||
return device.deviceId; | ||
return hasValue; | ||
}; | ||
const isMediaDevicesSupported = () => { | ||
return typeof navigator !== 'undefined' && !!navigator.mediaDevices; | ||
}; | ||
@@ -70,19 +49,25 @@ const useQrReader = ({ | ||
if (!isMediaDevicesSupported()) { | ||
if (typeof onResult === 'function') { | ||
onResult(null, 'NoMediaDevicesSupportException'); | ||
} | ||
if (!isMediaDevicesSupported() && isValidType(onResult, 'onResult', 'function')) { | ||
const message = 'MediaDevices API has no support for your browser. You can fix this by running "npm i webrtc-adapter"'; | ||
onResult(null, new Error(message), codeReader); | ||
} | ||
browser.BrowserQRCodeReader.listVideoInputDevices().then(videoInputDevices => getDeviceId(videoInputDevices, facingMode)).then(deviceId => codeReader.decodeFromVideoDevice(deviceId, videoId, (result, error) => { | ||
const exception = error && error.name || error.name; | ||
if (isValidType(facingMode, 'facingMode', 'string') && isValidValue(facingMode, 'facingMode', ['user', 'left', 'right', 'environment'])) { | ||
// TODO: add support for passing additional props to constraints | ||
const constraints = { | ||
video: { | ||
facingMode | ||
} | ||
}; | ||
codeReader.decodeFromConstraints(constraints, videoId, (result, error) => { | ||
if (isValidType(onResult, 'onResult', 'function')) { | ||
onResult(result, error, codeReader); | ||
} | ||
}).then(controls => controlsRef.current = controls).catch(error => { | ||
if (isValidType(onResult, 'onResult', 'function')) { | ||
onResult(null, error, codeReader); | ||
} | ||
}); | ||
} | ||
if (typeof onResult === 'function') { | ||
onResult(result, exception, codeReader); | ||
} | ||
})).then(controls => controlsRef.current = controls).catch(err => { | ||
if (typeof onResult === 'function') { | ||
onResult(null, err, codeReader); | ||
} | ||
}); | ||
return () => { | ||
@@ -89,0 +74,0 @@ var _controlsRef$current; |
import { useEffect, useRef } from 'react'; | ||
import { BrowserQRCodeReader } from '@zxing/browser'; | ||
import * as BrowserHelpers from "./utils.js"; | ||
import * as Helpers from "./utils.js"; // TODO: add support for debug logs | ||
export const useQrReader = ({ | ||
@@ -16,19 +17,25 @@ facingMode, | ||
if (!BrowserHelpers.isMediaDevicesSupported()) { | ||
if (typeof onResult === 'function') { | ||
onResult(null, 'NoMediaDevicesSupportException'); | ||
} | ||
if (!Helpers.isMediaDevicesSupported() && Helpers.isValidType(onResult, 'onResult', 'function')) { | ||
const message = 'MediaDevices API has no support for your browser. You can fix this by running "npm i webrtc-adapter"'; | ||
onResult(null, new Error(message), codeReader); | ||
} | ||
BrowserQRCodeReader.listVideoInputDevices().then(videoInputDevices => BrowserHelpers.getDeviceId(videoInputDevices, facingMode)).then(deviceId => codeReader.decodeFromVideoDevice(deviceId, videoId, (result, error) => { | ||
const exception = error && error.name || error.name; | ||
if (Helpers.isValidType(facingMode, 'facingMode', 'string') && Helpers.isValidValue(facingMode, 'facingMode', ['user', 'left', 'right', 'environment'])) { | ||
// TODO: add support for passing additional props to constraints | ||
const constraints = { | ||
video: { | ||
facingMode | ||
} | ||
}; | ||
codeReader.decodeFromConstraints(constraints, videoId, (result, error) => { | ||
if (Helpers.isValidType(onResult, 'onResult', 'function')) { | ||
onResult(result, error, codeReader); | ||
} | ||
}).then(controls => controlsRef.current = controls).catch(error => { | ||
if (Helpers.isValidType(onResult, 'onResult', 'function')) { | ||
onResult(null, error, codeReader); | ||
} | ||
}); | ||
} | ||
if (typeof onResult === 'function') { | ||
onResult(result, exception, codeReader); | ||
} | ||
})).then(controls => controlsRef.current = controls).catch(err => { | ||
if (typeof onResult === 'function') { | ||
onResult(null, err, codeReader); | ||
} | ||
}); | ||
return () => { | ||
@@ -35,0 +42,0 @@ var _controlsRef$current; |
@@ -1,48 +0,27 @@ | ||
export const getDeviceId = async (videoInputDevices, facingMode) => { | ||
const devices = []; | ||
export const isMediaDevicesSupported = () => { | ||
const isMediaDevicesSupported = typeof navigator !== 'undefined' && !!navigator.mediaDevices; | ||
for (let videoInputDevice of videoInputDevices) { | ||
try { | ||
var _settings; | ||
if (!isMediaDevicesSupported) { | ||
console.warn(`[ReactQrReader]: MediaDevices API has no support for your browser. You can fix this by running "npm i webrtc-adapter"`); | ||
} | ||
const stream = await navigator.mediaDevices.getUserMedia({ | ||
video: { | ||
deviceId: { | ||
exact: videoInputDevice.deviceId | ||
} | ||
} | ||
}); | ||
const [track] = stream.getVideoTracks(); | ||
let settings = null; | ||
return isMediaDevicesSupported; | ||
}; | ||
export const isValidType = (value, name, type) => { | ||
const isValid = typeof value === type; | ||
if (!!track) { | ||
settings = track.getSettings(); | ||
track.getCapabilities(); | ||
track.stop(); | ||
} | ||
devices.push({ | ||
deviceId: videoInputDevice.deviceId, | ||
facingMode: ((_settings = settings) === null || _settings === void 0 ? void 0 : _settings.facingMode) || facingMode, | ||
hasStreamingSupport: true | ||
}); | ||
} catch (err) { | ||
devices.push({ | ||
deviceId: videoInputDevice.deviceId, | ||
facingMode: null, | ||
hasStreamingSupport: false | ||
}); | ||
} | ||
if (!isValid) { | ||
console.warn(`[ReactQrReader]: Expected "${name}" to be a of type "${type}".`); | ||
} | ||
const [device] = devices.filter(device => device.hasStreamingSupport && device.facingMode === facingMode); | ||
return isValid; | ||
}; | ||
export const isValidValue = (value, name, values) => { | ||
const hasValue = values.find(v => v === value); | ||
if (!device) { | ||
throw new Error('No video input devices found'); | ||
if (!hasValue) { | ||
console.warn(`[ReactQrReader]: Expected "${name}" to have one of the following values: "${JSON.stringify(values)}".`); | ||
} | ||
return device.deviceId; | ||
}; | ||
export const isMediaDevicesSupported = () => { | ||
return typeof navigator !== 'undefined' && !!navigator.mediaDevices; | ||
return hasValue; | ||
}; |
@@ -1,2 +0,3 @@ | ||
export declare const getDeviceId: (videoInputDevices: MediaDeviceInfo[], facingMode: VideoFacingModeEnum) => Promise<string>; | ||
export declare const isMediaDevicesSupported: () => boolean; | ||
export declare const isValidType: (value: any, name: string, type: string) => boolean; | ||
export declare const isValidValue: (value: any, name: string, values: any[]) => any; |
@@ -34,4 +34,2 @@ /// <reference types="react" /> | ||
}; | ||
export declare type CodeReaderError = 'FormatException' | 'NotFoundException' | 'ChecksumException' | 'NoDeviceFoundException' | 'NoMediaDevicesSupportException' | string | Error; | ||
export declare type UseQrReaderHook = (props: UseQrReaderHookProps) => void; | ||
export declare type OnResultFunction = ( | ||
@@ -41,7 +39,7 @@ /** | ||
*/ | ||
result?: Result, | ||
result?: Result | undefined | null, | ||
/** | ||
* The name of the exceptions thrown while reading the QR | ||
*/ | ||
error?: CodeReaderError, | ||
error?: Error | undefined | null, | ||
/** | ||
@@ -69,15 +67,2 @@ * The instance of the QR browser reader | ||
}; | ||
export declare type Device = { | ||
/** | ||
* Property that represents the ID from video device | ||
*/ | ||
deviceId: string; | ||
/** | ||
* Property that represents which kind of camera is the device | ||
*/ | ||
facingMode: 'user' | 'environment' | string | null; | ||
/** | ||
* Property that represents if the camera supports streaming video | ||
*/ | ||
hasStreamingSupport: boolean; | ||
}; | ||
export declare type UseQrReaderHook = (props: UseQrReaderHookProps) => void; |
import { useRef, useEffect, createElement } from 'react'; | ||
import { BrowserQRCodeReader } from '@zxing/browser'; | ||
const getDeviceId = async (videoInputDevices, facingMode) => { | ||
const devices = []; | ||
const isMediaDevicesSupported = () => { | ||
const isMediaDevicesSupported = typeof navigator !== 'undefined' && !!navigator.mediaDevices; | ||
for (let videoInputDevice of videoInputDevices) { | ||
try { | ||
var _settings; | ||
if (!isMediaDevicesSupported) { | ||
console.warn(`[ReactQrReader]: MediaDevices API has no support for your browser. You can fix this by running "npm i webrtc-adapter"`); | ||
} | ||
const stream = await navigator.mediaDevices.getUserMedia({ | ||
video: { | ||
deviceId: { | ||
exact: videoInputDevice.deviceId | ||
} | ||
} | ||
}); | ||
const [track] = stream.getVideoTracks(); | ||
let settings = null; | ||
return isMediaDevicesSupported; | ||
}; | ||
const isValidType = (value, name, type) => { | ||
const isValid = typeof value === type; | ||
if (!!track) { | ||
settings = track.getSettings(); | ||
track.getCapabilities(); | ||
track.stop(); | ||
} | ||
devices.push({ | ||
deviceId: videoInputDevice.deviceId, | ||
facingMode: ((_settings = settings) === null || _settings === void 0 ? void 0 : _settings.facingMode) || facingMode, | ||
hasStreamingSupport: true | ||
}); | ||
} catch (err) { | ||
devices.push({ | ||
deviceId: videoInputDevice.deviceId, | ||
facingMode: null, | ||
hasStreamingSupport: false | ||
}); | ||
} | ||
if (!isValid) { | ||
console.warn(`[ReactQrReader]: Expected "${name}" to be a of type "${type}".`); | ||
} | ||
const [device] = devices.filter(device => device.hasStreamingSupport && device.facingMode === facingMode); | ||
return isValid; | ||
}; | ||
const isValidValue = (value, name, values) => { | ||
const hasValue = values.find(v => v === value); | ||
if (!device) { | ||
throw new Error('No video input devices found'); | ||
if (!hasValue) { | ||
console.warn(`[ReactQrReader]: Expected "${name}" to have one of the following values: "${JSON.stringify(values)}".`); | ||
} | ||
return device.deviceId; | ||
return hasValue; | ||
}; | ||
const isMediaDevicesSupported = () => { | ||
return typeof navigator !== 'undefined' && !!navigator.mediaDevices; | ||
}; | ||
@@ -65,19 +44,25 @@ const useQrReader = ({ | ||
if (!isMediaDevicesSupported()) { | ||
if (typeof onResult === 'function') { | ||
onResult(null, 'NoMediaDevicesSupportException'); | ||
} | ||
if (!isMediaDevicesSupported() && isValidType(onResult, 'onResult', 'function')) { | ||
const message = 'MediaDevices API has no support for your browser. You can fix this by running "npm i webrtc-adapter"'; | ||
onResult(null, new Error(message), codeReader); | ||
} | ||
BrowserQRCodeReader.listVideoInputDevices().then(videoInputDevices => getDeviceId(videoInputDevices, facingMode)).then(deviceId => codeReader.decodeFromVideoDevice(deviceId, videoId, (result, error) => { | ||
const exception = error && error.name || error.name; | ||
if (isValidType(facingMode, 'facingMode', 'string') && isValidValue(facingMode, 'facingMode', ['user', 'left', 'right', 'environment'])) { | ||
// TODO: add support for passing additional props to constraints | ||
const constraints = { | ||
video: { | ||
facingMode | ||
} | ||
}; | ||
codeReader.decodeFromConstraints(constraints, videoId, (result, error) => { | ||
if (isValidType(onResult, 'onResult', 'function')) { | ||
onResult(result, error, codeReader); | ||
} | ||
}).then(controls => controlsRef.current = controls).catch(error => { | ||
if (isValidType(onResult, 'onResult', 'function')) { | ||
onResult(null, error, codeReader); | ||
} | ||
}); | ||
} | ||
if (typeof onResult === 'function') { | ||
onResult(result, exception, codeReader); | ||
} | ||
})).then(controls => controlsRef.current = controls).catch(err => { | ||
if (typeof onResult === 'function') { | ||
onResult(null, err, codeReader); | ||
} | ||
}); | ||
return () => { | ||
@@ -84,0 +69,0 @@ var _controlsRef$current; |
{ | ||
"name": "@blackbox-vision/react-qr-reader", | ||
"description": "A React Component for reading QR codes from the webcam", | ||
"version": "4.0.0-0", | ||
"version": "4.0.0-1", | ||
"license": "MIT", | ||
@@ -6,0 +6,0 @@ "files": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
39633
501