omnipay-reactnative-sdk 1.2.2-beta.9 → 1.2.3-beta.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/README.md +43 -93
- package/android/build.gradle +0 -9
- package/android/src/main/AndroidManifest.xml +0 -5
- package/android/src/main/java/com/omniretail/omnipay/OmnipayActivityPackage.java +1 -4
- package/lib/commonjs/components/OmnipayProvider.js +1 -1
- package/lib/commonjs/components/biometrics/FaceVerification.js +235 -275
- package/lib/commonjs/components/biometrics/FaceVerification.js.map +1 -1
- package/lib/commonjs/index.js +0 -33
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/components/OmnipayProvider.js +1 -1
- package/lib/module/components/biometrics/FaceVerification.js +237 -277
- package/lib/module/components/biometrics/FaceVerification.js.map +1 -1
- package/lib/module/index.js +0 -6
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/components/biometrics/FaceVerification.d.ts +1 -3
- package/lib/typescript/components/biometrics/FaceVerification.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +0 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/package.json +4 -16
- package/src/components/OmnipayProvider.tsx +1 -1
- package/src/components/biometrics/FaceVerification.tsx +232 -317
- package/src/index.tsx +0 -7
- package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessCameraView.java +0 -153
- package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessCameraViewManager.java +0 -49
- package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessModule.java +0 -557
- package/ios/OmnipayLivenessCameraView.h +0 -15
- package/ios/OmnipayLivenessCameraView.m +0 -80
- package/ios/OmnipayLivenessCameraViewManager.m +0 -19
- package/ios/OmnipayLivenessModule.h +0 -38
- package/ios/OmnipayLivenessModule.m +0 -615
- package/lib/commonjs/components/biometrics/LivenessDetection.js +0 -149
- package/lib/commonjs/components/biometrics/LivenessDetection.js.map +0 -1
- package/lib/commonjs/components/biometrics/OmnipayLivenessCameraView.js +0 -15
- package/lib/commonjs/components/biometrics/OmnipayLivenessCameraView.js.map +0 -1
- package/lib/commonjs/components/biometrics/PermissionManager.js +0 -279
- package/lib/commonjs/components/biometrics/PermissionManager.js.map +0 -1
- package/lib/commonjs/components/biometrics/index.js +0 -45
- package/lib/commonjs/components/biometrics/index.js.map +0 -1
- package/lib/commonjs/components/biometrics/types.js +0 -17
- package/lib/commonjs/components/biometrics/types.js.map +0 -1
- package/lib/module/components/biometrics/LivenessDetection.js +0 -129
- package/lib/module/components/biometrics/LivenessDetection.js.map +0 -1
- package/lib/module/components/biometrics/OmnipayLivenessCameraView.js +0 -7
- package/lib/module/components/biometrics/OmnipayLivenessCameraView.js.map +0 -1
- package/lib/module/components/biometrics/PermissionManager.js +0 -272
- package/lib/module/components/biometrics/PermissionManager.js.map +0 -1
- package/lib/module/components/biometrics/index.js +0 -12
- package/lib/module/components/biometrics/index.js.map +0 -1
- package/lib/module/components/biometrics/types.js +0 -16
- package/lib/module/components/biometrics/types.js.map +0 -1
- package/lib/typescript/components/biometrics/LivenessDetection.d.ts +0 -33
- package/lib/typescript/components/biometrics/LivenessDetection.d.ts.map +0 -1
- package/lib/typescript/components/biometrics/OmnipayLivenessCameraView.d.ts +0 -18
- package/lib/typescript/components/biometrics/OmnipayLivenessCameraView.d.ts.map +0 -1
- package/lib/typescript/components/biometrics/PermissionManager.d.ts +0 -58
- package/lib/typescript/components/biometrics/PermissionManager.d.ts.map +0 -1
- package/lib/typescript/components/biometrics/index.d.ts +0 -5
- package/lib/typescript/components/biometrics/index.d.ts.map +0 -1
- package/lib/typescript/components/biometrics/types.d.ts +0 -73
- package/lib/typescript/components/biometrics/types.d.ts.map +0 -1
- package/omnipay-reactnative-sdk.podspec +0 -50
- package/src/components/biometrics/LivenessDetection.ts +0 -178
- package/src/components/biometrics/OmnipayLivenessCameraView.tsx +0 -19
- package/src/components/biometrics/PermissionManager.ts +0 -317
- package/src/components/biometrics/index.ts +0 -11
- package/src/components/biometrics/types.ts +0 -86
|
@@ -1,211 +1,98 @@
|
|
|
1
|
-
import React, { useState
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
View,
|
|
4
4
|
Modal,
|
|
5
5
|
Dimensions,
|
|
6
|
+
Platform,
|
|
6
7
|
StyleSheet,
|
|
7
8
|
TouchableOpacity,
|
|
8
9
|
Image,
|
|
9
10
|
Text,
|
|
10
11
|
ActivityIndicator,
|
|
11
12
|
} from 'react-native';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
import {
|
|
14
|
+
Camera,
|
|
15
|
+
useCameraDevice,
|
|
16
|
+
useCameraPermission,
|
|
17
|
+
} from 'react-native-vision-camera';
|
|
16
18
|
|
|
17
19
|
type FaceVerificationProps = {
|
|
18
20
|
onClose: () => void;
|
|
19
|
-
onSuccess: (
|
|
21
|
+
onSuccess: () => void;
|
|
20
22
|
primaryColor: string;
|
|
21
|
-
config?: Partial<LivenessConfig>;
|
|
22
23
|
};
|
|
23
24
|
|
|
24
|
-
type DetectionState =
|
|
25
|
-
| 'initializing'
|
|
26
|
-
| 'starting'
|
|
27
|
-
| 'running'
|
|
28
|
-
| 'completed'
|
|
29
|
-
| 'failed';
|
|
30
|
-
|
|
31
25
|
const FaceVerification: React.FC<FaceVerificationProps> = ({
|
|
32
26
|
onClose,
|
|
33
27
|
onSuccess,
|
|
34
28
|
primaryColor,
|
|
35
|
-
config,
|
|
36
29
|
}) => {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const [
|
|
40
|
-
const [currentChallenge, setCurrentChallenge] =
|
|
41
|
-
useState<LivenessChallenge | null>(null);
|
|
42
|
-
const [challengeProgress, setChallengeProgress] = useState<string>('');
|
|
43
|
-
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
checkSupport();
|
|
46
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
47
|
-
}, []);
|
|
30
|
+
const device = useCameraDevice('front');
|
|
31
|
+
const { hasPermission, requestPermission } = useCameraPermission();
|
|
32
|
+
const [isRequestingPermission, setIsRequestingPermission] = useState(false);
|
|
48
33
|
|
|
49
|
-
const
|
|
34
|
+
const handleRequestPermission = async () => {
|
|
35
|
+
setIsRequestingPermission(true);
|
|
50
36
|
try {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
await CameraPermissionManager.requestCameraPermission();
|
|
57
|
-
|
|
58
|
-
if (permissionResponse.result !== PermissionResult.GRANTED) {
|
|
59
|
-
console.log('❌ Camera permission denied:', permissionResponse.result);
|
|
60
|
-
setState('failed');
|
|
61
|
-
setError(
|
|
62
|
-
permissionResponse.result === PermissionResult.BLOCKED
|
|
63
|
-
? 'Camera permission is blocked. Please enable it in device settings.'
|
|
64
|
-
: 'Camera permission is required for face verification.'
|
|
65
|
-
);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
console.log('✅ Camera permission granted');
|
|
70
|
-
|
|
71
|
-
// Step 2: Check device support (hardware/framework capability)
|
|
72
|
-
console.log('🔍 Checking device capabilities...');
|
|
73
|
-
const supported = await LivenessDetection.isSupported();
|
|
74
|
-
console.log('📱 Device support result:', supported);
|
|
75
|
-
|
|
76
|
-
setIsSupported(supported);
|
|
77
|
-
if (supported) {
|
|
78
|
-
console.log('✅ Device supports liveness detection, starting...');
|
|
79
|
-
await startDetection();
|
|
80
|
-
} else {
|
|
81
|
-
console.log('❌ Device does not support liveness detection');
|
|
82
|
-
setState('failed');
|
|
83
|
-
setError('Liveness detection is not supported on this device');
|
|
84
|
-
}
|
|
85
|
-
} catch (err) {
|
|
86
|
-
console.error('💥 Error during initialization:', err);
|
|
87
|
-
setState('failed');
|
|
88
|
-
setError('Failed to initialize liveness detection');
|
|
37
|
+
await requestPermission();
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error('Error requesting camera permission:', error);
|
|
40
|
+
} finally {
|
|
41
|
+
setIsRequestingPermission(false);
|
|
89
42
|
}
|
|
90
43
|
};
|
|
91
44
|
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
onChallengeSuccess: (challenge, _challengeResult) => {
|
|
116
|
-
setChallengeProgress(
|
|
117
|
-
`✓ ${getChallengeInstruction(challenge)} completed`
|
|
118
|
-
);
|
|
119
|
-
},
|
|
120
|
-
onChallengeFailure: (challenge, reason) => {
|
|
121
|
-
setError(`Failed: ${reason}, ${challenge}`);
|
|
122
|
-
},
|
|
123
|
-
onAllChallengesComplete: () => {
|
|
124
|
-
setChallengeProgress(
|
|
125
|
-
'All challenges completed! Taking final photo...'
|
|
126
|
-
);
|
|
127
|
-
},
|
|
128
|
-
onScreenshotCaptured: (_screenshot) => {
|
|
129
|
-
// Screenshot captured, detection will complete soon
|
|
130
|
-
},
|
|
131
|
-
onDetectionFailed: (reason) => {
|
|
132
|
-
setError(reason);
|
|
133
|
-
setState('failed');
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
if (result.success) {
|
|
138
|
-
setState('completed');
|
|
139
|
-
setTimeout(() => {
|
|
140
|
-
onSuccess(result);
|
|
141
|
-
}, 1000); // Brief delay to show success state
|
|
142
|
-
} else {
|
|
143
|
-
setState('failed');
|
|
144
|
-
setError(result.failureReason || 'Face verification failed');
|
|
145
|
-
}
|
|
146
|
-
} catch (err) {
|
|
147
|
-
setState('failed');
|
|
148
|
-
setError(err instanceof Error ? err.message : 'Unknown error occurred');
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const getChallengeInstruction = (challenge: LivenessChallenge): string => {
|
|
153
|
-
switch (challenge) {
|
|
154
|
-
case LivenessChallenge.SMILE:
|
|
155
|
-
return 'Please smile';
|
|
156
|
-
case LivenessChallenge.BLINK:
|
|
157
|
-
return 'Please blink';
|
|
158
|
-
case LivenessChallenge.TURN_LEFT:
|
|
159
|
-
return 'Please turn your head left';
|
|
160
|
-
case LivenessChallenge.TURN_RIGHT:
|
|
161
|
-
return 'Please turn your head right';
|
|
162
|
-
default:
|
|
163
|
-
return 'Follow the instruction';
|
|
164
|
-
}
|
|
165
|
-
};
|
|
45
|
+
const renderPermissionRequest = () => (
|
|
46
|
+
<View style={styles.permissionContainer}>
|
|
47
|
+
<View style={styles.permissionIconContainer}>
|
|
48
|
+
<Text style={styles.permissionIcon}>📷</Text>
|
|
49
|
+
</View>
|
|
50
|
+
<Text style={styles.permissionTitle}>Camera Permission Required</Text>
|
|
51
|
+
<Text style={styles.permissionDescription}>
|
|
52
|
+
To verify your identity, we need access to your camera. This allows us
|
|
53
|
+
to capture your face for secure verification.
|
|
54
|
+
</Text>
|
|
55
|
+
<TouchableOpacity
|
|
56
|
+
style={[styles.permissionButton, { backgroundColor: primaryColor }]}
|
|
57
|
+
onPress={handleRequestPermission}
|
|
58
|
+
disabled={isRequestingPermission}
|
|
59
|
+
>
|
|
60
|
+
{isRequestingPermission ? (
|
|
61
|
+
<ActivityIndicator color="white" size="small" />
|
|
62
|
+
) : (
|
|
63
|
+
<Text style={styles.permissionButtonText}>Allow Camera Access</Text>
|
|
64
|
+
)}
|
|
65
|
+
</TouchableOpacity>
|
|
66
|
+
</View>
|
|
67
|
+
);
|
|
166
68
|
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return 'Face verification completed!';
|
|
177
|
-
case 'failed':
|
|
178
|
-
return error || 'Face verification failed';
|
|
179
|
-
default:
|
|
180
|
-
return 'Please wait...';
|
|
181
|
-
}
|
|
182
|
-
};
|
|
69
|
+
const renderNoDevice = () => (
|
|
70
|
+
<View style={styles.errorContainer}>
|
|
71
|
+
<Text style={styles.errorTitle}>Camera Not Available</Text>
|
|
72
|
+
<Text style={styles.errorSubtitle}>
|
|
73
|
+
No front camera detected on this device. Face verification requires a
|
|
74
|
+
front-facing camera.
|
|
75
|
+
</Text>
|
|
76
|
+
</View>
|
|
77
|
+
);
|
|
183
78
|
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
case 'completed':
|
|
187
|
-
return '#4CAF50';
|
|
188
|
-
case 'failed':
|
|
189
|
-
return '#F44336';
|
|
190
|
-
case 'running':
|
|
191
|
-
return primaryColor;
|
|
192
|
-
default:
|
|
193
|
-
return '#666';
|
|
194
|
-
}
|
|
195
|
-
};
|
|
79
|
+
const renderCamera = () => {
|
|
80
|
+
if (!device) return null;
|
|
196
81
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
82
|
+
return (
|
|
83
|
+
<View style={styles.cameraContainer}>
|
|
84
|
+
<Camera device={device} style={styles.camera} isActive={true} />
|
|
85
|
+
<View style={styles.cameraOverlay}>
|
|
86
|
+
<View style={styles.faceFrame} />
|
|
87
|
+
<Text style={styles.instructionText}>
|
|
88
|
+
Position your face within the frame
|
|
89
|
+
</Text>
|
|
90
|
+
</View>
|
|
91
|
+
</View>
|
|
92
|
+
);
|
|
203
93
|
};
|
|
204
94
|
|
|
205
|
-
|
|
206
|
-
state === 'failed' &&
|
|
207
|
-
error !==
|
|
208
|
-
'Camera permission is blocked. Please enable it in device settings.';
|
|
95
|
+
console.log(onSuccess, primaryColor);
|
|
209
96
|
|
|
210
97
|
return (
|
|
211
98
|
<Modal
|
|
@@ -217,7 +104,7 @@ const FaceVerification: React.FC<FaceVerificationProps> = ({
|
|
|
217
104
|
<TouchableOpacity
|
|
218
105
|
style={styles.backdrop}
|
|
219
106
|
activeOpacity={1}
|
|
220
|
-
onPress={
|
|
107
|
+
onPress={onClose}
|
|
221
108
|
>
|
|
222
109
|
<View style={[styles.container]}>
|
|
223
110
|
<TouchableOpacity style={styles.close} onPress={onClose}>
|
|
@@ -226,61 +113,10 @@ const FaceVerification: React.FC<FaceVerificationProps> = ({
|
|
|
226
113
|
style={styles.closeIcon}
|
|
227
114
|
/>
|
|
228
115
|
</TouchableOpacity>
|
|
229
|
-
|
|
230
116
|
<View style={styles.contentContainer}>
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
{
|
|
234
|
-
<View style={styles.cameraContainer}>
|
|
235
|
-
{state === 'running' && isSupported ? (
|
|
236
|
-
<OmnipayLivenessCameraView style={styles.camera} />
|
|
237
|
-
) : (
|
|
238
|
-
<View style={[styles.camera, styles.cameraPlaceholder]}>
|
|
239
|
-
{state === 'initializing' || state === 'starting' ? (
|
|
240
|
-
<ActivityIndicator size="large" color={primaryColor} />
|
|
241
|
-
) : state === 'completed' ? (
|
|
242
|
-
<View style={styles.successIcon}>
|
|
243
|
-
<Text style={styles.successText}>✓</Text>
|
|
244
|
-
</View>
|
|
245
|
-
) : (
|
|
246
|
-
<View style={styles.errorIcon}>
|
|
247
|
-
<Text style={styles.errorText}>!</Text>
|
|
248
|
-
</View>
|
|
249
|
-
)}
|
|
250
|
-
</View>
|
|
251
|
-
)}
|
|
252
|
-
|
|
253
|
-
{/* Overlay with instructions */}
|
|
254
|
-
<View style={styles.overlay}>
|
|
255
|
-
<Text style={[styles.instruction, { color: getStateColor() }]}>
|
|
256
|
-
{getStateMessage()}
|
|
257
|
-
</Text>
|
|
258
|
-
</View>
|
|
259
|
-
</View>
|
|
260
|
-
|
|
261
|
-
{/* Progress indicator for challenges */}
|
|
262
|
-
{state === 'running' && currentChallenge && (
|
|
263
|
-
<View style={styles.progressContainer}>
|
|
264
|
-
<Text style={styles.challengeText}>
|
|
265
|
-
{getChallengeInstruction(currentChallenge)}
|
|
266
|
-
</Text>
|
|
267
|
-
</View>
|
|
268
|
-
)}
|
|
269
|
-
|
|
270
|
-
{/* Action buttons */}
|
|
271
|
-
<View style={styles.buttonContainer}>
|
|
272
|
-
{showRetryButton && (
|
|
273
|
-
<TouchableOpacity
|
|
274
|
-
style={[
|
|
275
|
-
styles.retryButton,
|
|
276
|
-
{ backgroundColor: primaryColor },
|
|
277
|
-
]}
|
|
278
|
-
onPress={handleRetry}
|
|
279
|
-
>
|
|
280
|
-
<Text style={styles.retryButtonText}>Try Again</Text>
|
|
281
|
-
</TouchableOpacity>
|
|
282
|
-
)}
|
|
283
|
-
</View>
|
|
117
|
+
{!hasPermission && renderPermissionRequest()}
|
|
118
|
+
{hasPermission && !device && renderNoDevice()}
|
|
119
|
+
{hasPermission && device && renderCamera()}
|
|
284
120
|
</View>
|
|
285
121
|
</View>
|
|
286
122
|
</TouchableOpacity>
|
|
@@ -288,136 +124,215 @@ const FaceVerification: React.FC<FaceVerificationProps> = ({
|
|
|
288
124
|
);
|
|
289
125
|
};
|
|
290
126
|
|
|
291
|
-
|
|
127
|
+
export default FaceVerification;
|
|
292
128
|
|
|
293
129
|
const styles = StyleSheet.create({
|
|
294
|
-
|
|
295
|
-
|
|
130
|
+
hide: {
|
|
131
|
+
display: 'none',
|
|
296
132
|
},
|
|
297
|
-
|
|
133
|
+
full: {
|
|
298
134
|
flex: 1,
|
|
299
|
-
|
|
300
|
-
|
|
135
|
+
width: '100%',
|
|
136
|
+
height: '100%',
|
|
137
|
+
},
|
|
138
|
+
webview: {
|
|
139
|
+
flex: 1,
|
|
140
|
+
width: '100%',
|
|
141
|
+
height: Dimensions.get('window').height - 40,
|
|
142
|
+
backgroundColor: 'white',
|
|
143
|
+
borderTopRightRadius: 20,
|
|
144
|
+
borderTopLeftRadius: 20,
|
|
145
|
+
paddingTop: 150,
|
|
146
|
+
},
|
|
147
|
+
webviewLoader: {
|
|
148
|
+
zIndex: 3,
|
|
149
|
+
backgroundColor: 'white',
|
|
301
150
|
alignItems: 'center',
|
|
151
|
+
justifyContent: 'center',
|
|
152
|
+
flex: 1,
|
|
153
|
+
width: '100%',
|
|
154
|
+
height: '100%',
|
|
155
|
+
position: 'absolute',
|
|
156
|
+
top: 0,
|
|
157
|
+
left: 0,
|
|
158
|
+
borderTopRightRadius: 20,
|
|
159
|
+
borderTopLeftRadius: 20,
|
|
160
|
+
},
|
|
161
|
+
backdrop: {
|
|
162
|
+
backgroundColor: 'rgba(0,0,0,0.3)',
|
|
163
|
+
flex: 1,
|
|
164
|
+
justifyContent: 'flex-end',
|
|
165
|
+
position: 'relative',
|
|
166
|
+
height: '100%',
|
|
302
167
|
},
|
|
303
168
|
container: {
|
|
304
|
-
width: screenWidth * 0.9,
|
|
305
|
-
maxHeight: screenHeight * 0.8,
|
|
306
169
|
backgroundColor: 'white',
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
170
|
+
borderTopRightRadius: 20,
|
|
171
|
+
borderTopLeftRadius: 20,
|
|
172
|
+
maxHeight: Dimensions.get('window').height - 120,
|
|
173
|
+
flex: 1,
|
|
174
|
+
position: 'relative',
|
|
175
|
+
...(Platform.OS === 'android' && { overflow: 'hidden' }),
|
|
176
|
+
},
|
|
177
|
+
modal: {
|
|
178
|
+
flex: 1,
|
|
179
|
+
backgroundColor: 'rgba(0,0,0,0.48)',
|
|
180
|
+
height: '100%',
|
|
181
|
+
width: '100%',
|
|
310
182
|
},
|
|
311
183
|
close: {
|
|
312
184
|
position: 'absolute',
|
|
313
|
-
top:
|
|
314
|
-
right:
|
|
315
|
-
|
|
316
|
-
|
|
185
|
+
top: 10,
|
|
186
|
+
right: 10,
|
|
187
|
+
backgroundColor: 'white',
|
|
188
|
+
height: 24,
|
|
189
|
+
width: 24,
|
|
190
|
+
borderRadius: 1000,
|
|
191
|
+
alignItems: 'center',
|
|
192
|
+
justifyContent: 'center',
|
|
193
|
+
zIndex: 2,
|
|
317
194
|
},
|
|
318
195
|
closeIcon: {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
tintColor: '#666',
|
|
196
|
+
height: 12,
|
|
197
|
+
width: 12,
|
|
322
198
|
},
|
|
323
199
|
contentContainer: {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
200
|
+
height: '100%',
|
|
201
|
+
position: 'relative',
|
|
202
|
+
borderTopRightRadius: 20,
|
|
203
|
+
borderTopLeftRadius: 20,
|
|
204
|
+
padding: 16,
|
|
327
205
|
},
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
color: '#333',
|
|
332
|
-
marginBottom: 20,
|
|
333
|
-
textAlign: 'center',
|
|
206
|
+
testContent: {
|
|
207
|
+
paddingTop: 30,
|
|
208
|
+
paddingLeft: 16,
|
|
334
209
|
},
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
210
|
+
testTwoContent: {
|
|
211
|
+
paddingTop: 10,
|
|
212
|
+
paddingLeft: 16,
|
|
213
|
+
},
|
|
214
|
+
errorSubtitle: {
|
|
215
|
+
textAlign: 'center',
|
|
216
|
+
fontSize: 14,
|
|
217
|
+
color: '#5e7079',
|
|
342
218
|
marginBottom: 20,
|
|
219
|
+
paddingHorizontal: 8,
|
|
220
|
+
marginTop: 14,
|
|
221
|
+
},
|
|
222
|
+
errorContainer: {
|
|
223
|
+
flex: 1,
|
|
224
|
+
justifyContent: 'center',
|
|
225
|
+
alignItems: 'center',
|
|
226
|
+
width: Dimensions.get('window').width,
|
|
227
|
+
height: Dimensions.get('window').height,
|
|
228
|
+
zIndex: 2,
|
|
229
|
+
backgroundColor: 'white',
|
|
230
|
+
},
|
|
231
|
+
retryButton: {
|
|
232
|
+
minWidth: 160,
|
|
233
|
+
marginHorizontal: 'auto',
|
|
234
|
+
},
|
|
235
|
+
button: {
|
|
236
|
+
borderRadius: 6,
|
|
237
|
+
paddingHorizontal: 12,
|
|
238
|
+
paddingVertical: 14,
|
|
239
|
+
borderWidth: 1,
|
|
240
|
+
alignItems: 'center',
|
|
241
|
+
justifyContent: 'center',
|
|
343
242
|
},
|
|
243
|
+
buttonText: { color: 'white', fontSize: 16, paddingHorizontal: 30 },
|
|
344
244
|
camera: {
|
|
345
245
|
flex: 1,
|
|
346
246
|
width: '100%',
|
|
347
|
-
height:
|
|
247
|
+
height: 400,
|
|
348
248
|
},
|
|
349
|
-
|
|
249
|
+
// Permission request styles
|
|
250
|
+
permissionContainer: {
|
|
251
|
+
flex: 1,
|
|
350
252
|
justifyContent: 'center',
|
|
351
253
|
alignItems: 'center',
|
|
352
|
-
|
|
254
|
+
paddingHorizontal: 24,
|
|
255
|
+
paddingVertical: 40,
|
|
353
256
|
},
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
padding: 15,
|
|
257
|
+
permissionIconContainer: {
|
|
258
|
+
width: 80,
|
|
259
|
+
height: 80,
|
|
260
|
+
borderRadius: 40,
|
|
261
|
+
backgroundColor: '#f0f0f0',
|
|
262
|
+
justifyContent: 'center',
|
|
361
263
|
alignItems: 'center',
|
|
264
|
+
marginBottom: 24,
|
|
362
265
|
},
|
|
363
|
-
|
|
364
|
-
fontSize:
|
|
365
|
-
fontWeight: '600',
|
|
366
|
-
textAlign: 'center',
|
|
367
|
-
color: 'white',
|
|
368
|
-
},
|
|
369
|
-
progressContainer: {
|
|
370
|
-
marginBottom: 20,
|
|
371
|
-
alignItems: 'center',
|
|
266
|
+
permissionIcon: {
|
|
267
|
+
fontSize: 40,
|
|
372
268
|
},
|
|
373
|
-
|
|
374
|
-
fontSize:
|
|
269
|
+
permissionTitle: {
|
|
270
|
+
fontSize: 20,
|
|
375
271
|
fontWeight: '600',
|
|
376
|
-
color: '#
|
|
272
|
+
color: '#1a1a1a',
|
|
377
273
|
textAlign: 'center',
|
|
274
|
+
marginBottom: 12,
|
|
378
275
|
},
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
276
|
+
permissionDescription: {
|
|
277
|
+
fontSize: 16,
|
|
278
|
+
color: '#666',
|
|
279
|
+
textAlign: 'center',
|
|
280
|
+
lineHeight: 22,
|
|
281
|
+
marginBottom: 32,
|
|
383
282
|
},
|
|
384
|
-
|
|
385
|
-
paddingHorizontal:
|
|
386
|
-
paddingVertical:
|
|
283
|
+
permissionButton: {
|
|
284
|
+
paddingHorizontal: 32,
|
|
285
|
+
paddingVertical: 16,
|
|
387
286
|
borderRadius: 8,
|
|
287
|
+
minWidth: 200,
|
|
388
288
|
alignItems: 'center',
|
|
289
|
+
justifyContent: 'center',
|
|
389
290
|
},
|
|
390
|
-
|
|
291
|
+
permissionButtonText: {
|
|
391
292
|
color: 'white',
|
|
392
293
|
fontSize: 16,
|
|
393
294
|
fontWeight: '600',
|
|
394
295
|
},
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
296
|
+
// Error styles
|
|
297
|
+
errorTitle: {
|
|
298
|
+
fontSize: 18,
|
|
299
|
+
fontWeight: '600',
|
|
300
|
+
color: '#1a1a1a',
|
|
301
|
+
textAlign: 'center',
|
|
302
|
+
marginBottom: 8,
|
|
402
303
|
},
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
304
|
+
// Camera styles
|
|
305
|
+
cameraContainer: {
|
|
306
|
+
flex: 1,
|
|
307
|
+
position: 'relative',
|
|
407
308
|
},
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
309
|
+
cameraOverlay: {
|
|
310
|
+
position: 'absolute',
|
|
311
|
+
top: 0,
|
|
312
|
+
left: 0,
|
|
313
|
+
right: 0,
|
|
314
|
+
bottom: 0,
|
|
413
315
|
justifyContent: 'center',
|
|
414
316
|
alignItems: 'center',
|
|
415
317
|
},
|
|
416
|
-
|
|
417
|
-
|
|
318
|
+
faceFrame: {
|
|
319
|
+
width: 200,
|
|
320
|
+
height: 250,
|
|
321
|
+
borderWidth: 3,
|
|
322
|
+
borderColor: 'white',
|
|
323
|
+
borderRadius: 100,
|
|
324
|
+
borderStyle: 'dashed',
|
|
325
|
+
backgroundColor: 'transparent',
|
|
326
|
+
},
|
|
327
|
+
instructionText: {
|
|
418
328
|
color: 'white',
|
|
419
|
-
|
|
329
|
+
fontSize: 16,
|
|
330
|
+
fontWeight: '500',
|
|
331
|
+
textAlign: 'center',
|
|
332
|
+
marginTop: 20,
|
|
333
|
+
backgroundColor: 'rgba(0,0,0,0.5)',
|
|
334
|
+
paddingHorizontal: 16,
|
|
335
|
+
paddingVertical: 8,
|
|
336
|
+
borderRadius: 20,
|
|
420
337
|
},
|
|
421
338
|
});
|
|
422
|
-
|
|
423
|
-
export default FaceVerification;
|
package/src/index.tsx
CHANGED
|
@@ -2,11 +2,4 @@ import Omnipay from './components/OmnipayView';
|
|
|
2
2
|
|
|
3
3
|
export { OmnipayProvider } from './components/OmnipayProvider';
|
|
4
4
|
export { useOmnipay } from './hooks/useOmnipay';
|
|
5
|
-
|
|
6
|
-
// Biometric components and utilities
|
|
7
|
-
export { FaceVerification, LivenessDetection } from './components/biometrics';
|
|
8
|
-
|
|
9
|
-
// Biometric types
|
|
10
|
-
export * from './components/biometrics/types';
|
|
11
|
-
|
|
12
5
|
export default Omnipay;
|