react-native-rectangle-doc-scanner 3.117.0 → 3.118.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.
@@ -132,7 +132,6 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
132
132
  const rectangleCaptureTimeoutRef = (0, react_1.useRef)(null);
133
133
  const rectangleHintTimeoutRef = (0, react_1.useRef)(null);
134
134
  const isBusinessMode = type === 'business';
135
- const maxPhotos = isBusinessMode ? 2 : 1;
136
135
  const mergedStrings = (0, react_1.useMemo)(() => ({
137
136
  captureHint: strings?.captureHint,
138
137
  manualHint: strings?.manualHint,
@@ -392,9 +391,9 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
392
391
  rotationDegrees: rotationNormalized,
393
392
  };
394
393
  const updatedPhotos = [...capturedPhotos, currentPhoto];
395
- console.log('[FullDocScanner] Photos captured:', updatedPhotos.length, 'of', maxPhotos);
396
- // 모든 사진 촬영 완료 - 결과 반환
397
- console.log('[FullDocScanner] All photos captured, returning results');
394
+ console.log('[FullDocScanner] Photos captured:', updatedPhotos.length);
395
+ // 결과 반환
396
+ console.log('[FullDocScanner] Returning results');
398
397
  onResult(updatedPhotos);
399
398
  }, [croppedImageData, rotationDegrees, capturedPhotos, onResult]);
400
399
  const handleCaptureSecondPhoto = (0, react_1.useCallback)(() => {
@@ -431,20 +430,6 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
431
430
  docScannerRef.current.reset();
432
431
  }
433
432
  }, [croppedImageData, rotationDegrees]);
434
- const handleSkipSecondPhoto = (0, react_1.useCallback)(() => {
435
- console.log('[FullDocScanner] Skipping second photo - saving current photo only');
436
- if (!croppedImageData) {
437
- return;
438
- }
439
- // 현재 사진만 저장하고 완료
440
- const rotationNormalized = ((rotationDegrees % 360) + 360) % 360;
441
- const currentPhoto = {
442
- path: croppedImageData.path,
443
- base64: croppedImageData.base64,
444
- rotationDegrees: rotationNormalized,
445
- };
446
- onResult([currentPhoto]);
447
- }, [croppedImageData, rotationDegrees, onResult]);
448
433
  const handleRetake = (0, react_1.useCallback)(() => {
449
434
  console.log('[FullDocScanner] Retake - clearing cropped image and resetting scanner');
450
435
  // Business 모드에서 두 번째 사진을 다시 찍는 경우, 첫 번째 사진 유지
@@ -539,6 +524,8 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
539
524
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.rotateButtonTop, onPress: () => handleRotateImage(90), accessibilityLabel: "\uC624\uB978\uCABD\uC73C\uB85C 90\uB3C4 \uD68C\uC804", accessibilityRole: "button" },
540
525
  react_1.default.createElement(react_native_1.Text, { style: styles.rotateIconText }, "\u21BB"),
541
526
  react_1.default.createElement(react_native_1.Text, { style: styles.rotateButtonLabel }, "\uC6B0\uB85C 90\u00B0")))) : null,
527
+ isBusinessMode && capturedPhotos.length === 0 && (react_1.default.createElement(react_native_1.TouchableOpacity, { style: styles.captureBackButton, onPress: handleCaptureSecondPhoto, accessibilityLabel: mergedStrings.secondBtn, accessibilityRole: "button" },
528
+ react_1.default.createElement(react_native_1.Text, { style: styles.captureBackButtonText }, mergedStrings.secondBtn))),
542
529
  react_1.default.createElement(react_native_1.Image, { source: { uri: croppedImageData.path }, style: [
543
530
  styles.previewImage,
544
531
  { transform: [{ rotate: `${rotationDegrees}deg` }] }
@@ -546,12 +533,8 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
546
533
  react_1.default.createElement(react_native_1.View, { style: styles.confirmationButtons },
547
534
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.retakeButton], onPress: handleRetake, accessibilityLabel: mergedStrings.retake, accessibilityRole: "button" },
548
535
  react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.retake)),
549
- isBusinessMode && capturedPhotos.length === 0 ? (react_1.default.createElement(react_1.default.Fragment, null,
550
- react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.confirmButtonPrimary], onPress: handleCaptureSecondPhoto, accessibilityLabel: mergedStrings.secondBtn, accessibilityRole: "button" },
551
- react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.secondBtn)),
552
- react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.skipButton], onPress: handleSkipSecondPhoto, accessibilityLabel: mergedStrings.confirm, accessibilityRole: "button" },
553
- react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.confirm)))) : (react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.confirmButtonPrimary], onPress: handleConfirm, accessibilityLabel: mergedStrings.confirm, accessibilityRole: "button" },
554
- react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.confirm)))))) : (react_1.default.createElement(react_native_1.View, { style: styles.flex },
536
+ react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.confirmButtonPrimary], onPress: handleConfirm, accessibilityLabel: mergedStrings.confirm, accessibilityRole: "button" },
537
+ react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.confirm))))) : (react_1.default.createElement(react_native_1.View, { style: styles.flex },
555
538
  react_1.default.createElement(DocScanner_1.DocScanner, { 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 },
556
539
  react_1.default.createElement(react_native_1.View, { style: styles.overlayTop, pointerEvents: "box-none" },
557
540
  react_1.default.createElement(react_native_1.TouchableOpacity, { style: [
@@ -814,4 +797,24 @@ const styles = react_native_1.StyleSheet.create({
814
797
  paddingVertical: 6,
815
798
  borderRadius: 16,
816
799
  },
800
+ captureBackButton: {
801
+ position: 'absolute',
802
+ bottom: 140,
803
+ left: 0,
804
+ right: 0,
805
+ alignItems: 'center',
806
+ zIndex: 15,
807
+ },
808
+ captureBackButtonText: {
809
+ color: '#fff',
810
+ fontSize: 16,
811
+ fontWeight: '600',
812
+ // backgroundColor: 'rgba(255,100,50,0.9)',
813
+ paddingHorizontal: 32,
814
+ paddingVertical: 14,
815
+ borderRadius: 24,
816
+ borderWidth: 2,
817
+ borderColor: '#fff',
818
+ overflow: 'hidden',
819
+ },
817
820
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.117.0",
3
+ "version": "3.118.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -191,7 +191,6 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
191
191
  const rectangleHintTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
192
192
 
193
193
  const isBusinessMode = type === 'business';
194
- const maxPhotos = isBusinessMode ? 2 : 1;
195
194
 
196
195
  const mergedStrings = useMemo(
197
196
  () => ({
@@ -529,10 +528,10 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
529
528
  };
530
529
 
531
530
  const updatedPhotos = [...capturedPhotos, currentPhoto];
532
- console.log('[FullDocScanner] Photos captured:', updatedPhotos.length, 'of', maxPhotos);
531
+ console.log('[FullDocScanner] Photos captured:', updatedPhotos.length);
533
532
 
534
- // 모든 사진 촬영 완료 - 결과 반환
535
- console.log('[FullDocScanner] All photos captured, returning results');
533
+ // 결과 반환
534
+ console.log('[FullDocScanner] Returning results');
536
535
  onResult(updatedPhotos);
537
536
  }, [croppedImageData, rotationDegrees, capturedPhotos, onResult]);
538
537
 
@@ -575,23 +574,6 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
575
574
  }
576
575
  }, [croppedImageData, rotationDegrees]);
577
576
 
578
- const handleSkipSecondPhoto = useCallback(() => {
579
- console.log('[FullDocScanner] Skipping second photo - saving current photo only');
580
-
581
- if (!croppedImageData) {
582
- return;
583
- }
584
-
585
- // 현재 사진만 저장하고 완료
586
- const rotationNormalized = ((rotationDegrees % 360) + 360) % 360;
587
- const currentPhoto: FullDocScannerResult = {
588
- path: croppedImageData.path,
589
- base64: croppedImageData.base64,
590
- rotationDegrees: rotationNormalized,
591
- };
592
-
593
- onResult([currentPhoto]);
594
- }, [croppedImageData, rotationDegrees, onResult]);
595
577
 
596
578
  const handleRetake = useCallback(() => {
597
579
  console.log('[FullDocScanner] Retake - clearing cropped image and resetting scanner');
@@ -722,6 +704,19 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
722
704
  </TouchableOpacity>
723
705
  </View>
724
706
  ) : null}
707
+
708
+ {/* 뒷면 촬영 버튼 - 상단에 표시 (Business 모드이고 첫 번째 사진일 때만) */}
709
+ {isBusinessMode && capturedPhotos.length === 0 && (
710
+ <TouchableOpacity
711
+ style={styles.captureBackButton}
712
+ onPress={handleCaptureSecondPhoto}
713
+ accessibilityLabel={mergedStrings.secondBtn}
714
+ accessibilityRole="button"
715
+ >
716
+ <Text style={styles.captureBackButtonText}>{mergedStrings.secondBtn}</Text>
717
+ </TouchableOpacity>
718
+ )}
719
+
725
720
  <Image
726
721
  source={{ uri: croppedImageData.path }}
727
722
  style={[
@@ -740,36 +735,14 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
740
735
  <Text style={styles.confirmButtonText}>{mergedStrings.retake}</Text>
741
736
  </TouchableOpacity>
742
737
 
743
- {/* Business 모드이고 첫 번째 사진일 때: 뒷면 촬영 버튼과 확인 버튼 동시 표시 */}
744
- {isBusinessMode && capturedPhotos.length === 0 ? (
745
- <>
746
- <TouchableOpacity
747
- style={[styles.confirmButton, styles.confirmButtonPrimary]}
748
- onPress={handleCaptureSecondPhoto}
749
- accessibilityLabel={mergedStrings.secondBtn}
750
- accessibilityRole="button"
751
- >
752
- <Text style={styles.confirmButtonText}>{mergedStrings.secondBtn}</Text>
753
- </TouchableOpacity>
754
- <TouchableOpacity
755
- style={[styles.confirmButton, styles.skipButton]}
756
- onPress={handleSkipSecondPhoto}
757
- accessibilityLabel={mergedStrings.confirm}
758
- accessibilityRole="button"
759
- >
760
- <Text style={styles.confirmButtonText}>{mergedStrings.confirm}</Text>
761
- </TouchableOpacity>
762
- </>
763
- ) : (
764
- <TouchableOpacity
765
- style={[styles.confirmButton, styles.confirmButtonPrimary]}
766
- onPress={handleConfirm}
767
- accessibilityLabel={mergedStrings.confirm}
768
- accessibilityRole="button"
769
- >
770
- <Text style={styles.confirmButtonText}>{mergedStrings.confirm}</Text>
771
- </TouchableOpacity>
772
- )}
738
+ <TouchableOpacity
739
+ style={[styles.confirmButton, styles.confirmButtonPrimary]}
740
+ onPress={handleConfirm}
741
+ accessibilityLabel={mergedStrings.confirm}
742
+ accessibilityRole="button"
743
+ >
744
+ <Text style={styles.confirmButtonText}>{mergedStrings.confirm}</Text>
745
+ </TouchableOpacity>
773
746
  </View>
774
747
  </View>
775
748
  ) : (
@@ -1112,4 +1085,24 @@ const styles = StyleSheet.create({
1112
1085
  paddingVertical: 6,
1113
1086
  borderRadius: 16,
1114
1087
  },
1088
+ captureBackButton: {
1089
+ position: 'absolute',
1090
+ bottom: 140,
1091
+ left: 0,
1092
+ right: 0,
1093
+ alignItems: 'center',
1094
+ zIndex: 15,
1095
+ },
1096
+ captureBackButtonText: {
1097
+ color: '#fff',
1098
+ fontSize: 16,
1099
+ fontWeight: '600',
1100
+ // backgroundColor: 'rgba(255,100,50,0.9)',
1101
+ paddingHorizontal: 32,
1102
+ paddingVertical: 14,
1103
+ borderRadius: 24,
1104
+ borderWidth: 2,
1105
+ borderColor: '#fff',
1106
+ overflow: 'hidden',
1107
+ },
1115
1108
  });