@hexar/biometric-identity-sdk-react-native 1.12.0 → 1.14.0
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.
- package/dist/components/CameraCapture.d.ts.map +1 -1
- package/dist/components/CameraCapture.js +16 -0
- package/dist/components/VideoRecorder.d.ts.map +1 -1
- package/dist/components/VideoRecorder.js +18 -0
- package/package.json +1 -1
- package/src/components/CameraCapture.tsx +26 -2
- package/src/components/VideoRecorder.tsx +26 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CameraCapture.d.ts","sourceRoot":"","sources":["../../src/components/CameraCapture.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAsC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"CameraCapture.d.ts","sourceRoot":"","sources":["../../src/components/CameraCapture.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAsC,MAAM,OAAO,CAAC;AAa3D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAmC,MAAM,oCAAoC,CAAC;AAIrH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAqQtD,CAAC;AA0JF,eAAe,aAAa,CAAC"}
|
|
@@ -55,9 +55,19 @@ const CameraCapture = ({ mode, theme, language, onCapture, onCancel, }) => {
|
|
|
55
55
|
const strings = (0, biometric_identity_sdk_core_1.getStrings)();
|
|
56
56
|
// Get camera device (back camera for document capture)
|
|
57
57
|
const device = (0, react_native_vision_camera_1.useCameraDevice)('back');
|
|
58
|
+
const [deviceReady, setDeviceReady] = (0, react_1.useState)(!!device);
|
|
58
59
|
(0, react_1.useEffect)(() => {
|
|
59
60
|
checkPermissions();
|
|
60
61
|
}, []);
|
|
62
|
+
// Wait for camera device to become available
|
|
63
|
+
(0, react_1.useEffect)(() => {
|
|
64
|
+
if (device) {
|
|
65
|
+
setDeviceReady(true);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const timeout = setTimeout(() => setDeviceReady(true), 5000);
|
|
69
|
+
return () => clearTimeout(timeout);
|
|
70
|
+
}, [device]);
|
|
61
71
|
const checkPermissions = async () => {
|
|
62
72
|
try {
|
|
63
73
|
// First check if we already have permission from the hook
|
|
@@ -172,6 +182,12 @@ const CameraCapture = ({ mode, theme, language, onCapture, onCancel, }) => {
|
|
|
172
182
|
react_1.default.createElement(react_native_1.Text, { style: styles.buttonText }, strings.common.cancel || 'Cancel')))));
|
|
173
183
|
}
|
|
174
184
|
if (!device) {
|
|
185
|
+
if (!deviceReady) {
|
|
186
|
+
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
|
|
187
|
+
react_1.default.createElement(react_native_1.View, { style: styles.permissionContainer },
|
|
188
|
+
react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: theme?.primaryColor || '#6366F1' }),
|
|
189
|
+
react_1.default.createElement(react_native_1.Text, { style: [styles.permissionText, { marginTop: 16 }] }, strings.liveness.preparing || 'Preparing camera...'))));
|
|
190
|
+
}
|
|
175
191
|
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
|
|
176
192
|
react_1.default.createElement(react_native_1.View, { style: styles.permissionContainer },
|
|
177
193
|
react_1.default.createElement(react_native_1.Text, { style: styles.permissionText }, strings.errors.cameraNotAvailable || 'Camera not available'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../src/components/VideoRecorder.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../src/components/VideoRecorder.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAcxE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,EAAmC,MAAM,oCAAoC,CAAC;AAE1I,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,iCAAiC;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2CD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAw6BtD,CAAC;AA6OF,eAAe,aAAa,CAAC"}
|
|
@@ -103,6 +103,7 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
103
103
|
const cameraRef = (0, react_1.useRef)(null);
|
|
104
104
|
const { hasPermission: cameraPermission, requestPermission } = (0, react_native_vision_camera_1.useCameraPermission)();
|
|
105
105
|
const device = (0, react_native_vision_camera_1.useCameraDevice)('front');
|
|
106
|
+
const [deviceReady, setDeviceReady] = (0, react_1.useState)(!!device);
|
|
106
107
|
const fadeAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
|
|
107
108
|
const scaleAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
|
|
108
109
|
const pulseAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current;
|
|
@@ -144,6 +145,16 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
144
145
|
};
|
|
145
146
|
checkPermissions();
|
|
146
147
|
}, [cameraPermission, requestPermission]);
|
|
148
|
+
// Wait for camera device to become available (some Android OEMs
|
|
149
|
+
// take a few hundred ms to enumerate cameras after permission grant).
|
|
150
|
+
(0, react_1.useEffect)(() => {
|
|
151
|
+
if (device) {
|
|
152
|
+
setDeviceReady(true);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const timeout = setTimeout(() => setDeviceReady(true), 5000);
|
|
156
|
+
return () => clearTimeout(timeout);
|
|
157
|
+
}, [device]);
|
|
147
158
|
(0, react_1.useEffect)(() => {
|
|
148
159
|
const initChallenges = async () => {
|
|
149
160
|
try {
|
|
@@ -687,6 +698,13 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
687
698
|
react_1.default.createElement(react_native_1.Text, { style: [styles.cancelButtonText, { color: theme?.errorColor || '#EF4444' }] }, strings.common.cancel || 'Cancel')))));
|
|
688
699
|
}
|
|
689
700
|
if (!device) {
|
|
701
|
+
// Still waiting for camera to enumerate — show loading instead of error
|
|
702
|
+
if (!deviceReady) {
|
|
703
|
+
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
|
|
704
|
+
react_1.default.createElement(react_native_1.View, { style: styles.permissionContainer },
|
|
705
|
+
react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: theme?.primaryColor || '#6366F1' }),
|
|
706
|
+
react_1.default.createElement(react_native_1.Text, { style: [styles.permissionText, { marginTop: 16 }] }, strings.liveness.preparing || 'Preparing camera...'))));
|
|
707
|
+
}
|
|
690
708
|
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
|
|
691
709
|
react_1.default.createElement(react_native_1.View, { style: styles.permissionContainer },
|
|
692
710
|
react_1.default.createElement(react_native_1.Text, { style: styles.permissionText }, strings.errors.cameraNotAvailable || 'Camera not available'),
|
package/package.json
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
Dimensions,
|
|
13
13
|
Platform,
|
|
14
14
|
Alert,
|
|
15
|
+
ActivityIndicator,
|
|
15
16
|
} from 'react-native';
|
|
16
17
|
import { Camera, useCameraDevice, useCameraPermission } from 'react-native-vision-camera';
|
|
17
18
|
import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';
|
|
@@ -38,19 +39,30 @@ export const CameraCapture: React.FC<CameraCaptureProps> = ({
|
|
|
38
39
|
const [hasPermission, setHasPermission] = useState(false);
|
|
39
40
|
const cameraRef = useRef<Camera>(null);
|
|
40
41
|
const { hasPermission: cameraPermission, requestPermission } = useCameraPermission();
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
if (language) {
|
|
43
44
|
setLanguage(language);
|
|
44
45
|
}
|
|
45
46
|
const strings = getStrings();
|
|
46
|
-
|
|
47
|
+
|
|
47
48
|
// Get camera device (back camera for document capture)
|
|
48
49
|
const device = useCameraDevice('back');
|
|
50
|
+
const [deviceReady, setDeviceReady] = useState(!!device);
|
|
49
51
|
|
|
50
52
|
useEffect(() => {
|
|
51
53
|
checkPermissions();
|
|
52
54
|
}, []);
|
|
53
55
|
|
|
56
|
+
// Wait for camera device to become available
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (device) {
|
|
59
|
+
setDeviceReady(true);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const timeout = setTimeout(() => setDeviceReady(true), 5000);
|
|
63
|
+
return () => clearTimeout(timeout);
|
|
64
|
+
}, [device]);
|
|
65
|
+
|
|
54
66
|
const checkPermissions = async () => {
|
|
55
67
|
try {
|
|
56
68
|
// First check if we already have permission from the hook
|
|
@@ -190,6 +202,18 @@ export const CameraCapture: React.FC<CameraCaptureProps> = ({
|
|
|
190
202
|
}
|
|
191
203
|
|
|
192
204
|
if (!device) {
|
|
205
|
+
if (!deviceReady) {
|
|
206
|
+
return (
|
|
207
|
+
<View style={styles.container}>
|
|
208
|
+
<View style={styles.permissionContainer}>
|
|
209
|
+
<ActivityIndicator size="large" color={theme?.primaryColor || '#6366F1'} />
|
|
210
|
+
<Text style={[styles.permissionText, { marginTop: 16 }]}>
|
|
211
|
+
{strings.liveness.preparing || 'Preparing camera...'}
|
|
212
|
+
</Text>
|
|
213
|
+
</View>
|
|
214
|
+
</View>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
193
217
|
return (
|
|
194
218
|
<View style={styles.container}>
|
|
195
219
|
<View style={styles.permissionContainer}>
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
Easing,
|
|
14
14
|
Platform,
|
|
15
15
|
Alert,
|
|
16
|
+
ActivityIndicator,
|
|
16
17
|
} from 'react-native';
|
|
17
18
|
import { Camera, useCameraDevice, useCameraPermission } from 'react-native-vision-camera';
|
|
18
19
|
import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';
|
|
@@ -127,10 +128,10 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
127
128
|
const [frames, setFrames] = useState<string[]>([]);
|
|
128
129
|
const framesRef = useRef<string[]>([]);
|
|
129
130
|
const [hasPermission, setHasPermission] = useState(false);
|
|
130
|
-
|
|
131
131
|
const cameraRef = useRef<Camera>(null);
|
|
132
132
|
const { hasPermission: cameraPermission, requestPermission } = useCameraPermission();
|
|
133
133
|
const device = useCameraDevice('front');
|
|
134
|
+
const [deviceReady, setDeviceReady] = useState(!!device);
|
|
134
135
|
|
|
135
136
|
const fadeAnim = useRef(new Animated.Value(0)).current;
|
|
136
137
|
const scaleAnim = useRef(new Animated.Value(1)).current;
|
|
@@ -183,6 +184,17 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
183
184
|
checkPermissions();
|
|
184
185
|
}, [cameraPermission, requestPermission]);
|
|
185
186
|
|
|
187
|
+
// Wait for camera device to become available (some Android OEMs
|
|
188
|
+
// take a few hundred ms to enumerate cameras after permission grant).
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
if (device) {
|
|
191
|
+
setDeviceReady(true);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const timeout = setTimeout(() => setDeviceReady(true), 5000);
|
|
195
|
+
return () => clearTimeout(timeout);
|
|
196
|
+
}, [device]);
|
|
197
|
+
|
|
186
198
|
useEffect(() => {
|
|
187
199
|
const initChallenges = async () => {
|
|
188
200
|
try {
|
|
@@ -824,6 +836,19 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
824
836
|
}
|
|
825
837
|
|
|
826
838
|
if (!device) {
|
|
839
|
+
// Still waiting for camera to enumerate — show loading instead of error
|
|
840
|
+
if (!deviceReady) {
|
|
841
|
+
return (
|
|
842
|
+
<View style={styles.container}>
|
|
843
|
+
<View style={styles.permissionContainer}>
|
|
844
|
+
<ActivityIndicator size="large" color={theme?.primaryColor || '#6366F1'} />
|
|
845
|
+
<Text style={[styles.permissionText, { marginTop: 16 }]}>
|
|
846
|
+
{strings.liveness.preparing || 'Preparing camera...'}
|
|
847
|
+
</Text>
|
|
848
|
+
</View>
|
|
849
|
+
</View>
|
|
850
|
+
);
|
|
851
|
+
}
|
|
827
852
|
return (
|
|
828
853
|
<View style={styles.container}>
|
|
829
854
|
<View style={styles.permissionContainer}>
|