omnipay-reactnative-sdk 1.2.2-beta.9 → 1.2.3-beta.10

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.
Files changed (97) hide show
  1. package/README.md +58 -48
  2. package/android/build.gradle +4 -7
  3. package/android/src/main/AndroidManifest.xml +0 -5
  4. package/android/src/main/java/com/omniretail/omnipay/FaceVerificationFrameProcessor.kt +111 -0
  5. package/android/src/main/java/com/omniretail/omnipay/OmnipayActivityPackage.java +6 -4
  6. package/ios/FaceVerificationFrameProcessor.swift +138 -0
  7. package/ios/FaceVerificationFrameProcessorPlugin.m +4 -0
  8. package/ios/OmnipayReactnativeSdk.m +5 -0
  9. package/ios/OmnipayReactnativeSdk.swift +10 -0
  10. package/ios/omnipay_reactnative_sdk.h +6 -0
  11. package/lib/commonjs/components/Button.js +68 -0
  12. package/lib/commonjs/components/Button.js.map +1 -0
  13. package/lib/commonjs/components/OmnipayProvider.js +7 -23
  14. package/lib/commonjs/components/OmnipayProvider.js.map +1 -1
  15. package/lib/commonjs/components/biometrics/FaceVerification.js +294 -270
  16. package/lib/commonjs/components/biometrics/FaceVerification.js.map +1 -1
  17. package/lib/commonjs/components/biometrics/useFaceVerification.js +85 -0
  18. package/lib/commonjs/components/biometrics/useFaceVerification.js.map +1 -0
  19. package/lib/commonjs/components/biometrics/useFaceVerificationFlow.js +157 -0
  20. package/lib/commonjs/components/biometrics/useFaceVerificationFlow.js.map +1 -0
  21. package/lib/commonjs/index.js +0 -33
  22. package/lib/commonjs/index.js.map +1 -1
  23. package/lib/module/components/Button.js +61 -0
  24. package/lib/module/components/Button.js.map +1 -0
  25. package/lib/module/components/OmnipayProvider.js +7 -23
  26. package/lib/module/components/OmnipayProvider.js.map +1 -1
  27. package/lib/module/components/biometrics/FaceVerification.js +294 -271
  28. package/lib/module/components/biometrics/FaceVerification.js.map +1 -1
  29. package/lib/module/components/biometrics/useFaceVerification.js +78 -0
  30. package/lib/module/components/biometrics/useFaceVerification.js.map +1 -0
  31. package/lib/module/components/biometrics/useFaceVerificationFlow.js +150 -0
  32. package/lib/module/components/biometrics/useFaceVerificationFlow.js.map +1 -0
  33. package/lib/module/index.js +0 -6
  34. package/lib/module/index.js.map +1 -1
  35. package/lib/typescript/components/Button.d.ts +17 -0
  36. package/lib/typescript/components/Button.d.ts.map +1 -0
  37. package/lib/typescript/components/OmnipayProvider.d.ts.map +1 -1
  38. package/lib/typescript/components/biometrics/FaceVerification.d.ts +1 -3
  39. package/lib/typescript/components/biometrics/FaceVerification.d.ts.map +1 -1
  40. package/lib/typescript/components/biometrics/useFaceVerification.d.ts +38 -0
  41. package/lib/typescript/components/biometrics/useFaceVerification.d.ts.map +1 -0
  42. package/lib/typescript/components/biometrics/useFaceVerificationFlow.d.ts +29 -0
  43. package/lib/typescript/components/biometrics/useFaceVerificationFlow.d.ts.map +1 -0
  44. package/lib/typescript/index.d.ts +0 -2
  45. package/lib/typescript/index.d.ts.map +1 -1
  46. package/omnipay_reactnative_sdk.podspec +46 -0
  47. package/package.json +5 -8
  48. package/src/components/Button.tsx +86 -0
  49. package/src/components/OmnipayProvider.tsx +7 -24
  50. package/src/components/biometrics/FaceVerification.tsx +315 -309
  51. package/src/components/biometrics/useFaceVerification.ts +120 -0
  52. package/src/components/biometrics/useFaceVerificationFlow.ts +224 -0
  53. package/src/index.tsx +0 -7
  54. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessCameraView.java +0 -153
  55. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessCameraViewManager.java +0 -49
  56. package/android/src/main/java/com/omniretail/omnipay/OmnipayLivenessModule.java +0 -557
  57. package/ios/OmnipayLivenessCameraView.h +0 -15
  58. package/ios/OmnipayLivenessCameraView.m +0 -80
  59. package/ios/OmnipayLivenessCameraViewManager.m +0 -19
  60. package/ios/OmnipayLivenessModule.h +0 -38
  61. package/ios/OmnipayLivenessModule.m +0 -615
  62. package/lib/commonjs/components/biometrics/LivenessDetection.js +0 -149
  63. package/lib/commonjs/components/biometrics/LivenessDetection.js.map +0 -1
  64. package/lib/commonjs/components/biometrics/OmnipayLivenessCameraView.js +0 -15
  65. package/lib/commonjs/components/biometrics/OmnipayLivenessCameraView.js.map +0 -1
  66. package/lib/commonjs/components/biometrics/PermissionManager.js +0 -279
  67. package/lib/commonjs/components/biometrics/PermissionManager.js.map +0 -1
  68. package/lib/commonjs/components/biometrics/index.js +0 -45
  69. package/lib/commonjs/components/biometrics/index.js.map +0 -1
  70. package/lib/commonjs/components/biometrics/types.js +0 -17
  71. package/lib/commonjs/components/biometrics/types.js.map +0 -1
  72. package/lib/module/components/biometrics/LivenessDetection.js +0 -129
  73. package/lib/module/components/biometrics/LivenessDetection.js.map +0 -1
  74. package/lib/module/components/biometrics/OmnipayLivenessCameraView.js +0 -7
  75. package/lib/module/components/biometrics/OmnipayLivenessCameraView.js.map +0 -1
  76. package/lib/module/components/biometrics/PermissionManager.js +0 -272
  77. package/lib/module/components/biometrics/PermissionManager.js.map +0 -1
  78. package/lib/module/components/biometrics/index.js +0 -12
  79. package/lib/module/components/biometrics/index.js.map +0 -1
  80. package/lib/module/components/biometrics/types.js +0 -16
  81. package/lib/module/components/biometrics/types.js.map +0 -1
  82. package/lib/typescript/components/biometrics/LivenessDetection.d.ts +0 -33
  83. package/lib/typescript/components/biometrics/LivenessDetection.d.ts.map +0 -1
  84. package/lib/typescript/components/biometrics/OmnipayLivenessCameraView.d.ts +0 -18
  85. package/lib/typescript/components/biometrics/OmnipayLivenessCameraView.d.ts.map +0 -1
  86. package/lib/typescript/components/biometrics/PermissionManager.d.ts +0 -58
  87. package/lib/typescript/components/biometrics/PermissionManager.d.ts.map +0 -1
  88. package/lib/typescript/components/biometrics/index.d.ts +0 -5
  89. package/lib/typescript/components/biometrics/index.d.ts.map +0 -1
  90. package/lib/typescript/components/biometrics/types.d.ts +0 -73
  91. package/lib/typescript/components/biometrics/types.d.ts.map +0 -1
  92. package/omnipay-reactnative-sdk.podspec +0 -50
  93. package/src/components/biometrics/LivenessDetection.ts +0 -178
  94. package/src/components/biometrics/OmnipayLivenessCameraView.tsx +0 -19
  95. package/src/components/biometrics/PermissionManager.ts +0 -317
  96. package/src/components/biometrics/index.ts +0 -11
  97. package/src/components/biometrics/types.ts +0 -86
@@ -0,0 +1,120 @@
1
+ import {
2
+ useFrameProcessor,
3
+ VisionCameraProxy,
4
+ } from 'react-native-vision-camera';
5
+
6
+ export interface FaceVerificationResult {
7
+ faceDetected: boolean;
8
+ isSmiling?: boolean;
9
+ isBlinking?: boolean;
10
+ leftEyeClosed?: boolean;
11
+ rightEyeClosed?: boolean;
12
+ headPose?: {
13
+ yaw: number; // Left-right movement (-90 to 90)
14
+ pitch: number; // Up-down movement (-90 to 90)
15
+ roll: number; // Tilt movement (-180 to 180)
16
+ };
17
+ boundingBox?: {
18
+ x?: number;
19
+ y?: number;
20
+ width?: number;
21
+ height?: number;
22
+ left?: number;
23
+ top?: number;
24
+ right?: number;
25
+ bottom?: number;
26
+ };
27
+ smileProbability?: number;
28
+ leftEyeOpenProbability?: number;
29
+ rightEyeOpenProbability?: number;
30
+ trackingId?: number;
31
+ error?: string;
32
+ }
33
+
34
+ // Note: For production use, you would typically use shared values or state management
35
+ // to communicate results from the worklet back to the React component.
36
+ // This simplified version just logs results for debugging.
37
+
38
+ // Initialize the plugin
39
+ const plugin = VisionCameraProxy.initFrameProcessorPlugin('detectFaces', {});
40
+
41
+ export const useFaceVerification = () => {
42
+ const frameProcessor = useFrameProcessor((frame) => {
43
+ 'worklet';
44
+
45
+ try {
46
+ if (plugin == null) {
47
+ console.error('Failed to load Frame Processor Plugin "detectFaces"!');
48
+ return null;
49
+ }
50
+
51
+ const result = plugin.call(frame, {}) as any;
52
+
53
+ // For debugging - this works in worklets
54
+ if (result && result.faceDetected) {
55
+ console.log('Face detected:', result);
56
+ }
57
+
58
+ return result;
59
+ } catch (error) {
60
+ console.error('Face verification error:', error);
61
+ return {
62
+ faceDetected: false,
63
+ error: error instanceof Error ? error.message : 'Unknown error',
64
+ };
65
+ }
66
+ }, []);
67
+
68
+ return frameProcessor;
69
+ };
70
+
71
+ // Utility functions for interpreting results
72
+ export const FaceVerificationUtils = {
73
+ // Check if head is turned left (yaw > 20 degrees)
74
+ isHeadTurnedLeft: (result: FaceVerificationResult): boolean => {
75
+ return result.headPose?.yaw ? result.headPose.yaw > 20 : false;
76
+ },
77
+
78
+ // Check if head is turned right (yaw < -20 degrees)
79
+ isHeadTurnedRight: (result: FaceVerificationResult): boolean => {
80
+ return result.headPose?.yaw ? result.headPose.yaw < -20 : false;
81
+ },
82
+
83
+ // Check if head is tilted up (pitch > 10 degrees)
84
+ isHeadTiltedUp: (result: FaceVerificationResult): boolean => {
85
+ return result.headPose?.pitch ? result.headPose.pitch > 10 : false;
86
+ },
87
+
88
+ // Check if head is tilted down (pitch < -10 degrees)
89
+ isHeadTiltedDown: (result: FaceVerificationResult): boolean => {
90
+ return result.headPose?.pitch ? result.headPose.pitch < -10 : false;
91
+ },
92
+
93
+ // Check if face is centered (within ±10 degrees)
94
+ isFaceCentered: (result: FaceVerificationResult): boolean => {
95
+ if (!result.headPose) return false;
96
+ const { yaw, pitch } = result.headPose;
97
+ return Math.abs(yaw) <= 10 && Math.abs(pitch) <= 10;
98
+ },
99
+
100
+ // Check if smile is confident (high probability)
101
+ isConfidentSmile: (result: FaceVerificationResult): boolean => {
102
+ return result.smileProbability
103
+ ? result.smileProbability > 0.8
104
+ : result.isSmiling || false;
105
+ },
106
+
107
+ // Check if both eyes are confidently closed
108
+ isConfidentBlink: (result: FaceVerificationResult): boolean => {
109
+ if (
110
+ result.leftEyeOpenProbability !== undefined &&
111
+ result.rightEyeOpenProbability !== undefined
112
+ ) {
113
+ return (
114
+ result.leftEyeOpenProbability < 0.2 &&
115
+ result.rightEyeOpenProbability < 0.2
116
+ );
117
+ }
118
+ return result.isBlinking || false;
119
+ },
120
+ };
@@ -0,0 +1,224 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+ import {
3
+ FaceVerificationResult,
4
+ FaceVerificationUtils,
5
+ } from './useFaceVerification';
6
+
7
+ export type VerificationStep =
8
+ | 'position_face'
9
+ | 'smile'
10
+ | 'blink'
11
+ | 'turn_left'
12
+ | 'turn_right'
13
+ | 'completed'
14
+ | 'failed';
15
+
16
+ export interface VerificationFlowState {
17
+ currentStep: VerificationStep;
18
+ completedSteps: VerificationStep[];
19
+ stepStartTime: number;
20
+ totalStartTime: number;
21
+ isProcessing: boolean;
22
+ progress: number;
23
+ instruction: string;
24
+ error?: string;
25
+ }
26
+
27
+ export interface VerificationFlowConfig {
28
+ stepTimeout: number; // Maximum time per step (ms)
29
+ totalTimeout: number; // Maximum total time (ms)
30
+ confirmationFrames: number; // Frames needed to confirm action
31
+ requiredSteps: VerificationStep[]; // Steps to complete
32
+ }
33
+
34
+ const DEFAULT_CONFIG: VerificationFlowConfig = {
35
+ stepTimeout: 10000, // 10 seconds per step
36
+ totalTimeout: 60000, // 1 minute total
37
+ confirmationFrames: 5, // 5 consecutive frames
38
+ requiredSteps: ['position_face', 'smile', 'blink', 'turn_left', 'turn_right'],
39
+ };
40
+
41
+ const STEP_INSTRUCTIONS: Record<VerificationStep, string> = {
42
+ position_face: 'Position your face in the center of the frame',
43
+ smile: 'Please smile for the camera',
44
+ blink: 'Please blink your eyes',
45
+ turn_left: 'Slowly turn your head to the left',
46
+ turn_right: 'Slowly turn your head to the right',
47
+ completed: 'Verification completed successfully!',
48
+ failed: 'Verification failed. Please try again.',
49
+ };
50
+
51
+ export const useFaceVerificationFlow = (
52
+ config: Partial<VerificationFlowConfig> = {}
53
+ ) => {
54
+ const fullConfig = { ...DEFAULT_CONFIG, ...config };
55
+
56
+ const [state, setState] = useState<VerificationFlowState>({
57
+ currentStep: 'position_face',
58
+ completedSteps: [],
59
+ stepStartTime: Date.now(),
60
+ totalStartTime: Date.now(),
61
+ isProcessing: false,
62
+ progress: 0,
63
+ instruction: STEP_INSTRUCTIONS.position_face,
64
+ });
65
+
66
+ const [confirmationCount, setConfirmationCount] = useState(0);
67
+
68
+ // Reset verification flow
69
+ const resetFlow = useCallback(() => {
70
+ const now = Date.now();
71
+ setState({
72
+ currentStep: 'position_face',
73
+ completedSteps: [],
74
+ stepStartTime: now,
75
+ totalStartTime: now,
76
+ isProcessing: false,
77
+ progress: 0,
78
+ instruction: STEP_INSTRUCTIONS.position_face,
79
+ });
80
+ setConfirmationCount(0);
81
+ }, []);
82
+
83
+ // Check if current step is completed based on face detection result
84
+ const checkStepCompletion = useCallback(
85
+ (result: FaceVerificationResult): boolean => {
86
+ if (!result.faceDetected) return false;
87
+
88
+ switch (state.currentStep) {
89
+ case 'position_face':
90
+ return FaceVerificationUtils.isFaceCentered(result);
91
+
92
+ case 'smile':
93
+ return FaceVerificationUtils.isConfidentSmile(result);
94
+
95
+ case 'blink':
96
+ return FaceVerificationUtils.isConfidentBlink(result);
97
+
98
+ case 'turn_left':
99
+ return FaceVerificationUtils.isHeadTurnedLeft(result);
100
+
101
+ case 'turn_right':
102
+ return FaceVerificationUtils.isHeadTurnedRight(result);
103
+
104
+ default:
105
+ return false;
106
+ }
107
+ },
108
+ [state.currentStep]
109
+ );
110
+
111
+ // Get next step in sequence
112
+ const getNextStep = useCallback(
113
+ (currentStep: VerificationStep): VerificationStep => {
114
+ const currentIndex = fullConfig.requiredSteps.indexOf(currentStep);
115
+ if (
116
+ currentIndex === -1 ||
117
+ currentIndex === fullConfig.requiredSteps.length - 1
118
+ ) {
119
+ return 'completed';
120
+ }
121
+ const nextStep = fullConfig.requiredSteps[currentIndex + 1];
122
+ return nextStep || 'completed';
123
+ },
124
+ [fullConfig.requiredSteps]
125
+ );
126
+
127
+ // Process face detection result
128
+ const processFaceResult = useCallback(
129
+ (result: FaceVerificationResult) => {
130
+ if (state.currentStep === 'completed' || state.currentStep === 'failed') {
131
+ return;
132
+ }
133
+
134
+ const now = Date.now();
135
+
136
+ // Check for timeouts
137
+ if (now - state.totalStartTime > fullConfig.totalTimeout) {
138
+ setState((prev) => ({
139
+ ...prev,
140
+ currentStep: 'failed',
141
+ instruction: 'Verification timed out. Please try again.',
142
+ error: 'Total verification timeout exceeded',
143
+ }));
144
+ return;
145
+ }
146
+
147
+ if (now - state.stepStartTime > fullConfig.stepTimeout) {
148
+ setState((prev) => ({
149
+ ...prev,
150
+ currentStep: 'failed',
151
+ instruction: 'Step timed out. Please try again.',
152
+ error: 'Step timeout exceeded',
153
+ }));
154
+ return;
155
+ }
156
+
157
+ // Check if current step is completed
158
+ const stepCompleted = checkStepCompletion(result);
159
+
160
+ if (stepCompleted) {
161
+ setConfirmationCount((prev) => prev + 1);
162
+
163
+ // Require multiple consecutive confirmations
164
+ if (confirmationCount + 1 >= fullConfig.confirmationFrames) {
165
+ const nextStep = getNextStep(state.currentStep);
166
+ const newCompletedSteps = [
167
+ ...state.completedSteps,
168
+ state.currentStep,
169
+ ];
170
+ const newProgress =
171
+ (newCompletedSteps.length / fullConfig.requiredSteps.length) * 100;
172
+
173
+ setState((prev) => ({
174
+ ...prev,
175
+ currentStep: nextStep,
176
+ completedSteps: newCompletedSteps,
177
+ stepStartTime: now,
178
+ progress: newProgress,
179
+ instruction: STEP_INSTRUCTIONS[nextStep],
180
+ isProcessing: nextStep === 'completed',
181
+ }));
182
+
183
+ setConfirmationCount(0);
184
+ }
185
+ } else {
186
+ // Reset confirmation count if step not completed
187
+ setConfirmationCount(0);
188
+ }
189
+ },
190
+ [
191
+ state,
192
+ fullConfig.totalTimeout,
193
+ fullConfig.stepTimeout,
194
+ fullConfig.confirmationFrames,
195
+ fullConfig.requiredSteps.length,
196
+ confirmationCount,
197
+ checkStepCompletion,
198
+ getNextStep,
199
+ ]
200
+ );
201
+
202
+ // Auto-reset on mount
203
+ useEffect(() => {
204
+ resetFlow();
205
+ }, [resetFlow]);
206
+
207
+ return {
208
+ state,
209
+ processFaceResult,
210
+ resetFlow,
211
+ isCompleted: state.currentStep === 'completed',
212
+ isFailed: state.currentStep === 'failed',
213
+ isActive:
214
+ state.currentStep !== 'completed' && state.currentStep !== 'failed',
215
+ remainingTime: Math.max(
216
+ 0,
217
+ fullConfig.stepTimeout - (Date.now() - state.stepStartTime)
218
+ ),
219
+ totalRemainingTime: Math.max(
220
+ 0,
221
+ fullConfig.totalTimeout - (Date.now() - state.totalStartTime)
222
+ ),
223
+ };
224
+ };
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;
@@ -1,153 +0,0 @@
1
- package com.omniretail.omnipay;
2
-
3
- import android.content.Context;
4
- import android.util.AttributeSet;
5
- import android.util.Log;
6
- import android.view.LayoutInflater;
7
- import android.view.View;
8
- import android.widget.FrameLayout;
9
-
10
- import androidx.annotation.NonNull;
11
- import androidx.annotation.Nullable;
12
- import androidx.camera.core.CameraSelector;
13
- import androidx.camera.core.Preview;
14
- import androidx.camera.lifecycle.ProcessCameraProvider;
15
- import androidx.camera.view.PreviewView;
16
- import androidx.core.content.ContextCompat;
17
- import androidx.lifecycle.LifecycleOwner;
18
-
19
- import com.facebook.react.bridge.Arguments;
20
- import com.facebook.react.bridge.ReactContext;
21
- import com.facebook.react.bridge.WritableMap;
22
- import com.facebook.react.uimanager.events.RCTEventEmitter;
23
- import com.google.common.util.concurrent.ListenableFuture;
24
-
25
- import java.util.concurrent.ExecutionException;
26
-
27
- public class OmnipayLivenessCameraView extends FrameLayout {
28
- private static final String TAG = "OmnipayLivenessCameraView";
29
-
30
- private PreviewView previewView;
31
- private ProcessCameraProvider cameraProvider;
32
- private Preview preview;
33
- private boolean isInitialized = false;
34
-
35
- public OmnipayLivenessCameraView(@NonNull Context context) {
36
- super(context);
37
- init();
38
- }
39
-
40
- public OmnipayLivenessCameraView(@NonNull Context context, @Nullable AttributeSet attrs) {
41
- super(context, attrs);
42
- init();
43
- }
44
-
45
- public OmnipayLivenessCameraView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
46
- super(context, attrs, defStyleAttr);
47
- init();
48
- }
49
-
50
- private void init() {
51
- // Create and add PreviewView
52
- previewView = new PreviewView(getContext());
53
- previewView.setLayoutParams(new FrameLayout.LayoutParams(
54
- FrameLayout.LayoutParams.MATCH_PARENT,
55
- FrameLayout.LayoutParams.MATCH_PARENT
56
- ));
57
- previewView.setScaleType(PreviewView.ScaleType.FILL_CENTER);
58
- addView(previewView);
59
-
60
- // Initialize camera
61
- initializeCamera();
62
- }
63
-
64
- private void initializeCamera() {
65
- ListenableFuture<ProcessCameraProvider> cameraProviderFuture =
66
- ProcessCameraProvider.getInstance(getContext());
67
-
68
- cameraProviderFuture.addListener(() -> {
69
- try {
70
- cameraProvider = cameraProviderFuture.get();
71
- setupCamera();
72
- isInitialized = true;
73
- sendEvent("onCameraReady", Arguments.createMap());
74
- } catch (ExecutionException | InterruptedException e) {
75
- Log.e(TAG, "Error initializing camera", e);
76
- WritableMap errorMap = Arguments.createMap();
77
- errorMap.putString("error", "Failed to initialize camera: " + e.getMessage());
78
- sendEvent("onCameraError", errorMap);
79
- }
80
- }, ContextCompat.getMainExecutor(getContext()));
81
- }
82
-
83
- private void setupCamera() {
84
- if (cameraProvider == null) {
85
- return;
86
- }
87
-
88
- // Create preview use case
89
- preview = new Preview.Builder().build();
90
-
91
- // Connect preview to PreviewView
92
- preview.setSurfaceProvider(previewView.getSurfaceProvider());
93
-
94
- // Select front camera
95
- CameraSelector cameraSelector = CameraSelector.DEFAULT_FRONT_CAMERA;
96
-
97
- try {
98
- // Unbind all use cases before rebinding
99
- cameraProvider.unbindAll();
100
-
101
- // Bind preview to camera
102
- if (getContext() instanceof LifecycleOwner) {
103
- cameraProvider.bindToLifecycle(
104
- (LifecycleOwner) getContext(),
105
- cameraSelector,
106
- preview
107
- );
108
- } else {
109
- Log.w(TAG, "Context is not a LifecycleOwner, camera preview may not work properly");
110
- }
111
- } catch (Exception e) {
112
- Log.e(TAG, "Error binding camera", e);
113
- WritableMap errorMap = Arguments.createMap();
114
- errorMap.putString("error", "Failed to bind camera: " + e.getMessage());
115
- sendEvent("onCameraError", errorMap);
116
- }
117
- }
118
-
119
- public void setupCameraPreview(ProcessCameraProvider cameraProvider) {
120
- this.cameraProvider = cameraProvider;
121
- if (isInitialized) {
122
- setupCamera();
123
- }
124
- }
125
-
126
- public void startPreview() {
127
- if (preview != null && cameraProvider != null) {
128
- // Camera preview is automatically started when bound to lifecycle
129
- Log.d(TAG, "Camera preview started");
130
- }
131
- }
132
-
133
- public void stopPreview() {
134
- if (cameraProvider != null) {
135
- cameraProvider.unbindAll();
136
- Log.d(TAG, "Camera preview stopped");
137
- }
138
- }
139
-
140
- @Override
141
- protected void onDetachedFromWindow() {
142
- super.onDetachedFromWindow();
143
- stopPreview();
144
- }
145
-
146
- private void sendEvent(String eventName, WritableMap params) {
147
- ReactContext reactContext = (ReactContext) getContext();
148
- if (reactContext != null) {
149
- reactContext.getJSModule(RCTEventEmitter.class)
150
- .receiveEvent(getId(), eventName, params);
151
- }
152
- }
153
- }
@@ -1,49 +0,0 @@
1
- package com.omniretail.omnipay;
2
-
3
- import androidx.annotation.NonNull;
4
- import androidx.annotation.Nullable;
5
-
6
- import com.facebook.react.bridge.ReactApplicationContext;
7
- import com.facebook.react.common.MapBuilder;
8
- import com.facebook.react.uimanager.SimpleViewManager;
9
- import com.facebook.react.uimanager.ThemedReactContext;
10
- import com.facebook.react.uimanager.annotations.ReactProp;
11
-
12
- import java.util.Map;
13
-
14
- public class OmnipayLivenessCameraViewManager extends SimpleViewManager<OmnipayLivenessCameraView> {
15
- public static final String REACT_CLASS = "OmnipayLivenessCameraView";
16
-
17
- private ReactApplicationContext reactContext;
18
-
19
- public OmnipayLivenessCameraViewManager(ReactApplicationContext reactContext) {
20
- this.reactContext = reactContext;
21
- }
22
-
23
- @NonNull
24
- @Override
25
- public String getName() {
26
- return REACT_CLASS;
27
- }
28
-
29
- @NonNull
30
- @Override
31
- protected OmnipayLivenessCameraView createViewInstance(@NonNull ThemedReactContext reactContext) {
32
- return new OmnipayLivenessCameraView(reactContext);
33
- }
34
-
35
- @Nullable
36
- @Override
37
- public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
38
- return MapBuilder.<String, Object>builder()
39
- .put("onCameraReady", MapBuilder.of("registrationName", "onCameraReady"))
40
- .put("onCameraError", MapBuilder.of("registrationName", "onCameraError"))
41
- .build();
42
- }
43
-
44
- @Override
45
- public void onDropViewInstance(@NonNull OmnipayLivenessCameraView view) {
46
- view.stopPreview();
47
- super.onDropViewInstance(view);
48
- }
49
- }