@chayns-components/scanner 5.0.0-beta.1265

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -0
  3. package/lib/cjs/components/code-scanner/CodeScanner.js +227 -0
  4. package/lib/cjs/components/code-scanner/CodeScanner.js.map +1 -0
  5. package/lib/cjs/components/code-scanner/CodeScanner.styles.js +34 -0
  6. package/lib/cjs/components/code-scanner/CodeScanner.styles.js.map +1 -0
  7. package/lib/cjs/components/code-scanner/scanner-toolbar/ScannerToolbar.js +149 -0
  8. package/lib/cjs/components/code-scanner/scanner-toolbar/ScannerToolbar.js.map +1 -0
  9. package/lib/cjs/components/code-scanner/scanner-toolbar/ScannerToolbar.styles.js +50 -0
  10. package/lib/cjs/components/code-scanner/scanner-toolbar/ScannerToolbar.styles.js.map +1 -0
  11. package/lib/cjs/constants/codeScanner.js +20 -0
  12. package/lib/cjs/constants/codeScanner.js.map +1 -0
  13. package/lib/cjs/hooks/codeScanner.js +16 -0
  14. package/lib/cjs/hooks/codeScanner.js.map +1 -0
  15. package/lib/cjs/hooks/loadscript.js +44 -0
  16. package/lib/cjs/hooks/loadscript.js.map +1 -0
  17. package/lib/cjs/index.js +33 -0
  18. package/lib/cjs/index.js.map +1 -0
  19. package/lib/cjs/types/barcode.d.js +6 -0
  20. package/lib/cjs/types/barcode.d.js.map +1 -0
  21. package/lib/cjs/types/codeScanner.js +14 -0
  22. package/lib/cjs/types/codeScanner.js.map +1 -0
  23. package/lib/cjs/types/global.d.js +2 -0
  24. package/lib/cjs/types/global.d.js.map +1 -0
  25. package/lib/cjs/utils/animate.js +25 -0
  26. package/lib/cjs/utils/animate.js.map +1 -0
  27. package/lib/cjs/utils/errorDialog.js +13 -0
  28. package/lib/cjs/utils/errorDialog.js.map +1 -0
  29. package/lib/cjs/utils/loadScript.js +15 -0
  30. package/lib/cjs/utils/loadScript.js.map +1 -0
  31. package/lib/cjs/utils/support.js +11 -0
  32. package/lib/cjs/utils/support.js.map +1 -0
  33. package/lib/esm/components/code-scanner/CodeScanner.js +218 -0
  34. package/lib/esm/components/code-scanner/CodeScanner.js.map +1 -0
  35. package/lib/esm/components/code-scanner/CodeScanner.styles.js +27 -0
  36. package/lib/esm/components/code-scanner/CodeScanner.styles.js.map +1 -0
  37. package/lib/esm/components/code-scanner/scanner-toolbar/ScannerToolbar.js +141 -0
  38. package/lib/esm/components/code-scanner/scanner-toolbar/ScannerToolbar.js.map +1 -0
  39. package/lib/esm/components/code-scanner/scanner-toolbar/ScannerToolbar.styles.js +43 -0
  40. package/lib/esm/components/code-scanner/scanner-toolbar/ScannerToolbar.styles.js.map +1 -0
  41. package/lib/esm/constants/codeScanner.js +14 -0
  42. package/lib/esm/constants/codeScanner.js.map +1 -0
  43. package/lib/esm/hooks/codeScanner.js +10 -0
  44. package/lib/esm/hooks/codeScanner.js.map +1 -0
  45. package/lib/esm/hooks/loadscript.js +37 -0
  46. package/lib/esm/hooks/loadscript.js.map +1 -0
  47. package/lib/esm/index.js +3 -0
  48. package/lib/esm/index.js.map +1 -0
  49. package/lib/esm/types/barcode.d.js +4 -0
  50. package/lib/esm/types/barcode.d.js.map +1 -0
  51. package/lib/esm/types/codeScanner.js +8 -0
  52. package/lib/esm/types/codeScanner.js.map +1 -0
  53. package/lib/esm/types/global.d.js +2 -0
  54. package/lib/esm/types/global.d.js.map +1 -0
  55. package/lib/esm/utils/animate.js +18 -0
  56. package/lib/esm/utils/animate.js.map +1 -0
  57. package/lib/esm/utils/errorDialog.js +6 -0
  58. package/lib/esm/utils/errorDialog.js.map +1 -0
  59. package/lib/esm/utils/loadScript.js +8 -0
  60. package/lib/esm/utils/loadScript.js.map +1 -0
  61. package/lib/esm/utils/support.js +3 -0
  62. package/lib/esm/utils/support.js.map +1 -0
  63. package/lib/types/components/code-scanner/CodeScanner.d.ts +54 -0
  64. package/lib/types/components/code-scanner/CodeScanner.styles.d.ts +7 -0
  65. package/lib/types/components/code-scanner/scanner-toolbar/ScannerToolbar.d.ts +45 -0
  66. package/lib/types/components/code-scanner/scanner-toolbar/ScannerToolbar.styles.d.ts +7 -0
  67. package/lib/types/constants/codeScanner.d.ts +3 -0
  68. package/lib/types/hooks/codeScanner.d.ts +2 -0
  69. package/lib/types/hooks/loadscript.d.ts +4 -0
  70. package/lib/types/index.d.ts +2 -0
  71. package/lib/types/types/codeScanner.d.ts +16 -0
  72. package/lib/types/utils/animate.d.ts +1 -0
  73. package/lib/types/utils/errorDialog.d.ts +1 -0
  74. package/lib/types/utils/loadScript.d.ts +1 -0
  75. package/lib/types/utils/support.d.ts +2 -0
  76. package/package.json +87 -0
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = require("react");
8
+ const usePrevious = value => {
9
+ const ref = (0, _react.useRef)();
10
+ (0, _react.useEffect)(() => {
11
+ ref.current = value;
12
+ }, [value]);
13
+ return ref.current;
14
+ };
15
+ var _default = exports.default = usePrevious;
16
+ //# sourceMappingURL=codeScanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeScanner.js","names":["_react","require","usePrevious","value","ref","useRef","useEffect","current","_default","exports","default"],"sources":["../../../src/hooks/codeScanner.ts"],"sourcesContent":["import { useEffect, useRef } from 'react';\n\nconst usePrevious = <T>(value: T): T | undefined => {\n const ref = useRef<T>();\n useEffect(() => {\n ref.current = value;\n }, [value]);\n return ref.current;\n};\n\nexport default usePrevious;\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAEA,MAAMC,WAAW,GAAOC,KAAQ,IAAoB;EAChD,MAAMC,GAAG,GAAG,IAAAC,aAAM,EAAI,CAAC;EACvB,IAAAC,gBAAS,EAAC,MAAM;IACZF,GAAG,CAACG,OAAO,GAAGJ,KAAK;EACvB,CAAC,EAAE,CAACA,KAAK,CAAC,CAAC;EACX,OAAOC,GAAG,CAACG,OAAO;AACtB,CAAC;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEaR,WAAW","ignoreList":[]}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useScannerPolyfill = void 0;
7
+ var _react = require("react");
8
+ var _loadScript = require("../utils/loadScript");
9
+ const VERSION = 1;
10
+ let scannerPolyfillPromise;
11
+ let scannerWasmPromise;
12
+ const loadPolyfillScript = () => {
13
+ if (!scannerPolyfillPromise) {
14
+ scannerPolyfillPromise = (0, _loadScript.loadScript)(`https://api.chayns-static.space/polyfill/CodeScanner/v${VERSION}/barcode-detector-polyfill.js`);
15
+ }
16
+ return scannerPolyfillPromise;
17
+ };
18
+ const loadWasmScript = () => {
19
+ if (!scannerWasmPromise) {
20
+ scannerWasmPromise = (0, _loadScript.loadScript)(`https://api.chayns-static.space/polyfill/CodeScanner/v${VERSION}/zbar-wasm.js`);
21
+ }
22
+ return scannerWasmPromise;
23
+ };
24
+ const useScannerPolyfill = () => {
25
+ const [wasmLoaded, setWasmLoaded] = (0, _react.useState)(false);
26
+ const [polyfillLoaded, setPolyfillLoaded] = (0, _react.useState)(false);
27
+ const loadQrCodeDetector = (0, _react.useCallback)(async () => {
28
+ try {
29
+ await BarcodeDetector.getSupportedFormats();
30
+ } catch {
31
+ await loadWasmScript().then(() => setWasmLoaded(true));
32
+ await loadPolyfillScript().then(() => setPolyfillLoaded(true));
33
+ // @ts-expect-error polyfill is not defined in window
34
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
35
+ window.BarcodeDetector = barcodeDetectorPolyfill.BarcodeDetectorPolyfill;
36
+ }
37
+ }, []);
38
+ return {
39
+ loadQrCodeDetector,
40
+ loaded: polyfillLoaded && wasmLoaded
41
+ };
42
+ };
43
+ exports.useScannerPolyfill = useScannerPolyfill;
44
+ //# sourceMappingURL=loadscript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadscript.js","names":["_react","require","_loadScript","VERSION","scannerPolyfillPromise","scannerWasmPromise","loadPolyfillScript","loadScript","loadWasmScript","useScannerPolyfill","wasmLoaded","setWasmLoaded","useState","polyfillLoaded","setPolyfillLoaded","loadQrCodeDetector","useCallback","BarcodeDetector","getSupportedFormats","then","window","barcodeDetectorPolyfill","BarcodeDetectorPolyfill","loaded","exports"],"sources":["../../../src/hooks/loadscript.ts"],"sourcesContent":["import { useCallback, useState } from 'react';\nimport { loadScript } from '../utils/loadScript';\n\nconst VERSION = 1;\n\nlet scannerPolyfillPromise: Promise<Event | UIEvent> | undefined;\nlet scannerWasmPromise: Promise<Event | UIEvent> | undefined;\n\nconst loadPolyfillScript = () => {\n if (!scannerPolyfillPromise) {\n scannerPolyfillPromise = loadScript(\n `https://api.chayns-static.space/polyfill/CodeScanner/v${VERSION}/barcode-detector-polyfill.js`,\n );\n }\n\n return scannerPolyfillPromise;\n};\n\nconst loadWasmScript = () => {\n if (!scannerWasmPromise) {\n scannerWasmPromise = loadScript(\n `https://api.chayns-static.space/polyfill/CodeScanner/v${VERSION}/zbar-wasm.js`,\n );\n }\n\n return scannerWasmPromise;\n};\n\nexport const useScannerPolyfill = () => {\n const [wasmLoaded, setWasmLoaded] = useState(false);\n const [polyfillLoaded, setPolyfillLoaded] = useState(false);\n\n const loadQrCodeDetector = useCallback(async () => {\n try {\n await BarcodeDetector.getSupportedFormats();\n } catch {\n await loadWasmScript().then(() => setWasmLoaded(true));\n await loadPolyfillScript().then(() => setPolyfillLoaded(true));\n // @ts-expect-error polyfill is not defined in window\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access\n window.BarcodeDetector = barcodeDetectorPolyfill.BarcodeDetectorPolyfill;\n }\n }, []);\n\n return { loadQrCodeDetector, loaded: polyfillLoaded && wasmLoaded };\n};\n"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AAEA,MAAME,OAAO,GAAG,CAAC;AAEjB,IAAIC,sBAA4D;AAChE,IAAIC,kBAAwD;AAE5D,MAAMC,kBAAkB,GAAGA,CAAA,KAAM;EAC7B,IAAI,CAACF,sBAAsB,EAAE;IACzBA,sBAAsB,GAAG,IAAAG,sBAAU,EAC/B,yDAAyDJ,OAAO,+BACpE,CAAC;EACL;EAEA,OAAOC,sBAAsB;AACjC,CAAC;AAED,MAAMI,cAAc,GAAGA,CAAA,KAAM;EACzB,IAAI,CAACH,kBAAkB,EAAE;IACrBA,kBAAkB,GAAG,IAAAE,sBAAU,EAC3B,yDAAyDJ,OAAO,eACpE,CAAC;EACL;EAEA,OAAOE,kBAAkB;AAC7B,CAAC;AAEM,MAAMI,kBAAkB,GAAGA,CAAA,KAAM;EACpC,MAAM,CAACC,UAAU,EAAEC,aAAa,CAAC,GAAG,IAAAC,eAAQ,EAAC,KAAK,CAAC;EACnD,MAAM,CAACC,cAAc,EAAEC,iBAAiB,CAAC,GAAG,IAAAF,eAAQ,EAAC,KAAK,CAAC;EAE3D,MAAMG,kBAAkB,GAAG,IAAAC,kBAAW,EAAC,YAAY;IAC/C,IAAI;MACA,MAAMC,eAAe,CAACC,mBAAmB,CAAC,CAAC;IAC/C,CAAC,CAAC,MAAM;MACJ,MAAMV,cAAc,CAAC,CAAC,CAACW,IAAI,CAAC,MAAMR,aAAa,CAAC,IAAI,CAAC,CAAC;MACtD,MAAML,kBAAkB,CAAC,CAAC,CAACa,IAAI,CAAC,MAAML,iBAAiB,CAAC,IAAI,CAAC,CAAC;MAC9D;MACA;MACAM,MAAM,CAACH,eAAe,GAAGI,uBAAuB,CAACC,uBAAuB;IAC5E;EACJ,CAAC,EAAE,EAAE,CAAC;EAEN,OAAO;IAAEP,kBAAkB;IAAEQ,MAAM,EAAEV,cAAc,IAAIH;EAAW,CAAC;AACvE,CAAC;AAACc,OAAA,CAAAf,kBAAA,GAAAA,kBAAA","ignoreList":[]}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "ALL_FORMATS", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _codeScanner.ALL_FORMATS;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "CodeScanner", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _CodeScanner.default;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "DEFAULT_TRACK_CONSTRAINTS", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _codeScanner.DEFAULT_TRACK_CONSTRAINTS;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "DEFAULT_VIDEO_CONSTRAINTS", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _codeScanner.DEFAULT_VIDEO_CONSTRAINTS;
28
+ }
29
+ });
30
+ var _CodeScanner = _interopRequireDefault(require("./components/code-scanner/CodeScanner"));
31
+ var _codeScanner = require("./constants/codeScanner");
32
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["_CodeScanner","_interopRequireDefault","require","_codeScanner","e","__esModule","default"],"sources":["../../src/index.ts"],"sourcesContent":["export { default as CodeScanner } from './components/code-scanner/CodeScanner';\nexport {\n ALL_FORMATS,\n DEFAULT_TRACK_CONSTRAINTS,\n DEFAULT_VIDEO_CONSTRAINTS,\n} from './constants/codeScanner';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAIiC,SAAAD,uBAAAG,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ //# sourceMappingURL=barcode.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"barcode.d.js","names":[],"sources":["../../../src/types/barcode.d.ts"],"sourcesContent":["// This is necessary because Typescript refuses to import the file unless it has\n// an export, apparently. 🥲\nexport {};\n\ndeclare global {\n /**\n * The possible types of barcode format that can be detected using the\n * Barcode Detection API. This list may change in the future.\n * Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API\n */\n type BarcodeFormat =\n | 'code_128'\n | 'code_39'\n | 'code_93'\n | 'codabar'\n | 'ean_13'\n | 'ean_8'\n | 'itf'\n | 'qr_code'\n | 'upc_a'\n | 'upc_e'\n | 'unknown';\n\n /**\n * The return type of the Barcode Detect API `detect` function that\n * describes a barcode that has been recognized by the API.\n */\n interface DetectedBarcode {\n /**\n * A DOMRectReadOnly, which returns the dimensions of a rectangle\n * representing the extent of a detected barcode, aligned with the\n * image\n */\n boundingBox: DOMRectReadOnly;\n /**\n * The x and y co-ordinates of the four corner points of the detected\n * barcode relative to the image, starting with the top left and working\n * clockwise. This may not be square due to perspective distortions\n * within the image.\n */\n cornerPoints: {\n x: number;\n y: number;\n }[];\n /**\n * The detected barcode format\n */\n format: BarcodeFormat;\n\n /**\n * A string decoded from the barcode data\n */\n rawValue: string;\n }\n\n /**\n * Options for describing how a BarcodeDetector should be initialised\n */\n interface BarcodeDetectorOptions {\n /**\n * Which formats the barcode detector should detect\n */\n formats: BarcodeFormat[];\n }\n\n /**\n * The BarcodeDetector interface of the Barcode Detection API allows\n * detection of linear and two-dimensional barcodes in images.\n */\n class BarcodeDetector {\n /**\n * Initialize a Barcode Detector instance\n */\n constructor(options?: BarcodeDetectorOptions);\n\n /**\n * Retrieve the formats that are supported by the detector\n */\n static getSupportedFormats(): Promise<BarcodeFormat[]>;\n\n /**\n * Attempt to detect barcodes from an image source\n */\n public detect(source: ImageBitmapSource): Promise<DetectedBarcode[]>;\n }\n}\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ScannerErrorType = void 0;
7
+ let ScannerErrorType = exports.ScannerErrorType = /*#__PURE__*/function (ScannerErrorType) {
8
+ ScannerErrorType[ScannerErrorType["NO_CAMERA_ACCESS"] = 0] = "NO_CAMERA_ACCESS";
9
+ ScannerErrorType[ScannerErrorType["CAMERA_ALREADY_IN_USE"] = 1] = "CAMERA_ALREADY_IN_USE";
10
+ ScannerErrorType[ScannerErrorType["DEVICE_NOT_FOUND"] = 2] = "DEVICE_NOT_FOUND";
11
+ ScannerErrorType[ScannerErrorType["UNKNOWN"] = 3] = "UNKNOWN";
12
+ return ScannerErrorType;
13
+ }({});
14
+ //# sourceMappingURL=codeScanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codeScanner.js","names":["ScannerErrorType","exports"],"sources":["../../../src/types/codeScanner.ts"],"sourcesContent":["export type CodeReaderOnScanCallback = (code: {\n format: BarcodeFormat;\n value: string;\n}) => void | Promise<void>;\n\nexport enum ScannerErrorType {\n NO_CAMERA_ACCESS,\n CAMERA_ALREADY_IN_USE,\n DEVICE_NOT_FOUND,\n UNKNOWN,\n}\n\nexport interface ScannerErrorMessages {\n noPermission: string;\n alreadyInUse: string;\n cameraNotAvailable: string;\n noCodeFound: string;\n}\n"],"mappings":";;;;;;IAKYA,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,0BAAhBA,gBAAgB;EAAhBA,gBAAgB,CAAhBA,gBAAgB;EAAhBA,gBAAgB,CAAhBA,gBAAgB;EAAhBA,gBAAgB,CAAhBA,gBAAgB;EAAhBA,gBAAgB,CAAhBA,gBAAgB;EAAA,OAAhBA,gBAAgB;AAAA","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+
2
+ //# sourceMappingURL=global.d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global.d.js","names":[],"sources":["../../../src/types/global.d.ts"],"sourcesContent":["interface Window {\n BarcodeDetector: BarcodeDetector;\n}\n\ninterface MediaTrackCapabilities {\n zoom: {\n min: number;\n max: number;\n step?: number;\n };\n}\n\ninterface MediaTrackConstraintSet {\n zoom?: number;\n torch?: boolean;\n}\n\ninterface MediaTrackSettings {\n zoom: number;\n}\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.animateNumericValue = void 0;
7
+ const animateNumericValue = (start, end, duration, callback) => {
8
+ if (start === end) {
9
+ callback(end);
10
+ return;
11
+ }
12
+ const startTime = performance.now();
13
+ const animate = () => {
14
+ const currentTime = performance.now();
15
+ const progress = Math.min((currentTime - startTime) / duration, 1);
16
+ const value = start + (end - start) * progress;
17
+ callback(value);
18
+ if (progress < 1) {
19
+ requestAnimationFrame(animate);
20
+ }
21
+ };
22
+ animate();
23
+ };
24
+ exports.animateNumericValue = animateNumericValue;
25
+ //# sourceMappingURL=animate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animate.js","names":["animateNumericValue","start","end","duration","callback","startTime","performance","now","animate","currentTime","progress","Math","min","value","requestAnimationFrame","exports"],"sources":["../../../src/utils/animate.ts"],"sourcesContent":["export const animateNumericValue = (\n start: number,\n end: number,\n duration: number,\n callback: (value: number) => void,\n) => {\n if (start === end) {\n callback(end);\n return;\n }\n\n const startTime = performance.now();\n const animate = () => {\n const currentTime = performance.now();\n const progress = Math.min((currentTime - startTime) / duration, 1);\n const value = start + (end - start) * progress;\n callback(value);\n if (progress < 1) {\n requestAnimationFrame(animate);\n }\n };\n animate();\n};\n"],"mappings":";;;;;;AAAO,MAAMA,mBAAmB,GAAGA,CAC/BC,KAAa,EACbC,GAAW,EACXC,QAAgB,EAChBC,QAAiC,KAChC;EACD,IAAIH,KAAK,KAAKC,GAAG,EAAE;IACfE,QAAQ,CAACF,GAAG,CAAC;IACb;EACJ;EAEA,MAAMG,SAAS,GAAGC,WAAW,CAACC,GAAG,CAAC,CAAC;EACnC,MAAMC,OAAO,GAAGA,CAAA,KAAM;IAClB,MAAMC,WAAW,GAAGH,WAAW,CAACC,GAAG,CAAC,CAAC;IACrC,MAAMG,QAAQ,GAAGC,IAAI,CAACC,GAAG,CAAC,CAACH,WAAW,GAAGJ,SAAS,IAAIF,QAAQ,EAAE,CAAC,CAAC;IAClE,MAAMU,KAAK,GAAGZ,KAAK,GAAG,CAACC,GAAG,GAAGD,KAAK,IAAIS,QAAQ;IAC9CN,QAAQ,CAACS,KAAK,CAAC;IACf,IAAIH,QAAQ,GAAG,CAAC,EAAE;MACdI,qBAAqB,CAACN,OAAO,CAAC;IAClC;EACJ,CAAC;EACDA,OAAO,CAAC,CAAC;AACb,CAAC;AAACO,OAAA,CAAAf,mBAAA,GAAAA,mBAAA","ignoreList":[]}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createErrorAlertDialog = void 0;
7
+ var _chaynsApi = require("chayns-api");
8
+ const createErrorAlertDialog = text => (0, _chaynsApi.createDialog)({
9
+ type: _chaynsApi.DialogType.ALERT,
10
+ text: `<p style="text-align: center;">%%DialogErrorIcon%%</p><p>${text}</p>`
11
+ });
12
+ exports.createErrorAlertDialog = createErrorAlertDialog;
13
+ //# sourceMappingURL=errorDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errorDialog.js","names":["_chaynsApi","require","createErrorAlertDialog","text","createDialog","type","DialogType","ALERT","exports"],"sources":["../../../src/utils/errorDialog.ts"],"sourcesContent":["import { createDialog, DialogType } from 'chayns-api';\n\nexport const createErrorAlertDialog = (text: string) =>\n createDialog({\n type: DialogType.ALERT,\n text: `<p style=\"text-align: center;\">%%DialogErrorIcon%%</p><p>${text}</p>`,\n });\n"],"mappings":";;;;;;AAAA,IAAAA,UAAA,GAAAC,OAAA;AAEO,MAAMC,sBAAsB,GAAIC,IAAY,IAC/C,IAAAC,uBAAY,EAAC;EACTC,IAAI,EAAEC,qBAAU,CAACC,KAAK;EACtBJ,IAAI,EAAE,4DAA4DA,IAAI;AAC1E,CAAC,CAAC;AAACK,OAAA,CAAAN,sBAAA,GAAAA,sBAAA","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.loadScript = void 0;
7
+ const loadScript = src => new Promise((resolve, reject) => {
8
+ const script = document.createElement('script');
9
+ script.src = src;
10
+ script.onload = resolve;
11
+ script.onabort = reject;
12
+ document.head.appendChild(script);
13
+ });
14
+ exports.loadScript = loadScript;
15
+ //# sourceMappingURL=loadScript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadScript.js","names":["loadScript","src","Promise","resolve","reject","script","document","createElement","onload","onabort","head","appendChild","exports"],"sources":["../../../src/utils/loadScript.ts"],"sourcesContent":["export const loadScript = (src: string): Promise<Event | UIEvent> =>\n new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = src;\n script.onload = resolve;\n script.onabort = reject;\n document.head.appendChild(script);\n });\n"],"mappings":";;;;;;AAAO,MAAMA,UAAU,GAAIC,GAAW,IAClC,IAAIC,OAAO,CAAC,CAACC,OAAO,EAAEC,MAAM,KAAK;EAC7B,MAAMC,MAAM,GAAGC,QAAQ,CAACC,aAAa,CAAC,QAAQ,CAAC;EAC/CF,MAAM,CAACJ,GAAG,GAAGA,GAAG;EAChBI,MAAM,CAACG,MAAM,GAAGL,OAAO;EACvBE,MAAM,CAACI,OAAO,GAAGL,MAAM;EACvBE,QAAQ,CAACI,IAAI,CAACC,WAAW,CAACN,MAAM,CAAC;AACrC,CAAC,CAAC;AAACO,OAAA,CAAAZ,UAAA,GAAAA,UAAA","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.hasBrowserSupport = exports.checkTrackSupport = void 0;
7
+ const hasBrowserSupport = constraint => constraint in navigator.mediaDevices.getSupportedConstraints();
8
+ exports.hasBrowserSupport = hasBrowserSupport;
9
+ const checkTrackSupport = (track, capability) => hasBrowserSupport(capability) && capability in track.getCapabilities();
10
+ exports.checkTrackSupport = checkTrackSupport;
11
+ //# sourceMappingURL=support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support.js","names":["hasBrowserSupport","constraint","navigator","mediaDevices","getSupportedConstraints","exports","checkTrackSupport","track","capability","getCapabilities"],"sources":["../../../src/utils/support.ts"],"sourcesContent":["export const hasBrowserSupport = (constraint: string): boolean =>\n constraint in navigator.mediaDevices.getSupportedConstraints();\n\nexport const checkTrackSupport = (track: MediaStreamTrack, capability: string): boolean =>\n hasBrowserSupport(capability) && capability in track.getCapabilities();\n"],"mappings":";;;;;;AAAO,MAAMA,iBAAiB,GAAIC,UAAkB,IAChDA,UAAU,IAAIC,SAAS,CAACC,YAAY,CAACC,uBAAuB,CAAC,CAAC;AAACC,OAAA,CAAAL,iBAAA,GAAAA,iBAAA;AAE5D,MAAMM,iBAAiB,GAAGA,CAACC,KAAuB,EAAEC,UAAkB,KACzER,iBAAiB,CAACQ,UAAU,CAAC,IAAIA,UAAU,IAAID,KAAK,CAACE,eAAe,CAAC,CAAC;AAACJ,OAAA,CAAAC,iBAAA,GAAAA,iBAAA","ignoreList":[]}
@@ -0,0 +1,218 @@
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { addVisibilityChangeListener, removeVisibilityChangeListener } from 'chayns-api';
3
+ import { Icon, SmallWaitCursor } from '@chayns-components/core';
4
+ import { StyledCodeScanner, StyledCodeScannerPreview, StyledCodeScannerTextWrapper } from './CodeScanner.styles';
5
+ import { ScannerErrorType } from '../../types/codeScanner';
6
+ import { ALL_FORMATS, DEFAULT_TRACK_CONSTRAINTS, DEFAULT_VIDEO_CONSTRAINTS } from '../../constants/codeScanner';
7
+ import { checkTrackSupport } from '../../utils/support';
8
+ import { createErrorAlertDialog } from '../../utils/errorDialog';
9
+ import ScannerToolbar from './scanner-toolbar/ScannerToolbar';
10
+ import { useScannerPolyfill } from '../../hooks/loadscript';
11
+ const CodeScanner = ({
12
+ shouldTriggerForSameCode = false,
13
+ onScan,
14
+ allowedFormats = ALL_FORMATS,
15
+ trackConstraints = DEFAULT_TRACK_CONSTRAINTS,
16
+ videoConstraints = DEFAULT_VIDEO_CONSTRAINTS,
17
+ minZoom = 2,
18
+ maxZoom = 10,
19
+ isFileSelectDisabled = false,
20
+ isTorchDisabled = false,
21
+ isZoomDisabled = false,
22
+ scanInterval = 250,
23
+ errorMessages
24
+ }) => {
25
+ const [isPolyfillLoaded, setIsPolyfillLoaded] = useState(false);
26
+ const [videoRef, setVideoRef] = useState(null);
27
+ const [barcodeDetector, setBarcodeDetector] = useState();
28
+ const [stream, setStream] = useState();
29
+ const [scannerError, setScannerError] = useState(undefined);
30
+ const [isScanningFile, setIsScanningFile] = useState(false);
31
+ const [isHandlingCode, setIsHandlingCode] = useState(false);
32
+ const lastCode = useRef();
33
+ const handleStopRef = useRef();
34
+ const {
35
+ loadQrCodeDetector
36
+ } = useScannerPolyfill();
37
+ const errorText = useMemo(() => {
38
+ if (typeof scannerError === 'undefined') {
39
+ return undefined;
40
+ }
41
+ switch (scannerError) {
42
+ case ScannerErrorType.NO_CAMERA_ACCESS:
43
+ return errorMessages.noPermission;
44
+ case ScannerErrorType.CAMERA_ALREADY_IN_USE:
45
+ return errorMessages.alreadyInUse;
46
+ default:
47
+ return errorMessages.cameraNotAvailable;
48
+ }
49
+ }, [errorMessages, scannerError]);
50
+ const handleScan = useCallback(code => {
51
+ if (!onScan) return;
52
+ const result = onScan(code);
53
+ if (result instanceof Promise) {
54
+ setIsHandlingCode(true);
55
+ void result.finally(() => setIsHandlingCode(false));
56
+ }
57
+ }, [onScan]);
58
+ const handleScanResult = useCallback(result => {
59
+ if (!result.length) return;
60
+ const code = result[0];
61
+ if (!code) {
62
+ return;
63
+ }
64
+ if (allowedFormats && !allowedFormats.includes(code.format)) {
65
+ return;
66
+ }
67
+ if (shouldTriggerForSameCode) {
68
+ handleScan({
69
+ format: code.format,
70
+ value: code.rawValue
71
+ });
72
+ return;
73
+ }
74
+ if (lastCode.current && code.rawValue === lastCode.current) {
75
+ return;
76
+ }
77
+ lastCode.current = code.rawValue;
78
+ handleScan({
79
+ format: code.format,
80
+ value: code.rawValue
81
+ });
82
+ }, [handleScan, shouldTriggerForSameCode, allowedFormats]);
83
+ const handleVideoInitialization = useCallback(async () => {
84
+ if (!navigator.mediaDevices.getUserMedia || !videoRef || !isPolyfillLoaded) return;
85
+ let res;
86
+ try {
87
+ res = await navigator.mediaDevices.getUserMedia({
88
+ video: videoConstraints
89
+ });
90
+ } catch (e) {
91
+ const error = e;
92
+ if (error.name === 'NotAllowedError') {
93
+ setScannerError(ScannerErrorType.NO_CAMERA_ACCESS);
94
+ } else if (error.name === 'NotReadableError') {
95
+ setScannerError(ScannerErrorType.CAMERA_ALREADY_IN_USE);
96
+ } else if (error.name === 'NotFoundError') {
97
+ setScannerError(ScannerErrorType.DEVICE_NOT_FOUND);
98
+ } else {
99
+ setScannerError(ScannerErrorType.UNKNOWN);
100
+ console.warn(e);
101
+ }
102
+ }
103
+ if (res) {
104
+ res.getVideoTracks().forEach(elem => {
105
+ const constraints = {
106
+ ...trackConstraints,
107
+ advanced: trackConstraints.advanced?.map(a => ({
108
+ ...a
109
+ })) || []
110
+ };
111
+ if (checkTrackSupport(elem, 'zoom')) {
112
+ constraints.advanced.push({
113
+ zoom: minZoom
114
+ });
115
+ }
116
+ void elem.applyConstraints(constraints);
117
+ });
118
+ setStream(res);
119
+ videoRef.srcObject = res;
120
+ await videoRef.play();
121
+ }
122
+ const codeDetector = new BarcodeDetector(allowedFormats ? {
123
+ formats: allowedFormats
124
+ } : undefined);
125
+ setBarcodeDetector(codeDetector);
126
+ }, [isPolyfillLoaded, minZoom, trackConstraints, allowedFormats, videoConstraints, videoRef]);
127
+ const handleStopCameraAccess = useCallback(() => {
128
+ if (videoRef) {
129
+ videoRef.pause();
130
+ }
131
+ if (barcodeDetector) {
132
+ setBarcodeDetector(undefined);
133
+ }
134
+ if (stream) {
135
+ stream.getTracks().forEach(track => track.stop());
136
+ setStream(undefined);
137
+ }
138
+ }, [barcodeDetector, stream, videoRef]);
139
+
140
+ // Load BarCodeDetector
141
+ useEffect(() => {
142
+ void loadQrCodeDetector().then(() => {
143
+ setIsPolyfillLoaded(true);
144
+ });
145
+ return () => {
146
+ if (handleStopRef.current) handleStopRef.current();
147
+ };
148
+ }, [loadQrCodeDetector]);
149
+ useEffect(() => {
150
+ handleStopRef.current = handleStopCameraAccess;
151
+ }, [handleStopCameraAccess]);
152
+ useEffect(() => {
153
+ const idPromise = addVisibilityChangeListener(({
154
+ isVisible
155
+ }) => {
156
+ if (!isVisible) {
157
+ handleStopCameraAccess();
158
+ } else {
159
+ void handleVideoInitialization();
160
+ }
161
+ });
162
+ return () => {
163
+ void idPromise.then(id => {
164
+ void removeVisibilityChangeListener(id);
165
+ });
166
+ };
167
+ }, [handleStopCameraAccess, handleVideoInitialization]);
168
+ useEffect(() => {
169
+ if (!barcodeDetector || !videoRef) return undefined;
170
+ if (!isScanningFile && !isHandlingCode) {
171
+ const interval = setInterval(() => {
172
+ void barcodeDetector.detect(videoRef).then(handleScanResult);
173
+ }, scanInterval);
174
+ return () => clearInterval(interval);
175
+ }
176
+ return undefined;
177
+ }, [barcodeDetector, handleScanResult, isHandlingCode, isScanningFile, videoRef, scanInterval]);
178
+ useEffect(() => {
179
+ if (!navigator.mediaDevices.enumerateDevices || !navigator.mediaDevices.getUserMedia || !videoRef || !isPolyfillLoaded) {
180
+ return;
181
+ }
182
+ void handleVideoInitialization();
183
+ }, [handleVideoInitialization, isPolyfillLoaded, videoRef]);
184
+ return /*#__PURE__*/React.createElement(StyledCodeScanner, null, (!barcodeDetector || errorText) && /*#__PURE__*/React.createElement(StyledCodeScannerTextWrapper, null, !barcodeDetector && !errorText && /*#__PURE__*/React.createElement(SmallWaitCursor, null), errorText && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Icon, {
185
+ icons: ['fa fa-webcam-slash'],
186
+ size: 40,
187
+ color: "rgb(128, 128, 128)"
188
+ }), errorText)), /*#__PURE__*/React.createElement(StyledCodeScannerPreview, {
189
+ ref: setVideoRef,
190
+ autoPlay: true,
191
+ playsInline: true,
192
+ height: "100%",
193
+ width: "100%",
194
+ $isVisible: !!barcodeDetector && !errorText
195
+ }), !!barcodeDetector && /*#__PURE__*/React.createElement(ScannerToolbar, {
196
+ videoConstraints: videoConstraints,
197
+ onFileSelect: data => {
198
+ setIsScanningFile(true);
199
+ void barcodeDetector.detect(data).then(value => {
200
+ if (value.length) {
201
+ handleScanResult(value);
202
+ } else {
203
+ void createErrorAlertDialog(errorMessages.noCodeFound).open();
204
+ }
205
+ }).finally(() => setIsScanningFile(false));
206
+ },
207
+ isScanningFile: isScanningFile,
208
+ hasScannerError: typeof scannerError !== 'undefined',
209
+ stream: stream,
210
+ minZoom: minZoom,
211
+ maxZoom: maxZoom,
212
+ isZoomDisabled: isZoomDisabled,
213
+ isTorchDisabled: isTorchDisabled,
214
+ isFileSelectDisabled: isFileSelectDisabled
215
+ }));
216
+ };
217
+ export default CodeScanner;
218
+ //# sourceMappingURL=CodeScanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeScanner.js","names":["React","useCallback","useEffect","useMemo","useRef","useState","addVisibilityChangeListener","removeVisibilityChangeListener","Icon","SmallWaitCursor","StyledCodeScanner","StyledCodeScannerPreview","StyledCodeScannerTextWrapper","ScannerErrorType","ALL_FORMATS","DEFAULT_TRACK_CONSTRAINTS","DEFAULT_VIDEO_CONSTRAINTS","checkTrackSupport","createErrorAlertDialog","ScannerToolbar","useScannerPolyfill","CodeScanner","shouldTriggerForSameCode","onScan","allowedFormats","trackConstraints","videoConstraints","minZoom","maxZoom","isFileSelectDisabled","isTorchDisabled","isZoomDisabled","scanInterval","errorMessages","isPolyfillLoaded","setIsPolyfillLoaded","videoRef","setVideoRef","barcodeDetector","setBarcodeDetector","stream","setStream","scannerError","setScannerError","undefined","isScanningFile","setIsScanningFile","isHandlingCode","setIsHandlingCode","lastCode","handleStopRef","loadQrCodeDetector","errorText","NO_CAMERA_ACCESS","noPermission","CAMERA_ALREADY_IN_USE","alreadyInUse","cameraNotAvailable","handleScan","code","result","Promise","finally","handleScanResult","length","includes","format","value","rawValue","current","handleVideoInitialization","navigator","mediaDevices","getUserMedia","res","video","e","error","name","DEVICE_NOT_FOUND","UNKNOWN","console","warn","getVideoTracks","forEach","elem","constraints","advanced","map","a","push","zoom","applyConstraints","srcObject","play","codeDetector","BarcodeDetector","formats","handleStopCameraAccess","pause","getTracks","track","stop","then","idPromise","isVisible","id","interval","setInterval","detect","clearInterval","enumerateDevices","createElement","Fragment","icons","size","color","ref","autoPlay","playsInline","height","width","$isVisible","onFileSelect","data","noCodeFound","open","hasScannerError"],"sources":["../../../../src/components/code-scanner/CodeScanner.tsx"],"sourcesContent":["import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { addVisibilityChangeListener, removeVisibilityChangeListener } from 'chayns-api';\nimport { Icon, SmallWaitCursor } from '@chayns-components/core';\nimport {\n StyledCodeScanner,\n StyledCodeScannerPreview,\n StyledCodeScannerTextWrapper,\n} from './CodeScanner.styles';\nimport {\n CodeReaderOnScanCallback,\n ScannerErrorMessages,\n ScannerErrorType,\n} from '../../types/codeScanner';\nimport {\n ALL_FORMATS,\n DEFAULT_TRACK_CONSTRAINTS,\n DEFAULT_VIDEO_CONSTRAINTS,\n} from '../../constants/codeScanner';\nimport { checkTrackSupport } from '../../utils/support';\nimport { createErrorAlertDialog } from '../../utils/errorDialog';\nimport ScannerToolbar from './scanner-toolbar/ScannerToolbar';\nimport { useScannerPolyfill } from '../../hooks/loadscript';\n\ntype CodeScannerProps = {\n /**\n * Defines which barcode formats are allowed to be detected.\n */\n allowedFormats?: Array<BarcodeFormat>;\n /**\n * The interval of the scans.\n */\n scanInterval?: number;\n /**\n * Custom error messages for various scanner states or failures.\n */\n errorMessages: ScannerErrorMessages;\n /**\n * Disables the file select feature if set to true.\n */\n isFileSelectDisabled?: boolean;\n /**\n * Disables the torch (flashlight) feature if set to true.\n */\n isTorchDisabled?: boolean;\n /**\n * Disables the zoom control if set to true.\n */\n isZoomDisabled?: boolean;\n /**\n * Maximum allowed zoom level for the camera.\n */\n maxZoom?: number;\n /**\n * Minimum allowed zoom level for the camera.\n */\n minZoom?: number;\n /**\n * Callback function triggered when a code is successfully scanned.\n */\n onScan?: CodeReaderOnScanCallback;\n /**\n * If true, allows scanning the same code multiple times in a row.\n */\n shouldTriggerForSameCode?: boolean;\n /**\n * Custom media track constraints for controlling the video input.\n */\n trackConstraints?: MediaTrackConstraints;\n /**\n * Additional video constraints for the camera feed.\n */\n videoConstraints?: MediaTrackConstraints;\n};\n\nconst CodeScanner: FC<CodeScannerProps> = ({\n shouldTriggerForSameCode = false,\n onScan,\n allowedFormats = ALL_FORMATS,\n trackConstraints = DEFAULT_TRACK_CONSTRAINTS,\n videoConstraints = DEFAULT_VIDEO_CONSTRAINTS,\n minZoom = 2,\n maxZoom = 10,\n isFileSelectDisabled = false,\n isTorchDisabled = false,\n isZoomDisabled = false,\n scanInterval = 250,\n errorMessages,\n}) => {\n const [isPolyfillLoaded, setIsPolyfillLoaded] = useState(false);\n const [videoRef, setVideoRef] = useState<HTMLVideoElement | null>(null);\n const [barcodeDetector, setBarcodeDetector] = useState<BarcodeDetector>();\n const [stream, setStream] = useState<MediaStream>();\n const [scannerError, setScannerError] = useState<ScannerErrorType | undefined>(undefined);\n const [isScanningFile, setIsScanningFile] = useState(false);\n const [isHandlingCode, setIsHandlingCode] = useState(false);\n const lastCode = useRef<string>();\n const handleStopRef = useRef<() => void>();\n\n const { loadQrCodeDetector } = useScannerPolyfill();\n\n const errorText = useMemo(() => {\n if (typeof scannerError === 'undefined') {\n return undefined;\n }\n\n switch (scannerError) {\n case ScannerErrorType.NO_CAMERA_ACCESS:\n return errorMessages.noPermission;\n case ScannerErrorType.CAMERA_ALREADY_IN_USE:\n return errorMessages.alreadyInUse;\n default:\n return errorMessages.cameraNotAvailable;\n }\n }, [errorMessages, scannerError]);\n\n const handleScan = useCallback(\n (code: { format: BarcodeFormat; value: string }) => {\n if (!onScan) return;\n const result = onScan(code);\n if (result instanceof Promise) {\n setIsHandlingCode(true);\n void result.finally(() => setIsHandlingCode(false));\n }\n },\n [onScan],\n );\n\n const handleScanResult = useCallback(\n (result: Array<DetectedBarcode>) => {\n if (!result.length) return;\n\n const code = result[0];\n\n if (!code) {\n return;\n }\n\n if (allowedFormats && !allowedFormats.includes(code.format)) {\n return;\n }\n\n if (shouldTriggerForSameCode) {\n handleScan({ format: code.format, value: code.rawValue });\n return;\n }\n\n if (lastCode.current && code.rawValue === lastCode.current) {\n return;\n }\n\n lastCode.current = code.rawValue;\n handleScan({ format: code.format, value: code.rawValue });\n },\n [handleScan, shouldTriggerForSameCode, allowedFormats],\n );\n\n const handleVideoInitialization = useCallback(async () => {\n if (!navigator.mediaDevices.getUserMedia || !videoRef || !isPolyfillLoaded) return;\n\n let res: MediaStream | undefined;\n\n try {\n res = await navigator.mediaDevices.getUserMedia({\n video: videoConstraints,\n });\n } catch (e) {\n const error = e as Error;\n\n if (error.name === 'NotAllowedError') {\n setScannerError(ScannerErrorType.NO_CAMERA_ACCESS);\n } else if (error.name === 'NotReadableError') {\n setScannerError(ScannerErrorType.CAMERA_ALREADY_IN_USE);\n } else if (error.name === 'NotFoundError') {\n setScannerError(ScannerErrorType.DEVICE_NOT_FOUND);\n } else {\n setScannerError(ScannerErrorType.UNKNOWN);\n console.warn(e);\n }\n }\n\n if (res) {\n res.getVideoTracks().forEach((elem) => {\n const constraints = {\n ...trackConstraints,\n advanced: trackConstraints.advanced?.map((a) => ({ ...a })) || [],\n };\n\n if (checkTrackSupport(elem, 'zoom')) {\n constraints.advanced.push({ zoom: minZoom });\n }\n\n void elem.applyConstraints(constraints);\n });\n\n setStream(res);\n\n videoRef.srcObject = res;\n\n await videoRef.play();\n }\n\n const codeDetector = new BarcodeDetector(\n allowedFormats ? { formats: allowedFormats } : undefined,\n );\n\n setBarcodeDetector(codeDetector);\n }, [isPolyfillLoaded, minZoom, trackConstraints, allowedFormats, videoConstraints, videoRef]);\n\n const handleStopCameraAccess = useCallback(() => {\n if (videoRef) {\n videoRef.pause();\n }\n\n if (barcodeDetector) {\n setBarcodeDetector(undefined);\n }\n\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n setStream(undefined);\n }\n }, [barcodeDetector, stream, videoRef]);\n\n // Load BarCodeDetector\n useEffect(() => {\n void loadQrCodeDetector().then(() => {\n setIsPolyfillLoaded(true);\n });\n\n return () => {\n if (handleStopRef.current) handleStopRef.current();\n };\n }, [loadQrCodeDetector]);\n\n useEffect(() => {\n handleStopRef.current = handleStopCameraAccess;\n }, [handleStopCameraAccess]);\n\n useEffect(() => {\n const idPromise = addVisibilityChangeListener(({ isVisible }) => {\n if (!isVisible) {\n handleStopCameraAccess();\n } else {\n void handleVideoInitialization();\n }\n });\n\n return () => {\n void idPromise.then((id) => {\n void removeVisibilityChangeListener(id);\n });\n };\n }, [handleStopCameraAccess, handleVideoInitialization]);\n\n useEffect(() => {\n if (!barcodeDetector || !videoRef) return undefined;\n\n if (!isScanningFile && !isHandlingCode) {\n const interval = setInterval(() => {\n void barcodeDetector.detect(videoRef).then(handleScanResult);\n }, scanInterval);\n\n return () => clearInterval(interval);\n }\n\n return undefined;\n }, [barcodeDetector, handleScanResult, isHandlingCode, isScanningFile, videoRef, scanInterval]);\n\n useEffect(() => {\n if (\n !navigator.mediaDevices.enumerateDevices ||\n !navigator.mediaDevices.getUserMedia ||\n !videoRef ||\n !isPolyfillLoaded\n ) {\n return;\n }\n\n void handleVideoInitialization();\n }, [handleVideoInitialization, isPolyfillLoaded, videoRef]);\n\n return (\n <StyledCodeScanner>\n {(!barcodeDetector || errorText) && (\n <StyledCodeScannerTextWrapper>\n {!barcodeDetector && !errorText && <SmallWaitCursor />}\n {errorText && (\n <>\n <Icon\n icons={['fa fa-webcam-slash']}\n size={40}\n color=\"rgb(128, 128, 128)\"\n />\n {errorText}\n </>\n )}\n </StyledCodeScannerTextWrapper>\n )}\n <StyledCodeScannerPreview\n ref={setVideoRef}\n autoPlay\n playsInline\n height=\"100%\"\n width=\"100%\"\n $isVisible={!!barcodeDetector && !errorText}\n />\n {!!barcodeDetector && (\n <ScannerToolbar\n videoConstraints={videoConstraints}\n onFileSelect={(data) => {\n setIsScanningFile(true);\n\n void barcodeDetector\n .detect(data)\n .then((value) => {\n if (value.length) {\n handleScanResult(value);\n } else {\n void createErrorAlertDialog(errorMessages.noCodeFound).open();\n }\n })\n .finally(() => setIsScanningFile(false));\n }}\n isScanningFile={isScanningFile}\n hasScannerError={typeof scannerError !== 'undefined'}\n stream={stream}\n minZoom={minZoom}\n maxZoom={maxZoom}\n isZoomDisabled={isZoomDisabled}\n isTorchDisabled={isTorchDisabled}\n isFileSelectDisabled={isFileSelectDisabled}\n />\n )}\n </StyledCodeScanner>\n );\n};\n\nexport default CodeScanner;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,27 @@
1
+ import styled from 'styled-components';
2
+ export const StyledCodeScanner = styled.div`
3
+ display: flex;
4
+ justify-content: center;
5
+ align-items: center;
6
+ `;
7
+ export const StyledCodeScannerTextWrapper = styled.div`
8
+ width: 640px;
9
+ display: flex;
10
+ justify-content: center;
11
+ align-items: center;
12
+ aspect-ratio: 3 / 2;
13
+ flex-direction: column;
14
+ text-align: center;
15
+ padding: 20px;
16
+ `;
17
+ export const StyledCodeScannerPreview = styled.video`
18
+ width: 100%;
19
+ height: 100%;
20
+
21
+ ${({
22
+ $isVisible
23
+ }) => !$isVisible && `
24
+ display: none;
25
+ `}
26
+ `;
27
+ //# sourceMappingURL=CodeScanner.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeScanner.styles.js","names":["styled","StyledCodeScanner","div","StyledCodeScannerTextWrapper","StyledCodeScannerPreview","video","$isVisible"],"sources":["../../../../src/components/code-scanner/CodeScanner.styles.ts"],"sourcesContent":["import styled from 'styled-components';\n\nexport const StyledCodeScanner = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n`;\n\ntype StyledCodeScannerPreviewProps = {\n $isVisible: boolean;\n};\n\nexport const StyledCodeScannerTextWrapper = styled.div`\n width: 640px;\n display: flex;\n justify-content: center;\n align-items: center;\n aspect-ratio: 3 / 2;\n flex-direction: column;\n text-align: center;\n padding: 20px;\n`;\n\nexport const StyledCodeScannerPreview = styled.video<StyledCodeScannerPreviewProps>`\n width: 100%;\n height: 100%;\n\n ${({ $isVisible }) =>\n !$isVisible &&\n `\n display: none;\n `}\n`;\n"],"mappings":"AAAA,OAAOA,MAAM,MAAM,mBAAmB;AAEtC,OAAO,MAAMC,iBAAiB,GAAGD,MAAM,CAACE,GAAG;AAC3C;AACA;AACA;AACA,CAAC;AAMD,OAAO,MAAMC,4BAA4B,GAAGH,MAAM,CAACE,GAAG;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAED,OAAO,MAAME,wBAAwB,GAAGJ,MAAM,CAACK,KAAoC;AACnF;AACA;AACA;AACA,MAAM,CAAC;EAAEC;AAAW,CAAC,KACb,CAACA,UAAU,IACX;AACR;AACA,KAAK;AACL,CAAC","ignoreList":[]}