@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,KAAoB,MAAM,OAAO,CAAC;AAOzC,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,CAwFhE,CAAC;AAqHF,eAAe,kBAAkB,CAAC"}
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 getStatusText = () => {
52
- if (progress < 80)
53
- return strings.validation.checkingDocument || 'Extracting document data...';
54
- if (progress < 85)
55
- return strings.validation.checkingLiveness || 'Validating liveness...';
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' }] }, getStatusText()),
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: `${progress}%`,
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
- Math.round(progress),
118
+ displayProgress,
76
119
  "%")),
77
- react_1.default.createElement(react_native_1.View, { style: styles.stepsContainer },
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: 32,
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.31",
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.20",
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 getStatusText = () => {
35
- if (progress < 80) return strings.validation.checkingDocument || 'Extracting document data...';
36
- if (progress < 85) return strings.validation.checkingLiveness || 'Validating liveness...';
37
- if (progress < 95) return strings.validation.matchingFaces || 'Comparing faces...';
38
- return strings.validation.almostDone || 'Validating document authenticity...';
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
- {getStatusText()}
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: `${progress}%`,
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
- {Math.round(progress)}%
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 || 'This may take a few seconds...'}
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: 32,
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