react-native-rectangle-doc-scanner 15.1.0 → 15.2.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.
@@ -33,6 +33,11 @@ export type DocScannerCapture = {
33
33
  width: number;
34
34
  height: number;
35
35
  origin: 'auto' | 'manual';
36
+ pages?: Array<{
37
+ path: string;
38
+ width: number;
39
+ height: number;
40
+ }> | null;
36
41
  };
37
42
  export interface DetectionConfig {
38
43
  processingWidth?: number;
@@ -121,6 +121,7 @@ const ActivityScanner = (0, react_1.forwardRef)(({ onCapture, children, showManu
121
121
  width: event.width ?? 0,
122
122
  height: event.height ?? 0,
123
123
  origin,
124
+ pages: event.pages ?? null,
124
125
  });
125
126
  }
126
127
  if (captureResolvers.current) {
@@ -321,6 +322,7 @@ const VisionCameraScanner = (0, react_1.forwardRef)(({ onCapture, overlayColor =
321
322
  width: event.width ?? 0,
322
323
  height: event.height ?? 0,
323
324
  origin,
325
+ pages: event.pages ?? null,
324
326
  });
325
327
  }
326
328
  setDetectedRectangle(null);
@@ -207,7 +207,12 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
207
207
  secondPrompt: strings?.secondPrompt ?? strings?.secondBtn ?? 'Capture Back Side?',
208
208
  originalBtn: strings?.originalBtn ?? 'Use Original',
209
209
  }), [strings]);
210
- const autoEnhancementEnabled = (0, react_1.useMemo)(() => typeof pdfScannerManager?.applyColorControls === 'function', [pdfScannerManager]);
210
+ const autoEnhancementEnabled = (0, react_1.useMemo)(() => {
211
+ if (usesAndroidScannerActivity) {
212
+ return false;
213
+ }
214
+ return typeof pdfScannerManager?.applyColorControls === 'function';
215
+ }, [pdfScannerManager, usesAndroidScannerActivity]);
211
216
  const ensureBase64ForImage = (0, react_1.useCallback)(async (image) => {
212
217
  if (image.base64) {
213
218
  return image;
@@ -420,6 +425,18 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
420
425
  console.warn('[FullDocScanner] Missing capture mode for capture result, ignoring');
421
426
  return;
422
427
  }
428
+ if (usesAndroidScannerActivity) {
429
+ const pages = document.pages?.length
430
+ ? document.pages
431
+ : [{ path: document.path, width: document.width, height: document.height }];
432
+ const results = pages.map((page) => ({
433
+ path: stripFileUri(page.path),
434
+ rotationDegrees: 0,
435
+ }));
436
+ onResult(results);
437
+ resetScannerView({ remount: true });
438
+ return;
439
+ }
423
440
  const normalizedDoc = normalizeCapturedDocument(document);
424
441
  const shouldOpenAndroidCropEditor = isAndroidCropEditorAvailable &&
425
442
  captureMode === 'grid' &&
@@ -459,10 +476,12 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
459
476
  }, [
460
477
  emitError,
461
478
  isAndroidCropEditorAvailable,
479
+ onResult,
462
480
  openAndroidCropEditor,
463
481
  openCropper,
464
482
  preparePreviewImage,
465
483
  resetScannerView,
484
+ usesAndroidScannerActivity,
466
485
  ]);
467
486
  const triggerManualCapture = (0, react_1.useCallback)(() => {
468
487
  const scannerInstance = docScannerRef.current;
@@ -522,13 +541,24 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
522
541
  captureModeRef.current = null;
523
542
  captureInProgressRef.current = false;
524
543
  if (errorMessage.includes('SCAN_CANCELLED')) {
544
+ resetScannerView({ remount: true });
545
+ onClose?.();
525
546
  return;
526
547
  }
527
548
  if (error instanceof Error && error.message !== 'capture_in_progress') {
528
549
  emitError(error, 'Failed to capture image. Please try again.');
529
550
  }
530
551
  });
531
- }, [processing, rectangleDetected, rectangleHint, captureReady, emitError, usesAndroidScannerActivity]);
552
+ }, [
553
+ emitError,
554
+ onClose,
555
+ processing,
556
+ rectangleDetected,
557
+ rectangleHint,
558
+ captureReady,
559
+ resetScannerView,
560
+ usesAndroidScannerActivity,
561
+ ]);
532
562
  const handleGalleryPick = (0, react_1.useCallback)(async () => {
533
563
  console.log('[FullDocScanner] handleGalleryPick called');
534
564
  if (processing || isGalleryOpen) {
@@ -642,7 +672,18 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
642
672
  setCurrentPhotoIndex(0);
643
673
  }
644
674
  resetScannerView({ remount: true });
645
- }, [capturedPhotos.length, isBusinessMode, resetScannerView]);
675
+ if (usesAndroidScannerActivity) {
676
+ requestAnimationFrame(() => {
677
+ triggerManualCapture();
678
+ });
679
+ }
680
+ }, [
681
+ capturedPhotos.length,
682
+ isBusinessMode,
683
+ resetScannerView,
684
+ triggerManualCapture,
685
+ usesAndroidScannerActivity,
686
+ ]);
646
687
  const handleRectangleDetect = (0, react_1.useCallback)((event) => {
647
688
  const stableCounter = event.stableCounter ?? 0;
648
689
  const rectangleCoordinates = event.rectangleOnScreen ?? event.rectangleCoordinates;
@@ -785,7 +826,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
785
826
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.retakeButton], onPress: handleCropEditorCancel, accessibilityLabel: mergedStrings.retake, accessibilityRole: "button", disabled: processing },
786
827
  react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.retake)),
787
828
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.confirmButtonPrimary], onPress: handleCropEditorConfirm, accessibilityLabel: mergedStrings.confirm, accessibilityRole: "button", disabled: processing },
788
- react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.confirm))))) : (react_1.default.createElement(react_native_1.View, { style: styles.flex },
829
+ react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.confirm))))) : usesAndroidScannerActivity ? (react_1.default.createElement(react_native_1.View, { style: styles.flex })) : (react_1.default.createElement(react_native_1.View, { style: styles.flex },
789
830
  react_1.default.createElement(DocScanner_1.DocScanner, { key: scannerSession, ref: docScannerRef, autoCapture: false, overlayColor: overlayColor, showGrid: showGrid, gridColor: resolvedGridColor, gridLineWidth: gridLineWidth, minStableFrames: minStableFrames ?? 6, detectionConfig: detectionConfig, onCapture: handleCapture, onRectangleDetect: handleRectangleDetect, showManualCaptureButton: false, enableTorch: flashEnabled },
790
831
  react_1.default.createElement(react_native_1.View, { style: styles.overlayTop, pointerEvents: "box-none" },
791
832
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "15.1.0",
3
+ "version": "15.2.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -48,6 +48,7 @@ export type DocScannerCapture = {
48
48
  width: number;
49
49
  height: number;
50
50
  origin: 'auto' | 'manual';
51
+ pages?: Array<{ path: string; width: number; height: number }> | null;
51
52
  };
52
53
 
53
54
  const isFiniteNumber = (value: unknown): value is number =>
@@ -192,6 +193,7 @@ const ActivityScanner = forwardRef<DocScannerHandle, Props>(
192
193
  width: event.width ?? 0,
193
194
  height: event.height ?? 0,
194
195
  origin,
196
+ pages: event.pages ?? null,
195
197
  });
196
198
  }
197
199
 
@@ -480,6 +482,7 @@ const VisionCameraScanner = forwardRef<DocScannerHandle, Props>(
480
482
  width: event.width ?? 0,
481
483
  height: event.height ?? 0,
482
484
  origin,
485
+ pages: event.pages ?? null,
483
486
  });
484
487
  }
485
488
 
@@ -293,10 +293,12 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
293
293
  [strings],
294
294
  );
295
295
 
296
- const autoEnhancementEnabled = useMemo(
297
- () => typeof pdfScannerManager?.applyColorControls === 'function',
298
- [pdfScannerManager],
299
- );
296
+ const autoEnhancementEnabled = useMemo(() => {
297
+ if (usesAndroidScannerActivity) {
298
+ return false;
299
+ }
300
+ return typeof pdfScannerManager?.applyColorControls === 'function';
301
+ }, [pdfScannerManager, usesAndroidScannerActivity]);
300
302
 
301
303
  const ensureBase64ForImage = useCallback(
302
304
  async (image: PreviewImageInfo): Promise<PreviewImageInfo> => {
@@ -580,6 +582,19 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
580
582
  return;
581
583
  }
582
584
 
585
+ if (usesAndroidScannerActivity) {
586
+ const pages = document.pages?.length
587
+ ? document.pages
588
+ : [{ path: document.path, width: document.width, height: document.height }];
589
+ const results: FullDocScannerResult[] = pages.map((page) => ({
590
+ path: stripFileUri(page.path),
591
+ rotationDegrees: 0,
592
+ }));
593
+ onResult(results);
594
+ resetScannerView({ remount: true });
595
+ return;
596
+ }
597
+
583
598
  const normalizedDoc = normalizeCapturedDocument(document);
584
599
 
585
600
  const shouldOpenAndroidCropEditor =
@@ -630,10 +645,12 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
630
645
  [
631
646
  emitError,
632
647
  isAndroidCropEditorAvailable,
648
+ onResult,
633
649
  openAndroidCropEditor,
634
650
  openCropper,
635
651
  preparePreviewImage,
636
652
  resetScannerView,
653
+ usesAndroidScannerActivity,
637
654
  ],
638
655
  );
639
656
 
@@ -707,6 +724,8 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
707
724
  captureInProgressRef.current = false;
708
725
 
709
726
  if (errorMessage.includes('SCAN_CANCELLED')) {
727
+ resetScannerView({ remount: true });
728
+ onClose?.();
710
729
  return;
711
730
  }
712
731
 
@@ -717,7 +736,16 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
717
736
  );
718
737
  }
719
738
  });
720
- }, [processing, rectangleDetected, rectangleHint, captureReady, emitError, usesAndroidScannerActivity]);
739
+ }, [
740
+ emitError,
741
+ onClose,
742
+ processing,
743
+ rectangleDetected,
744
+ rectangleHint,
745
+ captureReady,
746
+ resetScannerView,
747
+ usesAndroidScannerActivity,
748
+ ]);
721
749
 
722
750
  const handleGalleryPick = useCallback(async () => {
723
751
  console.log('[FullDocScanner] handleGalleryPick called');
@@ -863,7 +891,19 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
863
891
  }
864
892
 
865
893
  resetScannerView({ remount: true });
866
- }, [capturedPhotos.length, isBusinessMode, resetScannerView]);
894
+
895
+ if (usesAndroidScannerActivity) {
896
+ requestAnimationFrame(() => {
897
+ triggerManualCapture();
898
+ });
899
+ }
900
+ }, [
901
+ capturedPhotos.length,
902
+ isBusinessMode,
903
+ resetScannerView,
904
+ triggerManualCapture,
905
+ usesAndroidScannerActivity,
906
+ ]);
867
907
 
868
908
  const handleRectangleDetect = useCallback((event: RectangleDetectEvent) => {
869
909
  const stableCounter = event.stableCounter ?? 0;
@@ -1142,6 +1182,8 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
1142
1182
  </TouchableOpacity>
1143
1183
  </View>
1144
1184
  </View>
1185
+ ) : usesAndroidScannerActivity ? (
1186
+ <View style={styles.flex} />
1145
1187
  ) : (
1146
1188
  <View style={styles.flex}>
1147
1189
  <DocScanner