@sanctum-key/react-native-sdk 1.0.13 → 1.0.15

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanctum-key/react-native-sdk",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "description": "Sanctum Key React Native SDK",
5
5
  "main": "build/src/index.js",
6
6
  "types": "build/src/index.d.ts",
@@ -1 +1 @@
1
- {"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAqJhE,CAAC"}
1
+ {"version":3,"file":"EnhancedCameraView.d.ts","sourceRoot":"","sources":["../../../src/components/EnhancedCameraView.tsx"],"names":[],"mappings":"AAuKA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGzD,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA2IhE,CAAC"}
@@ -1,3 +1,146 @@
1
+ // import React, { useCallback, useEffect, useRef, useState } from 'react';
2
+ // import { View, StyleSheet, Text, AppState } from 'react-native';
3
+ // import { Camera, useCameraDevice, useCameraFormat } from 'react-native-vision-camera';
4
+ // import VisionCameraModule from '../modules/camera/VisionCameraModule';
5
+ // import { useI18n } from '../hooks/useI18n';
6
+ // import { EnhancedCameraViewProps } from './OverLay/type';
7
+ // import { Button } from './ui/Button';
8
+ // export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
9
+ // showCamera,
10
+ // cameraType: initialCameraType = 'front',
11
+ // style,
12
+ // onError,
13
+ // onSilentCapture,
14
+ // silentCaptureResult,
15
+ // isProcessing = false,
16
+ // overlayComponent,
17
+ // }) => {
18
+ // const { t } = useI18n();
19
+ // const camera = useRef<Camera>(null);
20
+ // const isCapturingRef = useRef(false);
21
+ // const isProcessingRef = useRef(isProcessing);
22
+ // const [cameraType] = useState<'front' | 'back'>(initialCameraType);
23
+ // const [hasPermission, setHasPermission] = useState<boolean | null>(null);
24
+ // const [isInitialized, setIsInitialized] = useState(false);
25
+ // const [refreshCamera, setRefreshCamera] = useState(false);
26
+ // const [layout, setLayout] = useState({ width: 0, height: 0 });
27
+ // const device = useCameraDevice(cameraType, {
28
+ // physicalDevices: [
29
+ // 'wide-angle-camera' // Explicitly request standard 1x lens
30
+ // ]
31
+ // });
32
+ // const targetRatio = layout.width > 0 ? layout.height / layout.width : 16 / 9;
33
+ // const format = useCameraFormat(device, [
34
+ // { photoAspectRatio: targetRatio },
35
+ // { photoResolution: 'max' }
36
+ // ]);
37
+ // useEffect(() => {
38
+ // isProcessingRef.current = isProcessing;
39
+ // }, [isProcessing]);
40
+ // const checkPermissions = async () => {
41
+ // try {
42
+ // const hasAllPermissions = await VisionCameraModule.hasAllPermissions();
43
+ // if (!hasAllPermissions) {
44
+ // const granted = await VisionCameraModule.requestAllPermissions();
45
+ // if (!granted) {
46
+ // setHasPermission(false);
47
+ // onError?.({ message: t('camera.permissionRequired') });
48
+ // return;
49
+ // }
50
+ // }
51
+ // setHasPermission(true);
52
+ // } catch (error) {
53
+ // setHasPermission(false);
54
+ // onError?.({ message: t('camera.errorOccurred') });
55
+ // }
56
+ // };
57
+ // useEffect(() => {
58
+ // if (showCamera) checkPermissions();
59
+ // }, [showCamera, refreshCamera]);
60
+ // useEffect(() => {
61
+ // const subscription = AppState.addEventListener('change', nextAppState => {
62
+ // if (nextAppState === 'active' && showCamera && hasPermission === false) {
63
+ // checkPermissions();
64
+ // }
65
+ // });
66
+ // return () => subscription.remove();
67
+ // }, [showCamera, hasPermission]);
68
+ // const onInitialized = useCallback(() => setIsInitialized(true), []);
69
+ // const onCameraError = useCallback((error: any) => {
70
+ // onError?.({ message: error.message || t('camera.errorOccurred') });
71
+ // }, [onError, t]);
72
+ // const captureSilentPhoto = useCallback(async () => {
73
+ // if (!camera.current || !isInitialized || isProcessingRef.current || isCapturingRef.current) return;
74
+ // if (silentCaptureResult?.isAnalyzing) return;
75
+ // try {
76
+ // isCapturingRef.current = true;
77
+ // const photo = await camera.current.takePhoto({
78
+ // enableShutterSound: false,
79
+ // flash: 'off',
80
+ // });
81
+ // const result = await VisionCameraModule.processPhotoResult(photo);
82
+ // onSilentCapture?.({
83
+ // ...result,
84
+ // path: result.path || photo.path,
85
+ // });
86
+ // } catch (error) {
87
+ // // Silent background fail
88
+ // } finally {
89
+ // isCapturingRef.current = false;
90
+ // }
91
+ // }, [isInitialized, onSilentCapture, silentCaptureResult]);
92
+ // useEffect(() => {
93
+ // if (!showCamera || !isInitialized || isProcessing) return;
94
+ // let isActive = true;
95
+ // let intervalId: ReturnType<typeof setInterval>;
96
+ // const warmupTimer = setTimeout(() => {
97
+ // if (!isActive) return;
98
+ // intervalId = setInterval(() => {
99
+ // captureSilentPhoto();
100
+ // }, 1500);
101
+ // }, 1000);
102
+ // return () => {
103
+ // isActive = false;
104
+ // clearTimeout(warmupTimer);
105
+ // if (intervalId) clearInterval(intervalId);
106
+ // };
107
+ // }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);
108
+ // if (hasPermission === null) return <View style={[styles.container, style]} />;
109
+ // if (hasPermission === false) {
110
+ // return (
111
+ // <View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>
112
+ // <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>
113
+ // <Button title="Refresh Camera" onPress={() => setRefreshCamera(prev => !prev)} variant="primary" />
114
+ // </View>
115
+ // );
116
+ // }
117
+ // if (!device || !showCamera) return <View style={[styles.container, style]} />;
118
+ // return (
119
+ // <View
120
+ // style={[styles.container, style]}
121
+ // onLayout={(e) => setLayout({ width: e.nativeEvent.layout.width, height: e.nativeEvent.layout.height })}
122
+ // >
123
+ // <Camera
124
+ // ref={camera}
125
+ // style={StyleSheet.absoluteFill}
126
+ // device={device}
127
+ // format={format}
128
+ // resizeMode="cover"
129
+ // isActive={showCamera && !isProcessing}
130
+ // photo={true}
131
+ // video={false}
132
+ // audio={false}
133
+ // onInitialized={onInitialized}
134
+ // onError={onCameraError}
135
+ // />
136
+ // {overlayComponent}
137
+ // </View>
138
+ // );
139
+ // };
140
+ // const styles = StyleSheet.create({
141
+ // container: { flex: 1, backgroundColor: 'black' },
142
+ // permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },
143
+ // });
1
144
  import React, { useCallback, useEffect, useRef, useState } from 'react';
2
145
  import { View, StyleSheet, Text, AppState } from 'react-native';
3
146
  import { Camera, useCameraDevice } from 'react-native-vision-camera';
@@ -10,10 +153,11 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
10
153
  const isCapturingRef = useRef(false);
11
154
  const isProcessingRef = useRef(isProcessing);
12
155
  const [cameraType] = useState(initialCameraType);
13
- // 🚨 BUG FIX: Initialize to null to prevent the "Flicker" on retake
14
156
  const [hasPermission, setHasPermission] = useState(null);
15
157
  const [isInitialized, setIsInitialized] = useState(false);
16
158
  const [refreshCamera, setRefreshCamera] = useState(false);
159
+ // 🚨 THE FIX: Removed the strict physical device filtering and custom format.
160
+ // This allows Android to select its own supported, stable hardware stream, preventing crashes.
17
161
  const device = useCameraDevice(cameraType);
18
162
  useEffect(() => {
19
163
  isProcessingRef.current = isProcessing;
@@ -76,7 +220,6 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
76
220
  isCapturingRef.current = false;
77
221
  }
78
222
  }, [isInitialized, onSilentCapture, silentCaptureResult]);
79
- // 🚨 BUG FIX: The Warm-up Timer (Fixes Blurry Images)
80
223
  useEffect(() => {
81
224
  if (!showCamera || !isInitialized || isProcessing)
82
225
  return;
@@ -87,7 +230,7 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
87
230
  return;
88
231
  intervalId = setInterval(() => {
89
232
  captureSilentPhoto();
90
- }, 1500); // 1.5s gives the hardware more time to stabilize between shots
233
+ }, 1500);
91
234
  }, 1000);
92
235
  return () => {
93
236
  isActive = false;
@@ -96,11 +239,8 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
96
239
  clearInterval(intervalId);
97
240
  };
98
241
  }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);
99
- // --- RENDERERS ---
100
- // 🚨 BUG FIX: Show nothing while checking permissions (Stops flicker)
101
- if (hasPermission === null) {
242
+ if (hasPermission === null)
102
243
  return <View style={[styles.container, style]}/>;
103
- }
104
244
  if (hasPermission === false) {
105
245
  return (<View style={[styles.container, style, { justifyContent: 'center', alignItems: 'center' }]}>
106
246
  <Text style={styles.permissionMessage}>{t('camera.permissionRequired')}</Text>
@@ -110,7 +250,7 @@ export const EnhancedCameraView = ({ showCamera, cameraType: initialCameraType =
110
250
  if (!device || !showCamera)
111
251
  return <View style={[styles.container, style]}/>;
112
252
  return (<View style={[styles.container, style]}>
113
- <Camera ref={camera} style={StyleSheet.absoluteFill} device={device} isActive={showCamera && !isProcessing} photo={true} video={false} audio={false} onInitialized={onInitialized} onError={onCameraError}/>
253
+ <Camera ref={camera} style={StyleSheet.absoluteFill} device={device} resizeMode="cover" isActive={showCamera && !isProcessing} photo={true} video={false} audio={false} onInitialized={onInitialized} onError={onCameraError}/>
114
254
  {overlayComponent}
115
255
  </View>);
116
256
  };
@@ -1 +1 @@
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, AppState } 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\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 \n // 🚨 BUG FIX: Initialize to null to prevent the \"Flicker\" on retake\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(() => {\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 (error) {\n setHasPermission(false);\n onError?.({ message: t('camera.errorOccurred') });\n }\n };\n\n useEffect(() => {\n if (showCamera) checkPermissions();\n }, [showCamera, refreshCamera]);\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', nextAppState => {\n if (nextAppState === 'active' && showCamera && hasPermission === false) {\n checkPermissions();\n }\n });\n return () => subscription.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\n try {\n isCapturingRef.current = true; \n const photo = await camera.current.takePhoto({\n enableShutterSound: false, \n flash: 'off', \n });\n\n const result = await VisionCameraModule.processPhotoResult(photo);\n \n onSilentCapture?.({\n ...result,\n path: result.path || photo.path, \n });\n\n } catch (error) {\n // Silent background fail\n } finally {\n isCapturingRef.current = false; \n }\n }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n // 🚨 BUG FIX: The Warm-up Timer (Fixes Blurry Images)\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n \n let isActive = true;\n let intervalId: ReturnType<typeof setInterval>;\n\n const warmupTimer = setTimeout(() => {\n if (!isActive) return;\n intervalId = setInterval(() => {\n captureSilentPhoto();\n }, 1500); // 1.5s gives the hardware more time to stabilize between shots\n }, 1000); \n \n return () => {\n isActive = false;\n clearTimeout(warmupTimer);\n if (intervalId) clearInterval(intervalId);\n };\n }, [showCamera, isInitialized, isProcessing, captureSilentPhoto]);\n\n // --- RENDERERS ---\n \n // 🚨 BUG FIX: Show nothing while checking permissions (Stops flicker)\n if (hasPermission === null) {\n return <View style={[styles.container, style]} />;\n }\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 \n title=\"Refresh Camera\" \n onPress={() => setRefreshCamera(prev => !prev)} \n variant=\"primary\"\n />\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 isActive={showCamera && !isProcessing}\n photo={true}\n video={false} \n audio={false} \n onInitialized={onInitialized}\n onError={onCameraError}\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';\n// import { View, StyleSheet, Text, AppState } from 'react-native';\n// import { Camera, useCameraDevice, useCameraFormat } from 'react-native-vision-camera'; \n// import VisionCameraModule from '../modules/camera/VisionCameraModule';\n// import { useI18n } from '../hooks/useI18n';\n// import { EnhancedCameraViewProps } from './OverLay/type';\n// import { Button } from './ui/Button';\n\n// export 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// const [layout, setLayout] = useState({ width: 0, height: 0 });\n\n\n// const device = useCameraDevice(cameraType, {\n// physicalDevices: [\n// 'wide-angle-camera' // Explicitly request standard 1x lens\n// ]\n// });\n\n// const targetRatio = layout.width > 0 ? layout.height / layout.width : 16 / 9;\n\n// const format = useCameraFormat(device, [\n// { photoAspectRatio: targetRatio },\n// { photoResolution: 'max' } \n// ]);\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 (error) {\n// setHasPermission(false);\n// onError?.({ message: t('camera.errorOccurred') });\n// }\n// };\n\n// useEffect(() => {\n// if (showCamera) checkPermissions();\n// }, [showCamera, refreshCamera]);\n\n// useEffect(() => {\n// const subscription = AppState.addEventListener('change', nextAppState => {\n// if (nextAppState === 'active' && showCamera && hasPermission === false) {\n// checkPermissions();\n// }\n// });\n// return () => subscription.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\n// try {\n// isCapturingRef.current = true;\n// const photo = await camera.current.takePhoto({\n// enableShutterSound: false,\n// flash: 'off',\n// });\n// const result = await VisionCameraModule.processPhotoResult(photo);\n\n// onSilentCapture?.({\n// ...result,\n// path: result.path || photo.path,\n// });\n// } catch (error) {\n// // Silent background fail\n// } finally {\n// isCapturingRef.current = false;\n// }\n// }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n// useEffect(() => {\n// if (!showCamera || !isInitialized || isProcessing) return;\n// let isActive = true;\n// let intervalId: ReturnType<typeof setInterval>;\n\n// const warmupTimer = setTimeout(() => {\n// if (!isActive) return;\n// intervalId = setInterval(() => {\n// captureSilentPhoto();\n// }, 1500);\n// }, 1000);\n\n// return () => {\n// isActive = false;\n// clearTimeout(warmupTimer);\n// if (intervalId) clearInterval(intervalId);\n// };\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(prev => !prev)} variant=\"primary\" />\n// </View>\n// );\n// }\n\n// if (!device || !showCamera) return <View style={[styles.container, style]} />;\n\n// return (\n// <View \n// style={[styles.container, style]}\n// onLayout={(e) => setLayout({ width: e.nativeEvent.layout.width, height: e.nativeEvent.layout.height })}\n// >\n// <Camera\n// ref={camera}\n// style={StyleSheet.absoluteFill}\n// device={device}\n// format={format} \n// resizeMode=\"cover\" \n// isActive={showCamera && !isProcessing}\n// photo={true}\n// video={false}\n// audio={false}\n// onInitialized={onInitialized}\n// onError={onCameraError}\n// />\n// {overlayComponent}\n// </View>\n// );\n// };\n\n// const styles = StyleSheet.create({\n// container: { flex: 1, backgroundColor: 'black' },\n// permissionMessage: { color: 'white', textAlign: 'center', margin: 20, fontSize: 16 },\n// });\n\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View, StyleSheet, Text, AppState } 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\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 // 🚨 THE FIX: Removed the strict physical device filtering and custom format.\n // This allows Android to select its own supported, stable hardware stream, preventing crashes.\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 (error) {\n setHasPermission(false);\n onError?.({ message: t('camera.errorOccurred') });\n }\n };\n\n useEffect(() => {\n if (showCamera) checkPermissions();\n }, [showCamera, refreshCamera]);\n\n useEffect(() => {\n const subscription = AppState.addEventListener('change', nextAppState => {\n if (nextAppState === 'active' && showCamera && hasPermission === false) {\n checkPermissions();\n }\n });\n return () => subscription.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\n try {\n isCapturingRef.current = true;\n const photo = await camera.current.takePhoto({\n enableShutterSound: false,\n flash: 'off',\n });\n \n const result = await VisionCameraModule.processPhotoResult(photo);\n\n onSilentCapture?.({\n ...result,\n path: result.path || photo.path,\n });\n } catch (error) {\n // Silent background fail\n } finally {\n isCapturingRef.current = false;\n }\n }, [isInitialized, onSilentCapture, silentCaptureResult]);\n\n useEffect(() => {\n if (!showCamera || !isInitialized || isProcessing) return;\n \n let isActive = true;\n let intervalId: ReturnType<typeof setInterval>;\n\n const warmupTimer = setTimeout(() => {\n if (!isActive) return;\n intervalId = setInterval(() => {\n captureSilentPhoto();\n }, 1500);\n }, 1000);\n\n return () => {\n isActive = false;\n clearTimeout(warmupTimer);\n if (intervalId) clearInterval(intervalId);\n };\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(prev => !prev)} 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 {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 +1 @@
1
- {"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAI5D,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAc5L,UAAU,cAAc;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAAE;AAC3F,UAAU,kBAAkB;IAAG,SAAS,EAAE,iBAAiB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAAE;AAExO,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA+atD,CAAC"}
1
+ {"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAI5D,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAc5L,UAAU,cAAc;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAAE;AAC3F,UAAU,kBAAkB;IAAG,SAAS,EAAE,iBAAiB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAAC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAAE;AAExO,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyftD,CAAC"}