@hexar/biometric-identity-sdk-react-native 1.0.31 → 1.0.33
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValidationProgress.d.ts","sourceRoot":"","sources":["../../src/components/ValidationProgress.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"ValidationProgress.d.ts","sourceRoot":"","sources":["../../src/components/ValidationProgress.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAA2B,MAAM,oCAAoC,CAAC;AAE7G,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA8GhE,CAAC;AAqDF,eAAe,kBAAkB,CAAC"}
|
|
@@ -42,83 +42,84 @@ const react_1 = __importStar(require("react"));
|
|
|
42
42
|
const react_native_1 = require("react-native");
|
|
43
43
|
const biometric_identity_sdk_core_1 = require("@hexar/biometric-identity-sdk-core");
|
|
44
44
|
const ValidationProgress = ({ progress, theme, language = 'en', }) => {
|
|
45
|
+
const animatedProgress = (0, react_1.useRef)(new react_native_1.Animated.Value(0)).current;
|
|
46
|
+
const [displayProgress, setDisplayProgress] = (0, react_1.useState)(0);
|
|
47
|
+
const animationRef = (0, react_1.useRef)(null);
|
|
45
48
|
(0, react_1.useEffect)(() => {
|
|
46
49
|
if (language) {
|
|
47
50
|
(0, biometric_identity_sdk_core_1.setLanguage)(language);
|
|
48
51
|
}
|
|
49
52
|
}, [language]);
|
|
53
|
+
(0, react_1.useEffect)(() => {
|
|
54
|
+
// Start animation from 0 to 90% over 60 seconds (1 minute)
|
|
55
|
+
if (progress < 90) {
|
|
56
|
+
// If we have real progress from backend, use it; otherwise animate to 90% over 60s
|
|
57
|
+
if (progress > 0 && progress < 90) {
|
|
58
|
+
// Use actual progress
|
|
59
|
+
react_native_1.Animated.timing(animatedProgress, {
|
|
60
|
+
toValue: progress,
|
|
61
|
+
duration: 500,
|
|
62
|
+
useNativeDriver: false,
|
|
63
|
+
}).start();
|
|
64
|
+
}
|
|
65
|
+
else if (progress === 0) {
|
|
66
|
+
// Start animation to 90% over 60 seconds
|
|
67
|
+
if (animationRef.current) {
|
|
68
|
+
animationRef.current.stop();
|
|
69
|
+
}
|
|
70
|
+
animationRef.current = react_native_1.Animated.timing(animatedProgress, {
|
|
71
|
+
toValue: 90,
|
|
72
|
+
duration: 60000, // 60 seconds
|
|
73
|
+
useNativeDriver: false,
|
|
74
|
+
});
|
|
75
|
+
animationRef.current.start();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// If progress is 90% or more, animate to actual progress
|
|
80
|
+
react_native_1.Animated.timing(animatedProgress, {
|
|
81
|
+
toValue: progress,
|
|
82
|
+
duration: 500,
|
|
83
|
+
useNativeDriver: false,
|
|
84
|
+
}).start();
|
|
85
|
+
}
|
|
86
|
+
// Update display value
|
|
87
|
+
const listener = animatedProgress.addListener(({ value }) => {
|
|
88
|
+
setDisplayProgress(Math.round(value));
|
|
89
|
+
});
|
|
90
|
+
return () => {
|
|
91
|
+
animatedProgress.removeListener(listener);
|
|
92
|
+
if (animationRef.current) {
|
|
93
|
+
animationRef.current.stop();
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}, [progress, animatedProgress]);
|
|
50
97
|
const strings = (0, biometric_identity_sdk_core_1.getStrings)();
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (progress < 95)
|
|
57
|
-
return strings.validation.matchingFaces || 'Comparing faces...';
|
|
58
|
-
return strings.validation.almostDone || 'Validating document authenticity...';
|
|
59
|
-
};
|
|
98
|
+
const progressWidth = animatedProgress.interpolate({
|
|
99
|
+
inputRange: [0, 100],
|
|
100
|
+
outputRange: ['0%', '100%'],
|
|
101
|
+
extrapolate: 'clamp',
|
|
102
|
+
});
|
|
60
103
|
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
|
|
61
104
|
react_1.default.createElement(react_native_1.View, { style: styles.content },
|
|
62
105
|
react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: theme?.primaryColor || '#6366F1' }),
|
|
63
106
|
react_1.default.createElement(react_native_1.Text, { style: [styles.title, { color: theme?.textColor || '#000000' }] }, strings.validation.title || 'Validating Identity'),
|
|
64
|
-
react_1.default.createElement(react_native_1.Text, { style: [styles.statusText, { color: theme?.secondaryTextColor || '#6B7280' }] },
|
|
107
|
+
react_1.default.createElement(react_native_1.Text, { style: [styles.statusText, { color: theme?.secondaryTextColor || '#6B7280' }] }, strings.validation.validatingDocumentAndFace || 'Validando documento y rostro...'),
|
|
65
108
|
react_1.default.createElement(react_native_1.View, { style: styles.progressBarContainer },
|
|
66
109
|
react_1.default.createElement(react_native_1.View, { style: styles.progressBar },
|
|
67
|
-
react_1.default.createElement(react_native_1.View, { style: [
|
|
110
|
+
react_1.default.createElement(react_native_1.Animated.View, { style: [
|
|
68
111
|
styles.progressFill,
|
|
69
112
|
{
|
|
70
|
-
width:
|
|
113
|
+
width: progressWidth,
|
|
71
114
|
backgroundColor: theme?.primaryColor || '#6366F1',
|
|
72
115
|
},
|
|
73
116
|
] })),
|
|
74
117
|
react_1.default.createElement(react_native_1.Text, { style: [styles.progressText, { color: theme?.textColor || '#000000' }] },
|
|
75
|
-
|
|
118
|
+
displayProgress,
|
|
76
119
|
"%")),
|
|
77
|
-
react_1.default.createElement(react_native_1.
|
|
78
|
-
react_1.default.createElement(ValidationStep, { icon: "\u2713", text: strings.validation.checkingDocument || 'OCR Extraction', completed: progress >= 80, theme: theme }),
|
|
79
|
-
react_1.default.createElement(ValidationStep, { icon: "\u2713", text: strings.validation.checkingLiveness || 'Liveness Detection', completed: progress >= 85, theme: theme }),
|
|
80
|
-
react_1.default.createElement(ValidationStep, { icon: "\u2713", text: strings.validation.matchingFaces || 'Face Matching', completed: progress >= 95, theme: theme }),
|
|
81
|
-
react_1.default.createElement(ValidationStep, { icon: "\u2713", text: strings.validation.checkingDocument || 'Document Validation', completed: progress >= 100, theme: theme })),
|
|
82
|
-
react_1.default.createElement(react_native_1.Text, { style: styles.bottomText }, strings.validation.almostDone || 'This may take a few seconds...'))));
|
|
120
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.bottomText }, strings.validation.almostDone || 'Esto puede tardar unos segundos...'))));
|
|
83
121
|
};
|
|
84
122
|
exports.ValidationProgress = ValidationProgress;
|
|
85
|
-
const ValidationStep = ({ icon, text, completed, theme, }) => (react_1.default.createElement(react_native_1.View, { style: stepStyles.container },
|
|
86
|
-
react_1.default.createElement(react_native_1.View, { style: [
|
|
87
|
-
stepStyles.iconContainer,
|
|
88
|
-
completed && {
|
|
89
|
-
backgroundColor: theme?.successColor || '#10B981',
|
|
90
|
-
},
|
|
91
|
-
] }, completed && react_1.default.createElement(react_native_1.Text, { style: stepStyles.icon }, icon)),
|
|
92
|
-
react_1.default.createElement(react_native_1.Text, { style: [stepStyles.text, completed && stepStyles.textCompleted] }, text)));
|
|
93
|
-
const stepStyles = react_native_1.StyleSheet.create({
|
|
94
|
-
container: {
|
|
95
|
-
flexDirection: 'row',
|
|
96
|
-
alignItems: 'center',
|
|
97
|
-
marginVertical: 8,
|
|
98
|
-
},
|
|
99
|
-
iconContainer: {
|
|
100
|
-
width: 24,
|
|
101
|
-
height: 24,
|
|
102
|
-
borderRadius: 12,
|
|
103
|
-
backgroundColor: '#E5E7EB',
|
|
104
|
-
justifyContent: 'center',
|
|
105
|
-
alignItems: 'center',
|
|
106
|
-
marginRight: 12,
|
|
107
|
-
},
|
|
108
|
-
icon: {
|
|
109
|
-
color: '#FFFFFF',
|
|
110
|
-
fontSize: 14,
|
|
111
|
-
fontWeight: 'bold',
|
|
112
|
-
},
|
|
113
|
-
text: {
|
|
114
|
-
fontSize: 14,
|
|
115
|
-
color: '#9CA3AF',
|
|
116
|
-
},
|
|
117
|
-
textCompleted: {
|
|
118
|
-
color: '#111827',
|
|
119
|
-
fontWeight: '500',
|
|
120
|
-
},
|
|
121
|
-
});
|
|
122
123
|
const styles = react_native_1.StyleSheet.create({
|
|
123
124
|
container: {
|
|
124
125
|
flex: 1,
|
|
@@ -143,7 +144,7 @@ const styles = react_native_1.StyleSheet.create({
|
|
|
143
144
|
},
|
|
144
145
|
progressBarContainer: {
|
|
145
146
|
width: '100%',
|
|
146
|
-
marginBottom:
|
|
147
|
+
marginBottom: 24,
|
|
147
148
|
},
|
|
148
149
|
progressBar: {
|
|
149
150
|
width: '100%',
|
|
@@ -162,15 +163,11 @@ const styles = react_native_1.StyleSheet.create({
|
|
|
162
163
|
fontWeight: '600',
|
|
163
164
|
textAlign: 'center',
|
|
164
165
|
},
|
|
165
|
-
stepsContainer: {
|
|
166
|
-
width: '100%',
|
|
167
|
-
marginTop: 24,
|
|
168
|
-
marginBottom: 32,
|
|
169
|
-
},
|
|
170
166
|
bottomText: {
|
|
171
167
|
fontSize: 14,
|
|
172
168
|
color: '#9CA3AF',
|
|
173
169
|
textAlign: 'center',
|
|
170
|
+
marginTop: 16,
|
|
174
171
|
},
|
|
175
172
|
});
|
|
176
173
|
exports.default = exports.ValidationProgress;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hexar/biometric-identity-sdk-react-native",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.33",
|
|
4
4
|
"description": "React Native wrapper for Biometric Identity SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"clean": "rm -rf dist"
|
|
12
12
|
},
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"@hexar/biometric-identity-sdk-core": ">=1.0.
|
|
14
|
+
"@hexar/biometric-identity-sdk-core": ">=1.0.21",
|
|
15
15
|
"react": ">=18.0.0",
|
|
16
16
|
"react-native": ">=0.70.0",
|
|
17
17
|
"react-native-permissions": ">=4.0.0",
|
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
* Shows AI validation progress
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React, { useEffect } from 'react';
|
|
6
|
+
import React, { useEffect, useRef, useState } from 'react';
|
|
7
7
|
import {
|
|
8
8
|
View,
|
|
9
9
|
Text,
|
|
10
10
|
StyleSheet,
|
|
11
11
|
ActivityIndicator,
|
|
12
|
+
Animated,
|
|
12
13
|
} from 'react-native';
|
|
13
14
|
import { ThemeConfig, SupportedLanguage, getStrings, setLanguage } from '@hexar/biometric-identity-sdk-core';
|
|
14
15
|
|
|
@@ -23,20 +24,70 @@ export const ValidationProgress: React.FC<ValidationProgressProps> = ({
|
|
|
23
24
|
theme,
|
|
24
25
|
language = 'en',
|
|
25
26
|
}) => {
|
|
27
|
+
const animatedProgress = useRef(new Animated.Value(0)).current;
|
|
28
|
+
const [displayProgress, setDisplayProgress] = useState(0);
|
|
29
|
+
const animationRef = useRef<Animated.CompositeAnimation | null>(null);
|
|
30
|
+
|
|
26
31
|
useEffect(() => {
|
|
27
32
|
if (language) {
|
|
28
33
|
setLanguage(language);
|
|
29
34
|
}
|
|
30
35
|
}, [language]);
|
|
31
36
|
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
// Start animation from 0 to 90% over 60 seconds (1 minute)
|
|
39
|
+
if (progress < 90) {
|
|
40
|
+
// If we have real progress from backend, use it; otherwise animate to 90% over 60s
|
|
41
|
+
if (progress > 0 && progress < 90) {
|
|
42
|
+
// Use actual progress
|
|
43
|
+
Animated.timing(animatedProgress, {
|
|
44
|
+
toValue: progress,
|
|
45
|
+
duration: 500,
|
|
46
|
+
useNativeDriver: false,
|
|
47
|
+
}).start();
|
|
48
|
+
} else if (progress === 0) {
|
|
49
|
+
// Start animation to 90% over 60 seconds
|
|
50
|
+
if (animationRef.current) {
|
|
51
|
+
animationRef.current.stop();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
animationRef.current = Animated.timing(animatedProgress, {
|
|
55
|
+
toValue: 90,
|
|
56
|
+
duration: 60000, // 60 seconds
|
|
57
|
+
useNativeDriver: false,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
animationRef.current.start();
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
// If progress is 90% or more, animate to actual progress
|
|
64
|
+
Animated.timing(animatedProgress, {
|
|
65
|
+
toValue: progress,
|
|
66
|
+
duration: 500,
|
|
67
|
+
useNativeDriver: false,
|
|
68
|
+
}).start();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Update display value
|
|
72
|
+
const listener = animatedProgress.addListener(({ value }) => {
|
|
73
|
+
setDisplayProgress(Math.round(value));
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return () => {
|
|
77
|
+
animatedProgress.removeListener(listener);
|
|
78
|
+
if (animationRef.current) {
|
|
79
|
+
animationRef.current.stop();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}, [progress, animatedProgress]);
|
|
83
|
+
|
|
32
84
|
const strings = getStrings();
|
|
33
85
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
};
|
|
86
|
+
const progressWidth = animatedProgress.interpolate({
|
|
87
|
+
inputRange: [0, 100],
|
|
88
|
+
outputRange: ['0%', '100%'],
|
|
89
|
+
extrapolate: 'clamp',
|
|
90
|
+
});
|
|
40
91
|
|
|
41
92
|
return (
|
|
42
93
|
<View style={styles.container}>
|
|
@@ -51,123 +102,35 @@ export const ValidationProgress: React.FC<ValidationProgressProps> = ({
|
|
|
51
102
|
</Text>
|
|
52
103
|
|
|
53
104
|
<Text style={[styles.statusText, { color: theme?.secondaryTextColor || '#6B7280' }]}>
|
|
54
|
-
{
|
|
105
|
+
{strings.validation.validatingDocumentAndFace || 'Validando documento y rostro...'}
|
|
55
106
|
</Text>
|
|
56
107
|
|
|
57
108
|
{/* Progress Bar */}
|
|
58
109
|
<View style={styles.progressBarContainer}>
|
|
59
110
|
<View style={styles.progressBar}>
|
|
60
|
-
<View
|
|
111
|
+
<Animated.View
|
|
61
112
|
style={[
|
|
62
113
|
styles.progressFill,
|
|
63
114
|
{
|
|
64
|
-
width:
|
|
115
|
+
width: progressWidth,
|
|
65
116
|
backgroundColor: theme?.primaryColor || '#6366F1',
|
|
66
117
|
},
|
|
67
118
|
]}
|
|
68
119
|
/>
|
|
69
120
|
</View>
|
|
70
121
|
<Text style={[styles.progressText, { color: theme?.textColor || '#000000' }]}>
|
|
71
|
-
{
|
|
122
|
+
{displayProgress}%
|
|
72
123
|
</Text>
|
|
73
124
|
</View>
|
|
74
125
|
|
|
75
|
-
{/* Validation Steps */}
|
|
76
|
-
<View style={styles.stepsContainer}>
|
|
77
|
-
<ValidationStep
|
|
78
|
-
icon="✓"
|
|
79
|
-
text={strings.validation.checkingDocument || 'OCR Extraction'}
|
|
80
|
-
completed={progress >= 80}
|
|
81
|
-
theme={theme}
|
|
82
|
-
/>
|
|
83
|
-
<ValidationStep
|
|
84
|
-
icon="✓"
|
|
85
|
-
text={strings.validation.checkingLiveness || 'Liveness Detection'}
|
|
86
|
-
completed={progress >= 85}
|
|
87
|
-
theme={theme}
|
|
88
|
-
/>
|
|
89
|
-
<ValidationStep
|
|
90
|
-
icon="✓"
|
|
91
|
-
text={strings.validation.matchingFaces || 'Face Matching'}
|
|
92
|
-
completed={progress >= 95}
|
|
93
|
-
theme={theme}
|
|
94
|
-
/>
|
|
95
|
-
<ValidationStep
|
|
96
|
-
icon="✓"
|
|
97
|
-
text={strings.validation.checkingDocument || 'Document Validation'}
|
|
98
|
-
completed={progress >= 100}
|
|
99
|
-
theme={theme}
|
|
100
|
-
/>
|
|
101
|
-
</View>
|
|
102
|
-
|
|
103
126
|
<Text style={styles.bottomText}>
|
|
104
|
-
{strings.validation.almostDone || '
|
|
127
|
+
{strings.validation.almostDone || 'Esto puede tardar unos segundos...'}
|
|
105
128
|
</Text>
|
|
106
129
|
</View>
|
|
107
130
|
</View>
|
|
108
131
|
);
|
|
109
132
|
};
|
|
110
133
|
|
|
111
|
-
interface ValidationStepProps {
|
|
112
|
-
icon: string;
|
|
113
|
-
text: string;
|
|
114
|
-
completed: boolean;
|
|
115
|
-
theme?: ThemeConfig;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const ValidationStep: React.FC<ValidationStepProps> = ({
|
|
119
|
-
icon,
|
|
120
|
-
text,
|
|
121
|
-
completed,
|
|
122
|
-
theme,
|
|
123
|
-
}) => (
|
|
124
|
-
<View style={stepStyles.container}>
|
|
125
|
-
<View
|
|
126
|
-
style={[
|
|
127
|
-
stepStyles.iconContainer,
|
|
128
|
-
completed && {
|
|
129
|
-
backgroundColor: theme?.successColor || '#10B981',
|
|
130
|
-
},
|
|
131
|
-
]}
|
|
132
|
-
>
|
|
133
|
-
{completed && <Text style={stepStyles.icon}>{icon}</Text>}
|
|
134
|
-
</View>
|
|
135
|
-
<Text style={[stepStyles.text, completed && stepStyles.textCompleted]}>
|
|
136
|
-
{text}
|
|
137
|
-
</Text>
|
|
138
|
-
</View>
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
const stepStyles = StyleSheet.create({
|
|
142
|
-
container: {
|
|
143
|
-
flexDirection: 'row',
|
|
144
|
-
alignItems: 'center',
|
|
145
|
-
marginVertical: 8,
|
|
146
|
-
},
|
|
147
|
-
iconContainer: {
|
|
148
|
-
width: 24,
|
|
149
|
-
height: 24,
|
|
150
|
-
borderRadius: 12,
|
|
151
|
-
backgroundColor: '#E5E7EB',
|
|
152
|
-
justifyContent: 'center',
|
|
153
|
-
alignItems: 'center',
|
|
154
|
-
marginRight: 12,
|
|
155
|
-
},
|
|
156
|
-
icon: {
|
|
157
|
-
color: '#FFFFFF',
|
|
158
|
-
fontSize: 14,
|
|
159
|
-
fontWeight: 'bold',
|
|
160
|
-
},
|
|
161
|
-
text: {
|
|
162
|
-
fontSize: 14,
|
|
163
|
-
color: '#9CA3AF',
|
|
164
|
-
},
|
|
165
|
-
textCompleted: {
|
|
166
|
-
color: '#111827',
|
|
167
|
-
fontWeight: '500',
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
|
|
171
134
|
const styles = StyleSheet.create({
|
|
172
135
|
container: {
|
|
173
136
|
flex: 1,
|
|
@@ -192,7 +155,7 @@ const styles = StyleSheet.create({
|
|
|
192
155
|
},
|
|
193
156
|
progressBarContainer: {
|
|
194
157
|
width: '100%',
|
|
195
|
-
marginBottom:
|
|
158
|
+
marginBottom: 24,
|
|
196
159
|
},
|
|
197
160
|
progressBar: {
|
|
198
161
|
width: '100%',
|
|
@@ -211,15 +174,11 @@ const styles = StyleSheet.create({
|
|
|
211
174
|
fontWeight: '600',
|
|
212
175
|
textAlign: 'center',
|
|
213
176
|
},
|
|
214
|
-
stepsContainer: {
|
|
215
|
-
width: '100%',
|
|
216
|
-
marginTop: 24,
|
|
217
|
-
marginBottom: 32,
|
|
218
|
-
},
|
|
219
177
|
bottomText: {
|
|
220
178
|
fontSize: 14,
|
|
221
179
|
color: '#9CA3AF',
|
|
222
180
|
textAlign: 'center',
|
|
181
|
+
marginTop: 16,
|
|
223
182
|
},
|
|
224
183
|
});
|
|
225
184
|
|