@hexar/biometric-identity-sdk-react-native 1.0.30 → 1.0.32
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 +63 -32
- package/dist/components/ValidationProgress.d.ts.map +1 -1
- package/dist/components/ValidationProgress.js +3 -91
- package/package.json +2 -2
- package/src/components/CameraCapture.tsx +67 -32
- package/src/components/ValidationProgress.tsx +3 -141
|
@@ -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;AAY3D,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,
|
|
1
|
+
{"version":3,"file":"CameraCapture.d.ts","sourceRoot":"","sources":["../../src/components/CameraCapture.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAsC,MAAM,OAAO,CAAC;AAY3D,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,CAgQtD,CAAC;AA0JF,eAAe,aAAa,CAAC"}
|
|
@@ -98,43 +98,74 @@ const CameraCapture = ({ mode, theme, language, onCapture, onCancel, }) => {
|
|
|
98
98
|
const photo = await cameraRef.current.takePhoto({
|
|
99
99
|
flash: 'off',
|
|
100
100
|
});
|
|
101
|
-
//
|
|
102
|
-
// Try to use react-native-fs if available, otherwise use file path
|
|
101
|
+
// Compress and convert photo file to base64
|
|
103
102
|
try {
|
|
104
|
-
// Try
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
// Try to use react-native-image-resizer for compression
|
|
104
|
+
let ImageResizer = null;
|
|
105
|
+
try {
|
|
106
|
+
ImageResizer = require('react-native-image-resizer').default;
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
biometric_identity_sdk_core_1.logger.warn('react-native-image-resizer not available, using direct conversion');
|
|
110
|
+
}
|
|
111
|
+
let processedPath = photo.path;
|
|
112
|
+
// Compress image if ImageResizer is available
|
|
113
|
+
if (ImageResizer) {
|
|
114
|
+
try {
|
|
115
|
+
const resizedImage = await ImageResizer.createResizedImage(photo.path, 1600, // maxWidth
|
|
116
|
+
1600, // maxHeight
|
|
117
|
+
'JPEG', 75, // quality (0-100)
|
|
118
|
+
0, // rotation
|
|
119
|
+
undefined, // outputPath
|
|
120
|
+
false, // keepMeta
|
|
121
|
+
{ mode: 'contain', onlyScaleDown: true });
|
|
122
|
+
processedPath = resizedImage.uri;
|
|
123
|
+
biometric_identity_sdk_core_1.logger.info('Image compressed:', { original: photo.path, compressed: processedPath });
|
|
124
|
+
}
|
|
125
|
+
catch (resizeError) {
|
|
126
|
+
biometric_identity_sdk_core_1.logger.warn('Image compression failed, using original:', resizeError);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Convert to base64
|
|
111
130
|
try {
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const reader = new FileReader();
|
|
118
|
-
reader.onloadend = () => {
|
|
119
|
-
const base64data = reader.result;
|
|
120
|
-
const base64 = base64data.includes(',')
|
|
121
|
-
? base64data.split(',')[1]
|
|
122
|
-
: base64data;
|
|
123
|
-
onCapture(base64);
|
|
124
|
-
setIsCapturing(false);
|
|
125
|
-
};
|
|
126
|
-
reader.onerror = () => {
|
|
127
|
-
throw new Error('Failed to read photo file');
|
|
128
|
-
};
|
|
129
|
-
reader.readAsDataURL(blob);
|
|
130
|
-
return; // Don't set isCapturing to false here, wait for reader
|
|
131
|
+
const RNFS = require('react-native-fs');
|
|
132
|
+
const base64 = await RNFS.readFile(processedPath.replace('file://', ''), 'base64');
|
|
133
|
+
const sizeKB = Math.round(base64.length / 1024);
|
|
134
|
+
biometric_identity_sdk_core_1.logger.info('Image converted to base64:', { sizeKB, path: processedPath });
|
|
135
|
+
onCapture(base64);
|
|
131
136
|
}
|
|
132
|
-
catch (
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
catch (fsError) {
|
|
138
|
+
// Fallback: try fetch method
|
|
139
|
+
try {
|
|
140
|
+
const fileUri = react_native_1.Platform.OS === 'android' ? `file://${processedPath}` : processedPath;
|
|
141
|
+
const response = await fetch(fileUri);
|
|
142
|
+
const blob = await response.blob();
|
|
143
|
+
const reader = new FileReader();
|
|
144
|
+
reader.onloadend = () => {
|
|
145
|
+
const base64data = reader.result;
|
|
146
|
+
const base64 = base64data.includes(',')
|
|
147
|
+
? base64data.split(',')[1]
|
|
148
|
+
: base64data;
|
|
149
|
+
onCapture(base64);
|
|
150
|
+
setIsCapturing(false);
|
|
151
|
+
};
|
|
152
|
+
reader.onerror = () => {
|
|
153
|
+
throw new Error('Failed to read photo file');
|
|
154
|
+
};
|
|
155
|
+
reader.readAsDataURL(blob);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
catch (fetchError) {
|
|
159
|
+
biometric_identity_sdk_core_1.logger.warn('Could not convert to base64, using file path:', processedPath);
|
|
160
|
+
onCapture(processedPath);
|
|
161
|
+
}
|
|
136
162
|
}
|
|
137
163
|
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
biometric_identity_sdk_core_1.logger.error('Error processing image:', error);
|
|
166
|
+
// Final fallback: pass file path
|
|
167
|
+
onCapture(photo.path);
|
|
168
|
+
}
|
|
138
169
|
setIsCapturing(false);
|
|
139
170
|
}
|
|
140
171
|
catch (error) {
|
|
@@ -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,
|
|
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,CAmChE,CAAC;AAgCF,eAAe,kBAAkB,CAAC"}
|
|
@@ -48,77 +48,14 @@ const ValidationProgress = ({ progress, theme, language = 'en', }) => {
|
|
|
48
48
|
}
|
|
49
49
|
}, [language]);
|
|
50
50
|
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
|
-
};
|
|
60
51
|
return (react_1.default.createElement(react_native_1.View, { style: styles.container },
|
|
61
52
|
react_1.default.createElement(react_native_1.View, { style: styles.content },
|
|
62
53
|
react_1.default.createElement(react_native_1.ActivityIndicator, { size: "large", color: theme?.primaryColor || '#6366F1' }),
|
|
63
54
|
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' }] },
|
|
65
|
-
react_1.default.createElement(react_native_1.
|
|
66
|
-
react_1.default.createElement(react_native_1.View, { style: styles.progressBar },
|
|
67
|
-
react_1.default.createElement(react_native_1.View, { style: [
|
|
68
|
-
styles.progressFill,
|
|
69
|
-
{
|
|
70
|
-
width: `${progress}%`,
|
|
71
|
-
backgroundColor: theme?.primaryColor || '#6366F1',
|
|
72
|
-
},
|
|
73
|
-
] })),
|
|
74
|
-
react_1.default.createElement(react_native_1.Text, { style: [styles.progressText, { color: theme?.textColor || '#000000' }] },
|
|
75
|
-
Math.round(progress),
|
|
76
|
-
"%")),
|
|
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...'))));
|
|
55
|
+
react_1.default.createElement(react_native_1.Text, { style: [styles.statusText, { color: theme?.secondaryTextColor || '#6B7280' }] }, strings.validation.validatingDocumentAndFace || 'Validando documento y rostro...'),
|
|
56
|
+
react_1.default.createElement(react_native_1.Text, { style: styles.bottomText }, strings.validation.almostDone || 'Esto puede tardar unos segundos...'))));
|
|
83
57
|
};
|
|
84
58
|
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
59
|
const styles = react_native_1.StyleSheet.create({
|
|
123
60
|
container: {
|
|
124
61
|
flex: 1,
|
|
@@ -141,36 +78,11 @@ const styles = react_native_1.StyleSheet.create({
|
|
|
141
78
|
marginBottom: 32,
|
|
142
79
|
textAlign: 'center',
|
|
143
80
|
},
|
|
144
|
-
progressBarContainer: {
|
|
145
|
-
width: '100%',
|
|
146
|
-
marginBottom: 32,
|
|
147
|
-
},
|
|
148
|
-
progressBar: {
|
|
149
|
-
width: '100%',
|
|
150
|
-
height: 8,
|
|
151
|
-
backgroundColor: '#E5E7EB',
|
|
152
|
-
borderRadius: 4,
|
|
153
|
-
overflow: 'hidden',
|
|
154
|
-
marginBottom: 8,
|
|
155
|
-
},
|
|
156
|
-
progressFill: {
|
|
157
|
-
height: '100%',
|
|
158
|
-
borderRadius: 4,
|
|
159
|
-
},
|
|
160
|
-
progressText: {
|
|
161
|
-
fontSize: 14,
|
|
162
|
-
fontWeight: '600',
|
|
163
|
-
textAlign: 'center',
|
|
164
|
-
},
|
|
165
|
-
stepsContainer: {
|
|
166
|
-
width: '100%',
|
|
167
|
-
marginTop: 24,
|
|
168
|
-
marginBottom: 32,
|
|
169
|
-
},
|
|
170
81
|
bottomText: {
|
|
171
82
|
fontSize: 14,
|
|
172
83
|
color: '#9CA3AF',
|
|
173
84
|
textAlign: 'center',
|
|
85
|
+
marginTop: 16,
|
|
174
86
|
},
|
|
175
87
|
});
|
|
176
88
|
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.32",
|
|
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",
|
|
@@ -97,41 +97,76 @@ export const CameraCapture: React.FC<CameraCaptureProps> = ({
|
|
|
97
97
|
flash: 'off',
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
//
|
|
101
|
-
// Try to use react-native-fs if available, otherwise use file path
|
|
100
|
+
// Compress and convert photo file to base64
|
|
102
101
|
try {
|
|
103
|
-
// Try
|
|
104
|
-
|
|
105
|
-
const base64 = await RNFS.readFile(photo.path, 'base64');
|
|
106
|
-
onCapture(base64);
|
|
107
|
-
} catch (fsError) {
|
|
108
|
-
// If react-native-fs is not available, try alternative method
|
|
102
|
+
// Try to use react-native-image-resizer for compression
|
|
103
|
+
let ImageResizer: any = null;
|
|
109
104
|
try {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const blob = await response.blob();
|
|
114
|
-
|
|
115
|
-
// Convert blob to base64 using a workaround
|
|
116
|
-
const reader = new FileReader();
|
|
117
|
-
reader.onloadend = () => {
|
|
118
|
-
const base64data = reader.result as string;
|
|
119
|
-
const base64 = base64data.includes(',')
|
|
120
|
-
? base64data.split(',')[1]
|
|
121
|
-
: base64data;
|
|
122
|
-
onCapture(base64);
|
|
123
|
-
setIsCapturing(false);
|
|
124
|
-
};
|
|
125
|
-
reader.onerror = () => {
|
|
126
|
-
throw new Error('Failed to read photo file');
|
|
127
|
-
};
|
|
128
|
-
reader.readAsDataURL(blob);
|
|
129
|
-
return; // Don't set isCapturing to false here, wait for reader
|
|
130
|
-
} catch (fetchError) {
|
|
131
|
-
// Final fallback: pass file path (SDK should handle file paths)
|
|
132
|
-
logger.warn('Could not convert to base64, using file path:', photo.path);
|
|
133
|
-
onCapture(photo.path);
|
|
105
|
+
ImageResizer = require('react-native-image-resizer').default;
|
|
106
|
+
} catch (e) {
|
|
107
|
+
logger.warn('react-native-image-resizer not available, using direct conversion');
|
|
134
108
|
}
|
|
109
|
+
|
|
110
|
+
let processedPath = photo.path;
|
|
111
|
+
|
|
112
|
+
// Compress image if ImageResizer is available
|
|
113
|
+
if (ImageResizer) {
|
|
114
|
+
try {
|
|
115
|
+
const resizedImage = await ImageResizer.createResizedImage(
|
|
116
|
+
photo.path,
|
|
117
|
+
1600, // maxWidth
|
|
118
|
+
1600, // maxHeight
|
|
119
|
+
'JPEG',
|
|
120
|
+
75, // quality (0-100)
|
|
121
|
+
0, // rotation
|
|
122
|
+
undefined, // outputPath
|
|
123
|
+
false, // keepMeta
|
|
124
|
+
{ mode: 'contain', onlyScaleDown: true }
|
|
125
|
+
);
|
|
126
|
+
processedPath = resizedImage.uri;
|
|
127
|
+
logger.info('Image compressed:', { original: photo.path, compressed: processedPath });
|
|
128
|
+
} catch (resizeError) {
|
|
129
|
+
logger.warn('Image compression failed, using original:', resizeError);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Convert to base64
|
|
134
|
+
try {
|
|
135
|
+
const RNFS = require('react-native-fs');
|
|
136
|
+
const base64 = await RNFS.readFile(processedPath.replace('file://', ''), 'base64');
|
|
137
|
+
const sizeKB = Math.round(base64.length / 1024);
|
|
138
|
+
logger.info('Image converted to base64:', { sizeKB, path: processedPath });
|
|
139
|
+
onCapture(base64);
|
|
140
|
+
} catch (fsError) {
|
|
141
|
+
// Fallback: try fetch method
|
|
142
|
+
try {
|
|
143
|
+
const fileUri = Platform.OS === 'android' ? `file://${processedPath}` : processedPath;
|
|
144
|
+
const response = await fetch(fileUri);
|
|
145
|
+
const blob = await response.blob();
|
|
146
|
+
|
|
147
|
+
const reader = new FileReader();
|
|
148
|
+
reader.onloadend = () => {
|
|
149
|
+
const base64data = reader.result as string;
|
|
150
|
+
const base64 = base64data.includes(',')
|
|
151
|
+
? base64data.split(',')[1]
|
|
152
|
+
: base64data;
|
|
153
|
+
onCapture(base64);
|
|
154
|
+
setIsCapturing(false);
|
|
155
|
+
};
|
|
156
|
+
reader.onerror = () => {
|
|
157
|
+
throw new Error('Failed to read photo file');
|
|
158
|
+
};
|
|
159
|
+
reader.readAsDataURL(blob);
|
|
160
|
+
return;
|
|
161
|
+
} catch (fetchError) {
|
|
162
|
+
logger.warn('Could not convert to base64, using file path:', processedPath);
|
|
163
|
+
onCapture(processedPath);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
logger.error('Error processing image:', error);
|
|
168
|
+
// Final fallback: pass file path
|
|
169
|
+
onCapture(photo.path);
|
|
135
170
|
}
|
|
136
171
|
|
|
137
172
|
setIsCapturing(false);
|
|
@@ -31,13 +31,6 @@ export const ValidationProgress: React.FC<ValidationProgressProps> = ({
|
|
|
31
31
|
|
|
32
32
|
const strings = getStrings();
|
|
33
33
|
|
|
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
|
-
};
|
|
40
|
-
|
|
41
34
|
return (
|
|
42
35
|
<View style={styles.container}>
|
|
43
36
|
<View style={styles.content}>
|
|
@@ -51,123 +44,17 @@ export const ValidationProgress: React.FC<ValidationProgressProps> = ({
|
|
|
51
44
|
</Text>
|
|
52
45
|
|
|
53
46
|
<Text style={[styles.statusText, { color: theme?.secondaryTextColor || '#6B7280' }]}>
|
|
54
|
-
{
|
|
47
|
+
{strings.validation.validatingDocumentAndFace || 'Validando documento y rostro...'}
|
|
55
48
|
</Text>
|
|
56
49
|
|
|
57
|
-
{/* Progress Bar */}
|
|
58
|
-
<View style={styles.progressBarContainer}>
|
|
59
|
-
<View style={styles.progressBar}>
|
|
60
|
-
<View
|
|
61
|
-
style={[
|
|
62
|
-
styles.progressFill,
|
|
63
|
-
{
|
|
64
|
-
width: `${progress}%`,
|
|
65
|
-
backgroundColor: theme?.primaryColor || '#6366F1',
|
|
66
|
-
},
|
|
67
|
-
]}
|
|
68
|
-
/>
|
|
69
|
-
</View>
|
|
70
|
-
<Text style={[styles.progressText, { color: theme?.textColor || '#000000' }]}>
|
|
71
|
-
{Math.round(progress)}%
|
|
72
|
-
</Text>
|
|
73
|
-
</View>
|
|
74
|
-
|
|
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
50
|
<Text style={styles.bottomText}>
|
|
104
|
-
{strings.validation.almostDone || '
|
|
51
|
+
{strings.validation.almostDone || 'Esto puede tardar unos segundos...'}
|
|
105
52
|
</Text>
|
|
106
53
|
</View>
|
|
107
54
|
</View>
|
|
108
55
|
);
|
|
109
56
|
};
|
|
110
57
|
|
|
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
58
|
const styles = StyleSheet.create({
|
|
172
59
|
container: {
|
|
173
60
|
flex: 1,
|
|
@@ -190,36 +77,11 @@ const styles = StyleSheet.create({
|
|
|
190
77
|
marginBottom: 32,
|
|
191
78
|
textAlign: 'center',
|
|
192
79
|
},
|
|
193
|
-
progressBarContainer: {
|
|
194
|
-
width: '100%',
|
|
195
|
-
marginBottom: 32,
|
|
196
|
-
},
|
|
197
|
-
progressBar: {
|
|
198
|
-
width: '100%',
|
|
199
|
-
height: 8,
|
|
200
|
-
backgroundColor: '#E5E7EB',
|
|
201
|
-
borderRadius: 4,
|
|
202
|
-
overflow: 'hidden',
|
|
203
|
-
marginBottom: 8,
|
|
204
|
-
},
|
|
205
|
-
progressFill: {
|
|
206
|
-
height: '100%',
|
|
207
|
-
borderRadius: 4,
|
|
208
|
-
},
|
|
209
|
-
progressText: {
|
|
210
|
-
fontSize: 14,
|
|
211
|
-
fontWeight: '600',
|
|
212
|
-
textAlign: 'center',
|
|
213
|
-
},
|
|
214
|
-
stepsContainer: {
|
|
215
|
-
width: '100%',
|
|
216
|
-
marginTop: 24,
|
|
217
|
-
marginBottom: 32,
|
|
218
|
-
},
|
|
219
80
|
bottomText: {
|
|
220
81
|
fontSize: 14,
|
|
221
82
|
color: '#9CA3AF',
|
|
222
83
|
textAlign: 'center',
|
|
84
|
+
marginTop: 16,
|
|
223
85
|
},
|
|
224
86
|
});
|
|
225
87
|
|