@hexar/biometric-identity-sdk-react-native 1.0.25 → 1.0.26

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.
@@ -45,16 +45,16 @@ const useBiometricSDK_1 = require("../hooks/useBiometricSDK");
45
45
  const CameraCapture_1 = require("./CameraCapture");
46
46
  const VideoRecorder_1 = require("./VideoRecorder");
47
47
  const getInstructionMap = (strings) => ({
48
- look_left: { text: strings.liveness.instructions.lookLeft || 'Slowly turn your head LEFT', icon: '←' },
49
- look_right: { text: strings.liveness.instructions.lookRight || 'Slowly turn your head RIGHT', icon: '→' },
50
- look_up: { text: strings.liveness.instructions.lookUp || 'Look UP', icon: '↑' },
51
- look_down: { text: strings.liveness.instructions.lookDown || 'Look DOWN', icon: '↓' },
52
- turn_head_left: { text: strings.liveness.instructions.turnHeadLeft || 'Turn your head LEFT', icon: '←' },
53
- turn_head_right: { text: strings.liveness.instructions.turnHeadRight || 'Turn your head RIGHT', icon: '→' },
54
- smile: { text: strings.liveness.instructions.smile || 'Smile 😊', icon: '😊' },
55
- blink: { text: strings.liveness.instructions.blink || 'Blink your eyes naturally', icon: '👁' },
56
- open_mouth: { text: strings.liveness.instructions.openMouth || 'Open your mouth slightly', icon: '😮' },
57
- stay_still: { text: strings.liveness.instructions.stayStill || 'Look at the camera and follow the instructions', icon: '📷' },
48
+ look_left: { text: strings.liveness.instructions.lookLeft || 'Slowly turn your head LEFT' },
49
+ look_right: { text: strings.liveness.instructions.lookRight || 'Slowly turn your head RIGHT' },
50
+ look_up: { text: strings.liveness.instructions.lookUp || 'Look UP' },
51
+ look_down: { text: strings.liveness.instructions.lookDown || 'Look DOWN' },
52
+ turn_head_left: { text: strings.liveness.instructions.turnHeadLeft || 'Turn your head LEFT' },
53
+ turn_head_right: { text: strings.liveness.instructions.turnHeadRight || 'Turn your head RIGHT' },
54
+ smile: { text: strings.liveness.instructions.smile || 'Smile' },
55
+ blink: { text: strings.liveness.instructions.blink || 'Blink your eyes naturally' },
56
+ open_mouth: { text: strings.liveness.instructions.openMouth || 'Open your mouth slightly' },
57
+ stay_still: { text: strings.liveness.instructions.stayStill || 'Look at the camera and follow the instructions' },
58
58
  });
59
59
  const ValidationProgress_1 = require("./ValidationProgress");
60
60
  const ResultScreen_1 = require("./ResultScreen");
@@ -1 +1 @@
1
- {"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../src/components/VideoRecorder.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,EAAmC,MAAM,oCAAoC,CAAC;AAE1I,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,iCAAiC;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA8CD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAo0BtD,CAAC;AA4OF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../src/components/VideoRecorder.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,EAAmC,MAAM,oCAAoC,CAAC;AAE1I,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,iCAAiC;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0CD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAs1BtD,CAAC;AA4OF,eAAe,aAAa,CAAC"}
@@ -49,41 +49,37 @@ const getDefaultChallenges = (strings) => [
49
49
  instruction: strings.liveness.instructions.lookLeft || 'Slowly turn your head to the LEFT',
50
50
  duration_ms: 2500,
51
51
  order: 1,
52
- icon: '←',
53
52
  },
54
53
  {
55
54
  action: 'look_right',
56
55
  instruction: strings.liveness.instructions.lookRight || 'Slowly turn your head to the RIGHT',
57
56
  duration_ms: 2500,
58
57
  order: 2,
59
- icon: '→',
60
58
  },
61
59
  {
62
60
  action: 'blink',
63
61
  instruction: strings.liveness.instructions.blink || 'Blink your eyes naturally',
64
62
  duration_ms: 2000,
65
63
  order: 3,
66
- icon: '👁',
67
64
  },
68
65
  {
69
66
  action: 'smile',
70
- instruction: strings.liveness.instructions.smile || 'Smile 😊',
67
+ instruction: strings.liveness.instructions.smile || 'Smile',
71
68
  duration_ms: 2000,
72
69
  order: 4,
73
- icon: '😊',
74
70
  },
75
71
  ];
76
72
  const getInstructionMap = (strings) => ({
77
- look_left: { text: strings.liveness.instructions.lookLeft || 'Slowly turn your head LEFT', icon: '←' },
78
- look_right: { text: strings.liveness.instructions.lookRight || 'Slowly turn your head RIGHT', icon: '→' },
79
- look_up: { text: strings.liveness.instructions.lookUp || 'Look UP', icon: '↑' },
80
- look_down: { text: strings.liveness.instructions.lookDown || 'Look DOWN', icon: '↓' },
81
- turn_head_left: { text: strings.liveness.instructions.turnHeadLeft || 'Turn your head LEFT', icon: '←' },
82
- turn_head_right: { text: strings.liveness.instructions.turnHeadRight || 'Turn your head RIGHT', icon: '→' },
83
- smile: { text: strings.liveness.instructions.smile || 'Smile 😊', icon: '😊' },
84
- blink: { text: strings.liveness.instructions.blink || 'Blink your eyes naturally', icon: '👁' },
85
- open_mouth: { text: strings.liveness.instructions.openMouth || 'Open your mouth slightly', icon: '😮' },
86
- stay_still: { text: strings.liveness.instructions.stayStill || 'Look at the camera and follow the instructions', icon: '📷' },
73
+ look_left: { text: strings.liveness.instructions.lookLeft || 'Slowly turn your head LEFT' },
74
+ look_right: { text: strings.liveness.instructions.lookRight || 'Slowly turn your head RIGHT' },
75
+ look_up: { text: strings.liveness.instructions.lookUp || 'Look UP' },
76
+ look_down: { text: strings.liveness.instructions.lookDown || 'Look DOWN' },
77
+ turn_head_left: { text: strings.liveness.instructions.turnHeadLeft || 'Turn your head LEFT' },
78
+ turn_head_right: { text: strings.liveness.instructions.turnHeadRight || 'Turn your head RIGHT' },
79
+ smile: { text: strings.liveness.instructions.smile || 'Smile' },
80
+ blink: { text: strings.liveness.instructions.blink || 'Blink your eyes naturally' },
81
+ open_mouth: { text: strings.liveness.instructions.openMouth || 'Open your mouth slightly' },
82
+ stay_still: { text: strings.liveness.instructions.stayStill || 'Look at the camera and follow the instructions' },
87
83
  });
88
84
  const VideoRecorder = ({ theme, language, duration, instructions, challenges: propChallenges, sessionId, smartMode = true, onComplete, onCancel, onFetchChallenges, }) => {
89
85
  (0, react_1.useEffect)(() => {
@@ -183,7 +179,6 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
183
179
  instruction: currentStrings.liveness.instructions.stayStill || 'Look at the camera and stay still',
184
180
  duration_ms: duration || 5000,
185
181
  order: 1,
186
- icon: '📷',
187
182
  },
188
183
  ];
189
184
  }
@@ -346,11 +341,35 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
346
341
  });
347
342
  if (photo) {
348
343
  consecutiveErrors = 0;
344
+ let base64Data = null;
349
345
  try {
350
346
  const RNFS = require('react-native-fs');
351
- const base64 = await RNFS.readFile(photo.path, 'base64');
347
+ base64Data = await RNFS.readFile(photo.path, 'base64');
348
+ }
349
+ catch (fsError) {
350
+ try {
351
+ const fileUri = react_native_1.Platform.OS === 'android' ? `file://${photo.path}` : photo.path;
352
+ const response = await fetch(fileUri);
353
+ const blob = await response.blob();
354
+ base64Data = await new Promise((resolve, reject) => {
355
+ const reader = new FileReader();
356
+ reader.onloadend = () => {
357
+ const result = reader.result;
358
+ const base64 = result.includes(',') ? result.split(',')[1] : result;
359
+ resolve(base64);
360
+ };
361
+ reader.onerror = reject;
362
+ reader.readAsDataURL(blob);
363
+ });
364
+ }
365
+ catch (fetchError) {
366
+ biometric_identity_sdk_core_1.logger.error('Failed to read photo file as base64:', fetchError);
367
+ base64Data = null;
368
+ }
369
+ }
370
+ if (base64Data) {
352
371
  setFrames(prev => {
353
- const newFrames = prev.length < 100 ? [...prev, base64] : prev;
372
+ const newFrames = prev.length < 100 ? [...prev, base64Data] : prev;
354
373
  framesRef.current = newFrames;
355
374
  if (newFrames.length % 10 === 0) {
356
375
  biometric_identity_sdk_core_1.logger.info('Captured frames:', newFrames.length);
@@ -358,13 +377,8 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
358
377
  return newFrames;
359
378
  });
360
379
  }
361
- catch (fsError) {
362
- biometric_identity_sdk_core_1.logger.warn('Could not read photo file, using path');
363
- setFrames(prev => {
364
- const newFrames = prev.length < 100 ? [...prev, photo.path] : prev;
365
- framesRef.current = newFrames;
366
- return newFrames;
367
- });
380
+ else {
381
+ biometric_identity_sdk_core_1.logger.warn('Could not convert photo to base64, skipping frame');
368
382
  }
369
383
  }
370
384
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexar/biometric-identity-sdk-react-native",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
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.15",
14
+ "@hexar/biometric-identity-sdk-core": ">=1.0.16",
15
15
  "react": ">=18.0.0",
16
16
  "react-native": ">=0.70.0",
17
17
  "react-native-permissions": ">=4.0.0",
@@ -29,17 +29,17 @@ import { useBiometricSDK } from '../hooks/useBiometricSDK';
29
29
  import { CameraCapture } from './CameraCapture';
30
30
  import { VideoRecorder, VideoRecordingResult } from './VideoRecorder';
31
31
 
32
- const getInstructionMap = (strings: any): Record<string, { text: string; icon: string }> => ({
33
- look_left: { text: strings.liveness.instructions.lookLeft || 'Slowly turn your head LEFT', icon: '←' },
34
- look_right: { text: strings.liveness.instructions.lookRight || 'Slowly turn your head RIGHT', icon: '→' },
35
- look_up: { text: strings.liveness.instructions.lookUp || 'Look UP', icon: '↑' },
36
- look_down: { text: strings.liveness.instructions.lookDown || 'Look DOWN', icon: '↓' },
37
- turn_head_left: { text: strings.liveness.instructions.turnHeadLeft || 'Turn your head LEFT', icon: '←' },
38
- turn_head_right: { text: strings.liveness.instructions.turnHeadRight || 'Turn your head RIGHT', icon: '→' },
39
- smile: { text: strings.liveness.instructions.smile || 'Smile 😊', icon: '😊' },
40
- blink: { text: strings.liveness.instructions.blink || 'Blink your eyes naturally', icon: '👁' },
41
- open_mouth: { text: strings.liveness.instructions.openMouth || 'Open your mouth slightly', icon: '😮' },
42
- stay_still: { text: strings.liveness.instructions.stayStill || 'Look at the camera and follow the instructions', icon: '📷' },
32
+ const getInstructionMap = (strings: any): Record<string, { text: string; icon?: string }> => ({
33
+ look_left: { text: strings.liveness.instructions.lookLeft || 'Slowly turn your head LEFT' },
34
+ look_right: { text: strings.liveness.instructions.lookRight || 'Slowly turn your head RIGHT' },
35
+ look_up: { text: strings.liveness.instructions.lookUp || 'Look UP' },
36
+ look_down: { text: strings.liveness.instructions.lookDown || 'Look DOWN' },
37
+ turn_head_left: { text: strings.liveness.instructions.turnHeadLeft || 'Turn your head LEFT' },
38
+ turn_head_right: { text: strings.liveness.instructions.turnHeadRight || 'Turn your head RIGHT' },
39
+ smile: { text: strings.liveness.instructions.smile || 'Smile' },
40
+ blink: { text: strings.liveness.instructions.blink || 'Blink your eyes naturally' },
41
+ open_mouth: { text: strings.liveness.instructions.openMouth || 'Open your mouth slightly' },
42
+ stay_still: { text: strings.liveness.instructions.stayStill || 'Look at the camera and follow the instructions' },
43
43
  });
44
44
  import { ValidationProgress } from './ValidationProgress';
45
45
  import { ResultScreen } from './ResultScreen';
@@ -62,42 +62,38 @@ const getDefaultChallenges = (strings: any): ChallengeAction[] => [
62
62
  instruction: strings.liveness.instructions.lookLeft || 'Slowly turn your head to the LEFT',
63
63
  duration_ms: 2500,
64
64
  order: 1,
65
- icon: '←',
66
65
  },
67
66
  {
68
67
  action: 'look_right',
69
68
  instruction: strings.liveness.instructions.lookRight || 'Slowly turn your head to the RIGHT',
70
69
  duration_ms: 2500,
71
70
  order: 2,
72
- icon: '→',
73
71
  },
74
72
  {
75
73
  action: 'blink',
76
74
  instruction: strings.liveness.instructions.blink || 'Blink your eyes naturally',
77
75
  duration_ms: 2000,
78
76
  order: 3,
79
- icon: '👁',
80
77
  },
81
78
  {
82
79
  action: 'smile',
83
- instruction: strings.liveness.instructions.smile || 'Smile 😊',
80
+ instruction: strings.liveness.instructions.smile || 'Smile',
84
81
  duration_ms: 2000,
85
82
  order: 4,
86
- icon: '😊',
87
83
  },
88
84
  ];
89
85
 
90
- const getInstructionMap = (strings: any): Record<string, { text: string; icon: string }> => ({
91
- look_left: { text: strings.liveness.instructions.lookLeft || 'Slowly turn your head LEFT', icon: '←' },
92
- look_right: { text: strings.liveness.instructions.lookRight || 'Slowly turn your head RIGHT', icon: '→' },
93
- look_up: { text: strings.liveness.instructions.lookUp || 'Look UP', icon: '↑' },
94
- look_down: { text: strings.liveness.instructions.lookDown || 'Look DOWN', icon: '↓' },
95
- turn_head_left: { text: strings.liveness.instructions.turnHeadLeft || 'Turn your head LEFT', icon: '←' },
96
- turn_head_right: { text: strings.liveness.instructions.turnHeadRight || 'Turn your head RIGHT', icon: '→' },
97
- smile: { text: strings.liveness.instructions.smile || 'Smile 😊', icon: '😊' },
98
- blink: { text: strings.liveness.instructions.blink || 'Blink your eyes naturally', icon: '👁' },
99
- open_mouth: { text: strings.liveness.instructions.openMouth || 'Open your mouth slightly', icon: '😮' },
100
- stay_still: { text: strings.liveness.instructions.stayStill || 'Look at the camera and follow the instructions', icon: '📷' },
86
+ const getInstructionMap = (strings: any): Record<string, { text: string; icon?: string }> => ({
87
+ look_left: { text: strings.liveness.instructions.lookLeft || 'Slowly turn your head LEFT' },
88
+ look_right: { text: strings.liveness.instructions.lookRight || 'Slowly turn your head RIGHT' },
89
+ look_up: { text: strings.liveness.instructions.lookUp || 'Look UP' },
90
+ look_down: { text: strings.liveness.instructions.lookDown || 'Look DOWN' },
91
+ turn_head_left: { text: strings.liveness.instructions.turnHeadLeft || 'Turn your head LEFT' },
92
+ turn_head_right: { text: strings.liveness.instructions.turnHeadRight || 'Turn your head RIGHT' },
93
+ smile: { text: strings.liveness.instructions.smile || 'Smile' },
94
+ blink: { text: strings.liveness.instructions.blink || 'Blink your eyes naturally' },
95
+ open_mouth: { text: strings.liveness.instructions.openMouth || 'Open your mouth slightly' },
96
+ stay_still: { text: strings.liveness.instructions.stayStill || 'Look at the camera and follow the instructions' },
101
97
  });
102
98
 
103
99
  export const VideoRecorder: React.FC<VideoRecorderProps> = ({
@@ -213,17 +209,16 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
213
209
  order: idx + 1,
214
210
  icon: instructionMap[inst]?.icon,
215
211
  }));
216
- } else {
217
- challengeList = smartMode ? getDefaultChallenges(currentStrings) : [
218
- {
219
- action: 'stay_still',
220
- instruction: currentStrings.liveness.instructions.stayStill || 'Look at the camera and stay still',
221
- duration_ms: duration || 5000,
222
- order: 1,
223
- icon: '📷',
224
- },
225
- ];
226
- }
212
+ } else {
213
+ challengeList = smartMode ? getDefaultChallenges(currentStrings) : [
214
+ {
215
+ action: 'stay_still',
216
+ instruction: currentStrings.liveness.instructions.stayStill || 'Look at the camera and stay still',
217
+ duration_ms: duration || 5000,
218
+ order: 1,
219
+ },
220
+ ];
221
+ }
227
222
 
228
223
  setChallenges(challengeList);
229
224
  setPhase('countdown');
@@ -416,24 +411,43 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
416
411
 
417
412
  if (photo) {
418
413
  consecutiveErrors = 0;
414
+ let base64Data: string | null = null;
415
+
419
416
  try {
420
417
  const RNFS = require('react-native-fs');
421
- const base64 = await RNFS.readFile(photo.path, 'base64');
418
+ base64Data = await RNFS.readFile(photo.path, 'base64');
419
+ } catch (fsError) {
420
+ try {
421
+ const fileUri = Platform.OS === 'android' ? `file://${photo.path}` : photo.path;
422
+ const response = await fetch(fileUri);
423
+ const blob = await response.blob();
424
+ base64Data = await new Promise<string>((resolve, reject) => {
425
+ const reader = new FileReader();
426
+ reader.onloadend = () => {
427
+ const result = reader.result as string;
428
+ const base64 = result.includes(',') ? result.split(',')[1] : result;
429
+ resolve(base64);
430
+ };
431
+ reader.onerror = reject;
432
+ reader.readAsDataURL(blob);
433
+ });
434
+ } catch (fetchError) {
435
+ logger.error('Failed to read photo file as base64:', fetchError);
436
+ base64Data = null;
437
+ }
438
+ }
439
+
440
+ if (base64Data) {
422
441
  setFrames(prev => {
423
- const newFrames = prev.length < 100 ? [...prev, base64] : prev;
442
+ const newFrames = prev.length < 100 ? [...prev, base64Data!] : prev;
424
443
  framesRef.current = newFrames;
425
444
  if (newFrames.length % 10 === 0) {
426
445
  logger.info('Captured frames:', newFrames.length);
427
446
  }
428
447
  return newFrames;
429
448
  });
430
- } catch (fsError) {
431
- logger.warn('Could not read photo file, using path');
432
- setFrames(prev => {
433
- const newFrames = prev.length < 100 ? [...prev, photo.path] : prev;
434
- framesRef.current = newFrames;
435
- return newFrames;
436
- });
449
+ } else {
450
+ logger.warn('Could not convert photo to base64, skipping frame');
437
451
  }
438
452
  }
439
453
  } catch (error: any) {