@sanctum-key/react-native-sdk 1.0.23 → 1.0.25

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/build/package.json +3 -1
  2. package/build/src/components/EnhancedCameraView.d.ts +7 -1
  3. package/build/src/components/EnhancedCameraView.d.ts.map +1 -1
  4. package/build/src/components/EnhancedCameraView.js +88 -30
  5. package/build/src/components/EnhancedCameraView.js.map +1 -1
  6. package/build/src/components/EnhancedCameraView.web.d.ts +5 -1
  7. package/build/src/components/EnhancedCameraView.web.d.ts.map +1 -1
  8. package/build/src/components/EnhancedCameraView.web.js +80 -295
  9. package/build/src/components/EnhancedCameraView.web.js.map +1 -1
  10. package/build/src/components/KYCElements/CameraCapture.js +1 -1
  11. package/build/src/components/KYCElements/CameraCapture.js.map +1 -1
  12. package/build/src/components/KYCElements/CountrySelection.d.ts.map +1 -1
  13. package/build/src/components/KYCElements/CountrySelection.js +38 -218
  14. package/build/src/components/KYCElements/CountrySelection.js.map +1 -1
  15. package/build/src/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  16. package/build/src/components/KYCElements/CountrySelectionTemplate.js +119 -26
  17. package/build/src/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  18. package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  19. package/build/src/components/KYCElements/IDCardCapture.js +512 -87
  20. package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
  21. package/build/src/components/KYCElements/VerificationProgressTemplate.d.ts.map +1 -1
  22. package/build/src/components/KYCElements/VerificationProgressTemplate.js +93 -51
  23. package/build/src/components/KYCElements/VerificationProgressTemplate.js.map +1 -1
  24. package/build/src/components/OverLay/type.d.ts +1 -0
  25. package/build/src/components/OverLay/type.d.ts.map +1 -1
  26. package/build/src/components/OverLay/type.js.map +1 -1
  27. package/build/src/components/WebBarcodeScanner.d.ts +9 -0
  28. package/build/src/components/WebBarcodeScanner.d.ts.map +1 -0
  29. package/build/src/components/WebBarcodeScanner.js +152 -0
  30. package/build/src/components/WebBarcodeScanner.js.map +1 -0
  31. package/build/src/config/KYCConfigs.js +2 -2
  32. package/build/src/config/KYCConfigs.js.map +1 -1
  33. package/build/src/config/region_mapping.js +14 -14
  34. package/build/src/config/region_mapping.js.map +1 -1
  35. package/build/src/config/region_mapping.json +0 -14
  36. package/build/src/modules/api/CardAuthentification.d.ts +2 -0
  37. package/build/src/modules/api/CardAuthentification.d.ts.map +1 -1
  38. package/build/src/modules/api/CardAuthentification.js +23 -40
  39. package/build/src/modules/api/CardAuthentification.js.map +1 -1
  40. package/build/src/modules/api/KYCService.d.ts +7 -2
  41. package/build/src/modules/api/KYCService.d.ts.map +1 -1
  42. package/build/src/modules/api/KYCService.js +163 -57
  43. package/build/src/modules/api/KYCService.js.map +1 -1
  44. package/build/src/types/KYC.types.d.ts +1 -0
  45. package/build/src/types/KYC.types.d.ts.map +1 -1
  46. package/build/src/types/KYC.types.js.map +1 -1
  47. package/build/src/utils/aamvaParser.d.ts +62 -0
  48. package/build/src/utils/aamvaParser.d.ts.map +1 -0
  49. package/build/src/utils/aamvaParser.js +91 -0
  50. package/build/src/utils/aamvaParser.js.map +1 -0
  51. package/build/src/utils/cropByObb.d.ts.map +1 -1
  52. package/build/src/utils/cropByObb.js +4 -3
  53. package/build/src/utils/cropByObb.js.map +1 -1
  54. package/build/src/web/WebKYCEntry.d.ts +1 -1
  55. package/build/src/web/WebKYCEntry.d.ts.map +1 -1
  56. package/build/src/web/WebKYCEntry.js +105 -239
  57. package/build/src/web/WebKYCEntry.js.map +1 -1
  58. package/package.json +3 -1
  59. package/src/components/EnhancedCameraView.tsx +116 -42
  60. package/src/components/EnhancedCameraView.web.tsx +98 -338
  61. package/src/components/KYCElements/CameraCapture.tsx +1 -1
  62. package/src/components/KYCElements/CountrySelection.tsx +60 -240
  63. package/src/components/KYCElements/CountrySelectionTemplate.tsx +148 -29
  64. package/src/components/KYCElements/IDCardCapture.tsx +675 -142
  65. package/src/components/KYCElements/VerificationProgressTemplate.tsx +112 -65
  66. package/src/components/OverLay/type.ts +1 -1
  67. package/src/components/WebBarcodeScanner.tsx +273 -0
  68. package/src/config/KYCConfigs.ts +2 -2
  69. package/src/config/region_mapping.json +0 -14
  70. package/src/config/region_mapping.ts +14 -14
  71. package/src/modules/api/CardAuthentification.ts +44 -58
  72. package/src/modules/api/KYCService.ts +236 -82
  73. package/src/types/KYC.types.ts +1 -0
  74. package/src/utils/aamvaParser.ts +102 -0
  75. package/src/utils/cropByObb.ts +5 -3
  76. package/src/web/WebKYCEntry.tsx +125 -301
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctum-key/react-native-sdk",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "description": "Sanctum Key React Native SDK",
5
5
  "main": "build/src/index.js",
6
6
  "types": "build/src/index.d.ts",
@@ -47,6 +47,8 @@
47
47
  "access": "public"
48
48
  },
49
49
  "dependencies": {
50
+ "@zxing/browser": "^0.2.0",
51
+ "@zxing/library": "^0.22.0",
50
52
  "axios": "^1.11.0",
51
53
  "expo-blur": "~15.0.8",
52
54
  "i18n-js": "4.5.1",
@@ -1,4 +1,10 @@
1
1
  import React from 'react';
2
+ import { CodeType } from 'react-native-vision-camera';
2
3
  import { EnhancedCameraViewProps } from './OverLay/type';
3
- export declare const EnhancedCameraView: React.FC<EnhancedCameraViewProps>;
4
+ export interface ExtendedCameraProps extends EnhancedCameraViewProps {
5
+ isScanningBarcode?: boolean;
6
+ onBarcodeScanned?: (data: string) => void;
7
+ barcodeTypes?: CodeType[];
8
+ }
9
+ export declare const EnhancedCameraView: React.FC<ExtendedCameraProps>;
4
10
  //# sourceMappingURL=EnhancedCameraView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAOxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAIzD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAgHhE,CAAC"}
1
+ {"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EAAU,QAAQ,EAAmC,MAAM,4BAA4B,CAAC;AAG/F,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,MAAM,WAAW,mBAAoB,SAAQ,uBAAuB;IAClE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC;CAC3B;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAuL5D,CAAC"}
@@ -1,20 +1,27 @@
1
1
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
- import { View, StyleSheet, Text, AppState } from 'react-native';
3
- import { Camera, useCameraDevice } from 'react-native-vision-camera';
2
+ import { View, StyleSheet, Text, Platform } from 'react-native';
3
+ import { Camera, useCameraDevice, useCodeScanner } from 'react-native-vision-camera';
4
4
  import VisionCameraModule from '../modules/camera/VisionCameraModule';
5
5
  import { useI18n } from '../hooks/useI18n';
6
- import { Button } from './ui/Button';
7
- export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType = 'front', style, onError, onSilentCapture, silentCaptureResult, isProcessing = false, overlayComponent, }) => {
6
+ import { WebBarcodeScanner } from './WebBarcodeScanner';
7
+ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType = 'front', style, onError, onSilentCapture, silentCaptureResult, isProcessing = false, overlayComponent, isScanningBarcode = false, onBarcodeScanned, barcodeTypes }) => {
8
8
  const { t } = useI18n();
9
9
  const camera = useRef(null);
10
+ const webVideoRef = useRef(null);
10
11
  const isCapturingRef = useRef(false);
11
12
  const isProcessingRef = useRef(isProcessing);
12
13
  const [cameraType] = useState(initialCameraType);
13
14
  const [hasPermission, setHasPermission] = useState(null);
14
15
  const [isInitialized, setIsInitialized] = useState(false);
15
- const [refreshCamera, setRefreshCamera] = useState(false);
16
+ const [refreshCamera] = useState(false);
17
+ // 🚨 NEW STATE: Tells React when it is safe to mount the Web Scanner
18
+ const [isVideoFound, setIsVideoFound] = useState(false);
19
+ const scannedBarcodeRef = useRef(null);
20
+ const containerRef = useRef(null);
16
21
  const device = useCameraDevice(cameraType);
17
- useEffect(() => { isProcessingRef.current = isProcessing; }, [isProcessing]);
22
+ useEffect(() => {
23
+ isProcessingRef.current = isProcessing;
24
+ }, [isProcessing]);
18
25
  const checkPermissions = async () => {
19
26
  try {
20
27
  const hasAllPermissions = await VisionCameraModule.hasAllPermissions();
@@ -33,19 +40,28 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
33
40
  onError?.({ message: t('camera.errorOccurred') });
34
41
  }
35
42
  };
36
- useEffect(() => { if (showCamera)
37
- checkPermissions(); }, [showCamera, refreshCamera]);
38
43
  useEffect(() => {
39
- const sub = AppState.addEventListener('change', next => {
40
- if (next === 'active' && showCamera && hasPermission === false)
41
- checkPermissions();
42
- });
43
- return () => sub.remove();
44
- }, [showCamera, hasPermission]);
44
+ if (showCamera)
45
+ checkPermissions();
46
+ }, [showCamera, refreshCamera]);
45
47
  const onInitialized = useCallback(() => setIsInitialized(true), []);
46
48
  const onCameraError = useCallback((error) => {
47
49
  onError?.({ message: error.message || t('camera.errorOccurred') });
48
50
  }, [onError, t]);
51
+ const codeScanner = useCodeScanner({
52
+ codeTypes: barcodeTypes || ['pdf-417', 'qr', 'code-128', 'code-39'],
53
+ onCodeScanned: (codes) => {
54
+ if (!isProcessingRef.current && isScanningBarcode) {
55
+ for (const code of codes) {
56
+ if (code.value && scannedBarcodeRef.current !== code.value) {
57
+ scannedBarcodeRef.current = code.value;
58
+ onBarcodeScanned?.(code.value);
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ }
64
+ });
49
65
  const captureSilentPhoto = useCallback(async () => {
50
66
  if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current)
51
67
  return;
@@ -55,9 +71,10 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
55
71
  isCapturingRef.current = true;
56
72
  const photo = await camera.current.takePhoto({ enableShutterSound: false, flash: 'off' });
57
73
  const result = await VisionCameraModule.processPhotoResult(photo);
58
- onSilentCapture?.({ ...result, path: result.path || photo.path });
74
+ onSilentCapture?.({ ...result, path: result.path || photo.path, barcode: scannedBarcodeRef.current });
75
+ }
76
+ catch {
59
77
  }
60
- catch { /* silent */ }
61
78
  finally {
62
79
  isCapturingRef.current = false;
63
80
  }
@@ -70,24 +87,65 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
70
87
  const timer = setTimeout(() => {
71
88
  if (!active)
72
89
  return;
73
- id = setInterval(captureSilentPhoto, 1500);
74
- }, 1000);
75
- return () => { active = false; clearTimeout(timer); if (id)
76
- clearInterval(id); };
77
- }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);
90
+ const intervalDelay = isScanningBarcode ? 3000 : 1500;
91
+ id = setInterval(captureSilentPhoto, intervalDelay);
92
+ }, 1500);
93
+ return () => {
94
+ active = false;
95
+ clearTimeout(timer);
96
+ if (id)
97
+ clearInterval(id);
98
+ };
99
+ }, [showCamera, isInitialized, isProcessing, captureSilentPhoto, isScanningBarcode]);
100
+ // Web: Aggressive Video Element Hunter
101
+ useEffect(() => {
102
+ // 🚨 Kick off the search immediately if we are on the web and the camera should be showing
103
+ if (Platform.OS !== 'web' || !showCamera)
104
+ return;
105
+ let timeoutId;
106
+ const findVideo = () => {
107
+ console.log('🔍 [WEB ENGINE] Searching for <video> element in DOM...');
108
+ let video = null;
109
+ if (containerRef.current?.querySelector) {
110
+ video = containerRef.current.querySelector('video');
111
+ }
112
+ if (!video) {
113
+ video = document.querySelector('video');
114
+ }
115
+ if (video) {
116
+ console.log('✅ [WEB ENGINE] <video> element locked! Booting ZXing Scanner.');
117
+ webVideoRef.current = video;
118
+ setIsVideoFound(true); // This tells React to mount the scanner!
119
+ }
120
+ else {
121
+ console.log('⏳ [WEB ENGINE] <video> not found yet, retrying in 500ms...');
122
+ timeoutId = setTimeout(findVideo, 500);
123
+ }
124
+ };
125
+ // Start hunting immediately, do NOT wait for isInitialized
126
+ findVideo();
127
+ return () => clearTimeout(timeoutId);
128
+ }, [showCamera]);
129
+ // 🚨 FIX: Memoized Web Callback to prevent infinite re-rendering loop
130
+ const handleWebBarcodeScanned = useCallback((value) => {
131
+ console.log(`🎉 [WEB SCANNER] SUCCESS! Decoded value:`, value);
132
+ alert(`Decoded: ${value.substring(0, 50)}...`);
133
+ if (!isProcessingRef.current && value !== scannedBarcodeRef.current) {
134
+ scannedBarcodeRef.current = value;
135
+ onBarcodeScanned?.(value);
136
+ }
137
+ }, [onBarcodeScanned]);
78
138
  if (hasPermission === null)
79
139
  return <View style={[styles.container, style]}/>;
80
- if (hasPermission === false) {
81
- return (<View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>
82
- <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>
83
- <Button title="Refresh Camera" onPress={() => setRefreshCamera(p => !p)} variant="primary"/>
84
- </View>);
85
- }
140
+ if (hasPermission === false)
141
+ return <View style={[styles.container, style]}><Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text></View>;
86
142
  if (!device || !showCamera)
87
143
  return <View style={[styles.container, style]}/>;
88
- return (<View style={[styles.container, style]}>
89
- <Camera ref={camera} style={StyleSheet.absoluteFill} device={device} resizeMode="cover" isActive={showCamera && !isProcessing} photo={true} video={false} audio={false} onInitialized={onInitialized} onError={onCameraError}/>
90
-
144
+ return (<View ref={containerRef} style={[styles.container, style]}>
145
+ <Camera ref={camera} style={StyleSheet.absoluteFill} device={device} resizeMode="cover" isActive={showCamera && !isProcessing} photo={true} video={false} audio={false} onInitialized={onInitialized} onError={onCameraError} codeScanner={Platform.OS !== 'web' && isScanningBarcode ? codeScanner : undefined}/>
146
+
147
+ {Platform.OS === 'web' && isScanningBarcode && isVideoFound && (<WebBarcodeScanner videoRef={webVideoRef} onBarcodeScanned={handleWebBarcodeScanned} active={!isProcessingRef.current}/>)}
148
+
91
149
  {overlayComponent}
92
150
  </View>);
93
151
  };
@@ -1 +1 @@
1
- {"version":3,"file":"EnhancedCameraView.js","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EACL,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EACjC,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,kBAAkB,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,MAAM,CAAC,MAAM,kBAAkB,GAAsC,CAAC,EACpE,UAAU,EACV,UAAU,EAAE,iBAAiB,GAAG,OAAO,EACvC,KAAK,EACL,OAAO,EACP,eAAe,EACf,mBAAmB,EACnB,YAAY,GAAG,KAAK,EACpB,gBAAgB,GACjB,EAAE,EAAE;IACH,MAAM,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,MAAM,CAAS,IAAI,CAAC,CAAC;IAEpC,MAAM,cAAc,GAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,eAAe,GAAK,MAAM,CAAC,YAAY,CAAC,CAAC;IAE/C,MAAM,CAAC,UAAU,CAAC,GAAQ,QAAQ,CAAmB,iBAAiB,CAAC,CAAC;IACxE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC,CAAC;IACzE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAE3C,SAAS,CAAC,GAAG,EAAE,GAAG,eAAe,CAAC,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAE7E,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,iBAAiB,GAAG,MAAM,kBAAkB,CAAC,iBAAiB,EAAE,CAAC;YACvE,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,qBAAqB,EAAE,CAAC;gBACjE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,gBAAgB,CAAC,KAAK,CAAC,CAAC;oBACxB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,2BAA2B,CAAC,EAAE,CAAC,CAAC;oBACvD,OAAO;gBACT,CAAC;YACH,CAAC;YACD,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACxB,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE,GAAG,IAAI,UAAU;QAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;IAEtF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,GAAG,GAAG,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE;YACrD,IAAI,IAAI,KAAK,QAAQ,IAAI,UAAU,IAAI,aAAa,KAAK,KAAK;gBAAE,gBAAgB,EAAE,CAAC;QACrF,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;IAEhC,MAAM,aAAa,GAAI,WAAW,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACrE,MAAM,aAAa,GAAI,WAAW,CAAC,CAAC,KAAU,EAAE,EAAE;QAChD,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAEjB,MAAM,kBAAkB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAChD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,aAAa,IAAI,eAAe,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;YAAE,OAAO;QACnG,IAAI,mBAAmB,EAAE,WAAW;YAAE,OAAO;QAC7C,IAAI,CAAC;YACH,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9B,MAAM,KAAK,GAAI,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,kBAAkB,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAC3F,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAClE,eAAe,EAAE,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;gBAAS,CAAC;YAChC,cAAc,CAAC,OAAO,GAAG,KAAK,CAAC;QACjC,CAAC;IACH,CAAC,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAE1D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU,IAAI,CAAC,aAAa,IAAI,YAAY;YAAE,OAAO;QAC1D,IAAI,MAAM,GAAG,IAAI,CAAC;QAClB,IAAI,EAAkC,CAAC;QACvC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,EAAE,GAAG,WAAW,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAC7C,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,OAAO,GAAG,EAAE,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;YAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAElE,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,EAAG,CAAC;IAE9E,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,CACzF;QAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,EAAE,IAAI,CAC7E;QAAA,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAC5F;MAAA,EAAE,IAAI,CAAC,CACR,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,EAAG,CAAC;IAE9E,OAAO,CACL,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CACrC;MAAA,CAAC,MAAM,CACL,GAAG,CAAC,CAAC,MAAM,CAAC,CACZ,KAAK,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAC/B,MAAM,CAAC,CAAC,MAAM,CAAC,CACf,UAAU,CAAC,OAAO,CAClB,QAAQ,CAAC,CAAC,UAAU,IAAI,CAAC,YAAY,CAAC,CACtC,KAAK,CAAC,CAAC,IAAI,CAAC,CACZ,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,KAAK,CAAC,CAAC,KAAK,CAAC,CACb,aAAa,CAAC,CAAC,aAAa,CAAC,CAC7B,OAAO,CAAC,CAAC,aAAa,CAAC,EAGzB;;MAAA,CAAC,gBAAgB,CACnB;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,eAAe,EAAE,OAAO,EAAE;IAChD,iBAAiB,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;CACrF,CAAC,CAAC","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n View, StyleSheet, Text, AppState\n} from 'react-native';\nimport { Camera, useCameraDevice } from 'react-native-vision-camera';\nimport VisionCameraModule from '../modules/camera/VisionCameraModule';\nimport { useI18n } from '../hooks/useI18n';\nimport { EnhancedCameraViewProps } from './OverLay/type';\nimport { Button } from './ui/Button';\n\n\nexport const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({\n showCamera,\n cameraType: initialCameraType = 'front',\n style,\n onError,\n onSilentCapture,\n silentCaptureResult,\n isProcessing = false,\n overlayComponent,\n}) => {\n const { t } = useI18n();\n const camera = useRef<Camera>(null);\n\n const isCapturingRef = useRef(false);\n const isProcessingRef = useRef(isProcessing);\n\n const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [refreshCamera, setRefreshCamera] = useState(false);\n\n const device = useCameraDevice(cameraType);\n\n useEffect(() => { isProcessingRef.current = isProcessing; }, [isProcessing]);\n\n const checkPermissions = async () => {\n try {\n const hasAllPermissions = await VisionCameraModule.hasAllPermissions();\n if (!hasAllPermissions) {\n const granted = await VisionCameraModule.requestAllPermissions();\n if (!granted) {\n setHasPermission(false);\n onError?.({ message: t('camera.permissionRequired') });\n return;\n }\n }\n setHasPermission(true);\n } catch {\n setHasPermission(false);\n onError?.({ message: t('camera.errorOccurred') });\n }\n };\n\n useEffect(() => { if (showCamera) checkPermissions(); }, [showCamera, refreshCamera]);\n\n useEffect(() => {\n const sub = AppState.addEventListener('change', next => {\n if (next === 'active' && showCamera && hasPermission === false) checkPermissions();\n });\n return () => sub.remove();\n }, [showCamera, hasPermission]);\n\n const onInitialized = useCallback(() => setIsInitialized(true), []);\n const onCameraError = useCallback((error: any) => {\n onError?.({ message: error.message || t('camera.errorOccurred') });\n }, [onError, t]);\n\n const captureSilentPhoto = useCallback(async () => {\n if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;\n if (silentCaptureResult?.isAnalyzing) return;\n try {\n isCapturingRef.current = true;\n const photo = await camera.current.takePhoto({ enableShutterSound: false, flash: 'off' });\n const result = await VisionCameraModule.processPhotoResult(photo);\n onSilentCapture?.({ ...result, path: result.path || photo.path });\n } catch { /* silent */ } finally {\n isCapturingRef.current = false;\n }\n }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n let active = true;\n let id: ReturnType<typeof setInterval>;\n const timer = setTimeout(() => {\n if (!active) return;\n id = setInterval(captureSilentPhoto, 1500);\n }, 1000);\n return () => { active = false; clearTimeout(timer); if (id) clearInterval(id); };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);\n\n if (hasPermission === null) return <View style={[styles.container, style]} />;\n\n if (hasPermission === false) {\n return (\n <View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>\n <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>\n <Button title=\"Refresh Camera\" onPress={() => setRefreshCamera(p => !p)} variant=\"primary\" />\n </View>\n );\n }\n\n if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n return (\n <View style={[styles.container, style]}>\n <Camera\n ref={camera}\n style={StyleSheet.absoluteFill}\n device={device}\n resizeMode=\"cover\"\n isActive={showCamera && !isProcessing}\n photo={true}\n video={false}\n audio={false}\n onInitialized={onInitialized}\n onError={onCameraError}\n />\n\n {overlayComponent}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: { flex: 1, backgroundColor: 'black' },\n permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n});"]}
1
+ {"version":3,"file":"EnhancedCameraView.js","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View, StyleSheet, Text, Platform } from 'react-native';\nimport { Camera, CodeType, useCameraDevice, useCodeScanner } from 'react-native-vision-camera';\nimport VisionCameraModule from '../modules/camera/VisionCameraModule';\nimport { useI18n } from '../hooks/useI18n';\nimport { EnhancedCameraViewProps } from './OverLay/type';\nimport { WebBarcodeScanner } from './WebBarcodeScanner';\n\nexport interface ExtendedCameraProps extends EnhancedCameraViewProps {\n isScanningBarcode?: boolean;\n onBarcodeScanned?: (data: string) => void;\n barcodeTypes?: CodeType[];\n}\n\nexport const EnhancedCameraView: React.FC<ExtendedCameraProps> = ({\n showCamera,\n cameraType: initialCameraType = 'front',\n style,\n onError,\n onSilentCapture,\n silentCaptureResult,\n isProcessing = false,\n overlayComponent,\n isScanningBarcode = false,\n onBarcodeScanned,\n barcodeTypes\n}) => {\n const { t } = useI18n();\n const camera = useRef<Camera>(null);\n \n const webVideoRef = useRef<HTMLVideoElement | null>(null);\n const isCapturingRef = useRef(false);\n const isProcessingRef = useRef(isProcessing);\n const [cameraType] = useState<'front' | 'back'>(initialCameraType);\n const [hasPermission, setHasPermission] = useState<boolean | null>(null);\n const [isInitialized, setIsInitialized] = useState(false);\n const [refreshCamera] = useState(false);\n \n // 🚨 NEW STATE: Tells React when it is safe to mount the Web Scanner\n const [isVideoFound, setIsVideoFound] = useState(false);\n\n const scannedBarcodeRef = useRef<string | null>(null);\n const containerRef = useRef<any>(null);\n const device = useCameraDevice(cameraType);\n\n useEffect(() => {\n isProcessingRef.current = isProcessing;\n }, [isProcessing]);\n\n const checkPermissions = async () => {\n try {\n const hasAllPermissions = await VisionCameraModule.hasAllPermissions();\n if (!hasAllPermissions) {\n const granted = await VisionCameraModule.requestAllPermissions();\n if (!granted) {\n setHasPermission(false);\n onError?.({ message: t('camera.permissionRequired') });\n return;\n }\n }\n setHasPermission(true);\n } catch {\n setHasPermission(false);\n onError?.({ message: t('camera.errorOccurred') });\n }\n };\n\n useEffect(() => {\n if (showCamera) checkPermissions();\n }, [showCamera, refreshCamera]);\n\n const onInitialized = useCallback(() => setIsInitialized(true), []);\n const onCameraError = useCallback((error: any) => {\n onError?.({ message: error.message || t('camera.errorOccurred') });\n }, [onError, t]);\n\n const codeScanner = useCodeScanner({\n codeTypes: barcodeTypes || ['pdf-417', 'qr', 'code-128', 'code-39'],\n onCodeScanned: (codes) => {\n if (!isProcessingRef.current && isScanningBarcode) {\n for (const code of codes) {\n if (code.value && scannedBarcodeRef.current !== code.value) {\n scannedBarcodeRef.current = code.value;\n onBarcodeScanned?.(code.value);\n break;\n }\n }\n }\n }\n });\n\n const captureSilentPhoto = useCallback(async () => {\n if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;\n if (silentCaptureResult?.isAnalyzing) return;\n try {\n isCapturingRef.current = true;\n const photo = await camera.current.takePhoto({ enableShutterSound: false, flash: 'off' });\n const result = await VisionCameraModule.processPhotoResult(photo);\n onSilentCapture?.({ ...result, path: result.path || photo.path, barcode: scannedBarcodeRef.current });\n } catch {\n } finally {\n isCapturingRef.current = false;\n }\n }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n let active = true;\n let id: ReturnType<typeof setInterval>;\n const timer = setTimeout(() => {\n if (!active) return;\n const intervalDelay = isScanningBarcode ? 3000 : 1500;\n id = setInterval(captureSilentPhoto, intervalDelay);\n }, 1500);\n return () => {\n active = false;\n clearTimeout(timer);\n if (id) clearInterval(id);\n };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto, isScanningBarcode]);\n\n // Web: Aggressive Video Element Hunter\n useEffect(() => {\n // 🚨 Kick off the search immediately if we are on the web and the camera should be showing\n if (Platform.OS !== 'web' || !showCamera) return;\n \n let timeoutId: ReturnType<typeof setTimeout>;\n\n const findVideo = () => {\n console.log('🔍 [WEB ENGINE] Searching for <video> element in DOM...');\n \n let video: HTMLVideoElement | null = null;\n if (containerRef.current?.querySelector) {\n video = containerRef.current.querySelector('video');\n }\n if (!video) {\n video = document.querySelector('video');\n }\n\n if (video) {\n console.log('✅ [WEB ENGINE] <video> element locked! Booting ZXing Scanner.');\n webVideoRef.current = video;\n setIsVideoFound(true); // This tells React to mount the scanner!\n } else {\n console.log('⏳ [WEB ENGINE] <video> not found yet, retrying in 500ms...');\n timeoutId = setTimeout(findVideo, 500);\n }\n };\n \n // Start hunting immediately, do NOT wait for isInitialized\n findVideo();\n\n return () => clearTimeout(timeoutId);\n }, [showCamera]);\n\n // 🚨 FIX: Memoized Web Callback to prevent infinite re-rendering loop\n const handleWebBarcodeScanned = useCallback((value: string) => {\n console.log(`🎉 [WEB SCANNER] SUCCESS! Decoded value:`, value);\n alert(`Decoded: ${value.substring(0, 50)}...`);\n \n if (!isProcessingRef.current && value !== scannedBarcodeRef.current) {\n scannedBarcodeRef.current = value;\n onBarcodeScanned?.(value);\n }\n }, [onBarcodeScanned]);\n\n if (hasPermission === null) return <View style={[styles.container, style]} />;\n if (hasPermission === false) return <View style={[styles.container, style]}><Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text></View>;\n if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n return (\n <View ref={containerRef} style={[styles.container, style]}>\n <Camera\n ref={camera}\n style={StyleSheet.absoluteFill}\n device={device}\n resizeMode=\"cover\"\n isActive={showCamera && !isProcessing}\n photo={true}\n video={false}\n audio={false}\n onInitialized={onInitialized}\n onError={onCameraError}\n codeScanner={Platform.OS !== 'web' && isScanningBarcode ? codeScanner : undefined}\n />\n \n {Platform.OS === 'web' && isScanningBarcode && isVideoFound && (\n <WebBarcodeScanner\n videoRef={webVideoRef as React.RefObject<HTMLVideoElement>}\n onBarcodeScanned={handleWebBarcodeScanned}\n active={!isProcessingRef.current}\n />\n )}\n \n {overlayComponent}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n container: { flex: 1, backgroundColor: 'black' },\n permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n});"]}
@@ -1,4 +1,8 @@
1
1
  import React from 'react';
2
2
  import { EnhancedCameraViewProps } from './OverLay/type';
3
- export declare const EnhancedCameraView: React.FC<EnhancedCameraViewProps>;
3
+ export interface ExtendedCameraProps extends EnhancedCameraViewProps {
4
+ isScanningBarcode?: boolean;
5
+ onBarcodeScanned?: (data: string) => void;
6
+ }
7
+ export declare const EnhancedCameraView: React.FC<ExtendedCameraProps>;
4
8
  //# sourceMappingURL=EnhancedCameraView.web.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EnhancedCameraView.web.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAIzD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA+chE,CAAC"}
1
+ {"version":3,"file":"EnhancedCameraView.web.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAExE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAMzD,MAAM,WAAW,mBAAoB,SAAQ,uBAAuB;IAClE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAgU5D,CAAC"}