@switchlabs/verify-ai-react-native 2.4.8 → 2.4.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.
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useRef, useState, useCallback, useEffect } from 'react';
3
- import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, AppState, useWindowDimensions, } from 'react-native';
3
+ import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, AppState, Platform, useWindowDimensions, } from 'react-native';
4
4
  import { CameraView, useCameraPermissions, } from 'expo-camera';
5
5
  import { useTelemetry } from '../telemetry/TelemetryContext';
6
6
  /** Quality used when expo-image-manipulator is not available (lower = smaller). */
@@ -94,10 +94,52 @@ export function VerifyAIScanner({ onCapture, onResult, onError, overlay, style,
94
94
  const isLandscape = windowWidth > windowHeight;
95
95
  const prevDimensionsRef = useRef({ width: windowWidth, height: windowHeight });
96
96
  // Track physical device orientation independently of interface orientation.
97
- // When the host app is orientation-locked, window dimensions don't change
98
- // on rotation this fires via expo-camera's responsive-orientation callback
99
- // so we can rotate the overlay UI to stay readable from the user's viewpoint.
97
+ // When the host app is orientation-locked, window dimensions don't change on
98
+ // rotation. iOS uses expo-camera's responsive-orientation callback; Android
99
+ // uses the accelerometer via expo-sensors (the callback is iOS-only). Either
100
+ // way we rotate the overlay UI to stay readable from the user's viewpoint.
100
101
  const [physicalOrientation, setPhysicalOrientation] = useState('portrait');
102
+ useEffect(() => {
103
+ if (Platform.OS !== 'android')
104
+ return;
105
+ let subscription = null;
106
+ let cancelled = false;
107
+ let lastOrientation = 'portrait';
108
+ (async () => {
109
+ let Accelerometer = null;
110
+ try {
111
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
112
+ const mod = require('expo-sensors');
113
+ Accelerometer = mod?.Accelerometer ?? null;
114
+ }
115
+ catch {
116
+ return;
117
+ }
118
+ if (cancelled || !Accelerometer)
119
+ return;
120
+ Accelerometer.setUpdateInterval(500);
121
+ subscription = Accelerometer.addListener(({ x, y }) => {
122
+ let next;
123
+ if (Math.abs(x) > Math.abs(y) + 0.2) {
124
+ next = x > 0 ? 'landscapeRight' : 'landscapeLeft';
125
+ }
126
+ else if (Math.abs(y) > Math.abs(x) + 0.2) {
127
+ next = y > 0 ? 'portraitUpsideDown' : 'portrait';
128
+ }
129
+ else {
130
+ return; // ambiguous tilt — ignore
131
+ }
132
+ if (next !== lastOrientation) {
133
+ lastOrientation = next;
134
+ setPhysicalOrientation(next);
135
+ }
136
+ });
137
+ })();
138
+ return () => {
139
+ cancelled = true;
140
+ subscription?.remove();
141
+ };
142
+ }, []);
101
143
  const overlayRotationDeg = (() => {
102
144
  switch (physicalOrientation) {
103
145
  case 'landscapeLeft':
package/lib/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "2.4.8";
1
+ export declare const SDK_VERSION = "2.4.10";
package/lib/version.js CHANGED
@@ -1 +1 @@
1
- export const SDK_VERSION = '2.4.8';
1
+ export const SDK_VERSION = '2.4.10';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@switchlabs/verify-ai-react-native",
3
- "version": "2.4.8",
3
+ "version": "2.4.10",
4
4
  "description": "React Native SDK for Verify AI - photo verification with AI vision processing",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -43,6 +43,7 @@
43
43
  "expo-camera": ">=15.0.0",
44
44
  "expo-file-system": ">=17.0.0",
45
45
  "expo-image-manipulator": ">=12.0.0",
46
+ "expo-sensors": ">=13.0.0",
46
47
  "react": ">=18.0.0",
47
48
  "react-native": ">=0.72.0",
48
49
  "react-native-fast-tflite": ">=1.0.0"
@@ -54,6 +55,9 @@
54
55
  "expo-image-manipulator": {
55
56
  "optional": true
56
57
  },
58
+ "expo-sensors": {
59
+ "optional": true
60
+ },
57
61
  "@react-native-async-storage/async-storage": {
58
62
  "optional": true
59
63
  },
@@ -6,6 +6,7 @@ import {
6
6
  StyleSheet,
7
7
  ActivityIndicator,
8
8
  AppState,
9
+ Platform,
9
10
  useWindowDimensions,
10
11
  type ViewStyle,
11
12
  } from 'react-native';
@@ -160,13 +161,59 @@ export function VerifyAIScanner({
160
161
  const prevDimensionsRef = useRef({ width: windowWidth, height: windowHeight });
161
162
 
162
163
  // Track physical device orientation independently of interface orientation.
163
- // When the host app is orientation-locked, window dimensions don't change
164
- // on rotation this fires via expo-camera's responsive-orientation callback
165
- // so we can rotate the overlay UI to stay readable from the user's viewpoint.
164
+ // When the host app is orientation-locked, window dimensions don't change on
165
+ // rotation. iOS uses expo-camera's responsive-orientation callback; Android
166
+ // uses the accelerometer via expo-sensors (the callback is iOS-only). Either
167
+ // way we rotate the overlay UI to stay readable from the user's viewpoint.
166
168
  const [physicalOrientation, setPhysicalOrientation] = useState<
167
169
  'portrait' | 'portraitUpsideDown' | 'landscapeLeft' | 'landscapeRight'
168
170
  >('portrait');
169
171
 
172
+ useEffect(() => {
173
+ if (Platform.OS !== 'android') return;
174
+ let subscription: { remove: () => void } | null = null;
175
+ let cancelled = false;
176
+ let lastOrientation: typeof physicalOrientation = 'portrait';
177
+
178
+ (async () => {
179
+ let Accelerometer: {
180
+ setUpdateInterval: (ms: number) => void;
181
+ addListener: (
182
+ cb: (data: { x: number; y: number; z: number }) => void,
183
+ ) => { remove: () => void };
184
+ } | null = null;
185
+ try {
186
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
187
+ const mod = require('expo-sensors');
188
+ Accelerometer = mod?.Accelerometer ?? null;
189
+ } catch {
190
+ return;
191
+ }
192
+ if (cancelled || !Accelerometer) return;
193
+
194
+ Accelerometer.setUpdateInterval(500);
195
+ subscription = Accelerometer.addListener(({ x, y }) => {
196
+ let next: typeof physicalOrientation;
197
+ if (Math.abs(x) > Math.abs(y) + 0.2) {
198
+ next = x > 0 ? 'landscapeRight' : 'landscapeLeft';
199
+ } else if (Math.abs(y) > Math.abs(x) + 0.2) {
200
+ next = y > 0 ? 'portraitUpsideDown' : 'portrait';
201
+ } else {
202
+ return; // ambiguous tilt — ignore
203
+ }
204
+ if (next !== lastOrientation) {
205
+ lastOrientation = next;
206
+ setPhysicalOrientation(next);
207
+ }
208
+ });
209
+ })();
210
+
211
+ return () => {
212
+ cancelled = true;
213
+ subscription?.remove();
214
+ };
215
+ }, []);
216
+
170
217
  const overlayRotationDeg = (() => {
171
218
  switch (physicalOrientation) {
172
219
  case 'landscapeLeft':
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const SDK_VERSION = '2.4.8';
1
+ export const SDK_VERSION = '2.4.10';