react-native-biometric-verifier 0.0.1 → 0.0.3
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/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {
|
|
2
|
+
StyleSheet,
|
|
3
|
+
Dimensions,
|
|
4
|
+
View,
|
|
5
|
+
Modal,
|
|
6
|
+
} from "react-native";
|
|
7
|
+
import { normalize } from "react-native-elements";
|
|
8
|
+
import FastImage from "react-native-fast-image";
|
|
9
|
+
|
|
10
|
+
export default function Loader({ visible = true,source }) {
|
|
11
|
+
return (
|
|
12
|
+
<Modal
|
|
13
|
+
animationType="none"
|
|
14
|
+
transparent={true}
|
|
15
|
+
visible={visible}
|
|
16
|
+
onRequestClose={() => {}}
|
|
17
|
+
>
|
|
18
|
+
<View style={styles.container}>
|
|
19
|
+
<View style={styles.loaderBox}>
|
|
20
|
+
<FastImage
|
|
21
|
+
style={styles.icon}
|
|
22
|
+
source={source}
|
|
23
|
+
/>
|
|
24
|
+
</View>
|
|
25
|
+
</View>
|
|
26
|
+
</Modal>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const { width, height } = Dimensions.get("window");
|
|
31
|
+
|
|
32
|
+
const styles = StyleSheet.create({
|
|
33
|
+
container: {
|
|
34
|
+
justifyContent: "center",
|
|
35
|
+
alignItems: "center",
|
|
36
|
+
height,
|
|
37
|
+
width,
|
|
38
|
+
backgroundColor: "rgba(0,0,0,0.3)", // semi-transparent backdrop
|
|
39
|
+
},
|
|
40
|
+
loaderBox: {
|
|
41
|
+
borderRadius: normalize(20),
|
|
42
|
+
padding: 10,
|
|
43
|
+
backgroundColor: "white",
|
|
44
|
+
borderWidth: 1,
|
|
45
|
+
borderColor: "lightblue",
|
|
46
|
+
elevation: 5, // shadow on Android
|
|
47
|
+
shadowColor: "#000", // shadow on iOS
|
|
48
|
+
shadowOpacity: 0.2,
|
|
49
|
+
shadowOffset: { width: 0, height: 2 },
|
|
50
|
+
shadowRadius: 4,
|
|
51
|
+
},
|
|
52
|
+
icon: {
|
|
53
|
+
height: normalize(70),
|
|
54
|
+
width: normalize(70),
|
|
55
|
+
justifyContent: "center",
|
|
56
|
+
alignItems: "center",
|
|
57
|
+
},
|
|
58
|
+
});
|
package/src/index.js
CHANGED
|
@@ -4,15 +4,12 @@ import {
|
|
|
4
4
|
TouchableOpacity,
|
|
5
5
|
Text,
|
|
6
6
|
Modal,
|
|
7
|
-
Dimensions,
|
|
8
7
|
} from 'react-native';
|
|
9
8
|
import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
10
|
-
|
|
11
9
|
import { useCountdown } from './hooks/useCountdown';
|
|
12
10
|
import { useGeolocation } from './hooks/useGeolocation';
|
|
13
11
|
import { useImageProcessing } from './hooks/useImageProcessing';
|
|
14
12
|
import { useNotifyMessage } from './hooks/useNotifyMessage';
|
|
15
|
-
import { createLogger } from './utils/logger';
|
|
16
13
|
import { getDistanceInMeters } from './utils/distanceCalculator';
|
|
17
14
|
import {
|
|
18
15
|
ANIMATION_STATES,
|
|
@@ -21,7 +18,7 @@ import {
|
|
|
21
18
|
MAX_DISTANCE_METERS,
|
|
22
19
|
RECOGNIZE_URL,
|
|
23
20
|
} from './utils/constants';
|
|
24
|
-
|
|
21
|
+
import Loader from './components/Loader';
|
|
25
22
|
import { CountdownTimer } from './components/CountdownTimer';
|
|
26
23
|
import { EmployeeCard } from './components/EmployeeCard';
|
|
27
24
|
import { Notification } from './components/Notification';
|
|
@@ -29,8 +26,9 @@ import { StateIndicator } from './components/StateIndicator';
|
|
|
29
26
|
import { styles } from './components/styles';
|
|
30
27
|
import { useNavigation } from '@react-navigation/native';
|
|
31
28
|
import networkServiceCall from './utils/NetworkServiceCall';
|
|
29
|
+
import { getLoaderGif } from './utils/getLoaderGif';
|
|
32
30
|
|
|
33
|
-
const BiometricVerificationModal = React.memo(({ data, callback }) => {
|
|
31
|
+
const BiometricVerificationModal = React.memo(({ data, qrscan = false, callback }) => {
|
|
34
32
|
const navigation = useNavigation();
|
|
35
33
|
|
|
36
34
|
const { countdown, startCountdown, resetCountdown } = useCountdown();
|
|
@@ -114,7 +112,18 @@ const BiometricVerificationModal = React.memo(({ data, callback }) => {
|
|
|
114
112
|
employeeData: response.data?.data,
|
|
115
113
|
animationState: ANIMATION_STATES.SUCCESS,
|
|
116
114
|
});
|
|
117
|
-
|
|
115
|
+
|
|
116
|
+
if (qrscan) {
|
|
117
|
+
// If QR scanning is required, continue with QR Scan
|
|
118
|
+
setTimeout(() => startQRCodeScan(), 1500);
|
|
119
|
+
} else {
|
|
120
|
+
// If only Face recognition → finish process
|
|
121
|
+
setTimeout(() => {
|
|
122
|
+
callback?.(dataRef.current);
|
|
123
|
+
updateState({ modalVisible: false });
|
|
124
|
+
resetState();
|
|
125
|
+
}, 1500);
|
|
126
|
+
}
|
|
118
127
|
} else {
|
|
119
128
|
updateState({ animationState: ANIMATION_STATES.ERROR });
|
|
120
129
|
notifyMessage(response.data?.error?.message || 'Face not recognized. Please try again.', 'error');
|
|
@@ -125,7 +134,7 @@ const BiometricVerificationModal = React.memo(({ data, callback }) => {
|
|
|
125
134
|
} finally {
|
|
126
135
|
updateState({ isLoading: false });
|
|
127
136
|
}
|
|
128
|
-
}, [convertImageToBase64, notifyMessage,
|
|
137
|
+
}, [convertImageToBase64, notifyMessage, qrscan, resetState, updateState, callback]);
|
|
129
138
|
|
|
130
139
|
const handleStartFaceScan = useCallback(() => {
|
|
131
140
|
updateState({
|
|
@@ -150,7 +159,7 @@ const BiometricVerificationModal = React.memo(({ data, callback }) => {
|
|
|
150
159
|
cameramoduletype: 2,
|
|
151
160
|
onSelect: handleQRScanned,
|
|
152
161
|
});
|
|
153
|
-
}, [navigation, updateState
|
|
162
|
+
}, [navigation, updateState]);
|
|
154
163
|
|
|
155
164
|
const handleQRScanned = useCallback(async (qrCodeData) => {
|
|
156
165
|
updateState({
|
|
@@ -275,9 +284,13 @@ const BiometricVerificationModal = React.memo(({ data, callback }) => {
|
|
|
275
284
|
duration={COUNTDOWN_DURATION}
|
|
276
285
|
currentTime={countdown}
|
|
277
286
|
/>
|
|
287
|
+
|
|
288
|
+
{state.isLoading && getLoaderGif(state.animationState, state.currentStep) && (
|
|
289
|
+
<Loader source={getLoaderGif(state.animationState, state.currentStep)} />
|
|
290
|
+
)}
|
|
278
291
|
</View>
|
|
279
292
|
</Modal>
|
|
280
293
|
);
|
|
281
294
|
});
|
|
282
295
|
|
|
283
|
-
export default BiometricVerificationModal;
|
|
296
|
+
export default BiometricVerificationModal;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import FaceGif from '../Asset/gif/Face.gif';
|
|
2
|
+
import LocationGif from '../Asset/gif/Location.gif';
|
|
3
|
+
import { ANIMATION_STATES } from '../utils/constants';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Decides which GIF should be shown based on animationState or currentStep
|
|
7
|
+
* @param {string} animationState - Current animation state
|
|
8
|
+
* @param {string} currentStep - Current step of verification
|
|
9
|
+
* @returns {any} - Gif image source or null
|
|
10
|
+
*/
|
|
11
|
+
export const getLoaderGif = (animationState, currentStep) => {
|
|
12
|
+
if (
|
|
13
|
+
animationState === ANIMATION_STATES.FACE_SCAN ||
|
|
14
|
+
currentStep === 'Identity Verification'
|
|
15
|
+
) {
|
|
16
|
+
return FaceGif;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (
|
|
20
|
+
animationState === ANIMATION_STATES.QR_SCAN ||
|
|
21
|
+
currentStep === 'Location Verification'
|
|
22
|
+
) {
|
|
23
|
+
return LocationGif;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
};
|