react-native-rectangle-doc-scanner 3.114.0 → 3.117.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.
- package/dist/FullDocScanner.d.ts +1 -0
- package/dist/FullDocScanner.js +49 -16
- package/package.json +1 -1
- package/src/FullDocScanner.tsx +59 -18
package/dist/FullDocScanner.d.ts
CHANGED
package/dist/FullDocScanner.js
CHANGED
|
@@ -145,6 +145,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
145
145
|
first: strings?.first ?? 'Front',
|
|
146
146
|
second: strings?.second ?? 'Back',
|
|
147
147
|
secondBtn: strings?.secondBtn ?? 'Capture Back Side?',
|
|
148
|
+
secondPrompt: strings?.secondPrompt ?? strings?.secondBtn ?? 'Capture Back Side?',
|
|
148
149
|
}), [strings]);
|
|
149
150
|
const emitError = (0, react_1.useCallback)((error, fallbackMessage) => {
|
|
150
151
|
console.error('[FullDocScanner] error', error);
|
|
@@ -392,20 +393,24 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
392
393
|
};
|
|
393
394
|
const updatedPhotos = [...capturedPhotos, currentPhoto];
|
|
394
395
|
console.log('[FullDocScanner] Photos captured:', updatedPhotos.length, 'of', maxPhotos);
|
|
395
|
-
// Business 모드이고 아직 첫 번째 사진만 찍은 경우
|
|
396
|
-
if (isBusinessMode && updatedPhotos.length === 1) {
|
|
397
|
-
// 두 번째 사진 촬영 여부를 물어봄 (UI에서 버튼으로 표시)
|
|
398
|
-
setCapturedPhotos(updatedPhotos);
|
|
399
|
-
setCurrentPhotoIndex(1);
|
|
400
|
-
// 확인 화면을 유지하고 "뒷면 촬영" 버튼을 표시
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
396
|
// 모든 사진 촬영 완료 - 결과 반환
|
|
404
397
|
console.log('[FullDocScanner] All photos captured, returning results');
|
|
405
398
|
onResult(updatedPhotos);
|
|
406
|
-
}, [croppedImageData, rotationDegrees, capturedPhotos,
|
|
399
|
+
}, [croppedImageData, rotationDegrees, capturedPhotos, onResult]);
|
|
407
400
|
const handleCaptureSecondPhoto = (0, react_1.useCallback)(() => {
|
|
408
401
|
console.log('[FullDocScanner] Capturing second photo');
|
|
402
|
+
if (!croppedImageData) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
// 현재 사진(앞면)을 먼저 저장
|
|
406
|
+
const rotationNormalized = ((rotationDegrees % 360) + 360) % 360;
|
|
407
|
+
const currentPhoto = {
|
|
408
|
+
path: croppedImageData.path,
|
|
409
|
+
base64: croppedImageData.base64,
|
|
410
|
+
rotationDegrees: rotationNormalized,
|
|
411
|
+
};
|
|
412
|
+
setCapturedPhotos([currentPhoto]);
|
|
413
|
+
setCurrentPhotoIndex(1);
|
|
409
414
|
// 확인 화면을 닫고 카메라로 돌아감
|
|
410
415
|
setCroppedImageData(null);
|
|
411
416
|
setRotationDegrees(0);
|
|
@@ -425,14 +430,34 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
425
430
|
if (docScannerRef.current?.reset) {
|
|
426
431
|
docScannerRef.current.reset();
|
|
427
432
|
}
|
|
428
|
-
}, []);
|
|
433
|
+
}, [croppedImageData, rotationDegrees]);
|
|
429
434
|
const handleSkipSecondPhoto = (0, react_1.useCallback)(() => {
|
|
430
|
-
console.log('[FullDocScanner] Skipping second photo');
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
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]);
|
|
434
448
|
const handleRetake = (0, react_1.useCallback)(() => {
|
|
435
449
|
console.log('[FullDocScanner] Retake - clearing cropped image and resetting scanner');
|
|
450
|
+
// Business 모드에서 두 번째 사진을 다시 찍는 경우, 첫 번째 사진 유지
|
|
451
|
+
if (isBusinessMode && capturedPhotos.length === 1) {
|
|
452
|
+
console.log('[FullDocScanner] Retake detected on back photo - keeping front photo');
|
|
453
|
+
setCurrentPhotoIndex(1);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
// 첫 번째 사진 또는 일반 모드: 모든 상태 초기화
|
|
457
|
+
console.log('[FullDocScanner] Retake detected - resetting all photos');
|
|
458
|
+
setCapturedPhotos([]);
|
|
459
|
+
setCurrentPhotoIndex(0);
|
|
460
|
+
}
|
|
436
461
|
setCroppedImageData(null);
|
|
437
462
|
setRotationDegrees(0);
|
|
438
463
|
setProcessing(false);
|
|
@@ -452,7 +477,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
452
477
|
if (docScannerRef.current?.reset) {
|
|
453
478
|
docScannerRef.current.reset();
|
|
454
479
|
}
|
|
455
|
-
}, []);
|
|
480
|
+
}, [capturedPhotos.length, isBusinessMode]);
|
|
456
481
|
const handleRectangleDetect = (0, react_1.useCallback)((event) => {
|
|
457
482
|
const stableCounter = event.stableCounter ?? 0;
|
|
458
483
|
const rectangleCoordinates = event.rectangleOnScreen ?? event.rectangleCoordinates;
|
|
@@ -521,7 +546,7 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
|
|
|
521
546
|
react_1.default.createElement(react_native_1.View, { style: styles.confirmationButtons },
|
|
522
547
|
react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.retakeButton], onPress: handleRetake, accessibilityLabel: mergedStrings.retake, accessibilityRole: "button" },
|
|
523
548
|
react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.retake)),
|
|
524
|
-
isBusinessMode && capturedPhotos.length ===
|
|
549
|
+
isBusinessMode && capturedPhotos.length === 0 ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
525
550
|
react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.confirmButtonPrimary], onPress: handleCaptureSecondPhoto, accessibilityLabel: mergedStrings.secondBtn, accessibilityRole: "button" },
|
|
526
551
|
react_1.default.createElement(react_native_1.Text, { style: styles.confirmButtonText }, mergedStrings.secondBtn)),
|
|
527
552
|
react_1.default.createElement(react_native_1.TouchableOpacity, { style: [styles.confirmButton, styles.skipButton], onPress: handleSkipSecondPhoto, accessibilityLabel: mergedStrings.confirm, accessibilityRole: "button" },
|
|
@@ -718,6 +743,14 @@ const styles = react_native_1.StyleSheet.create({
|
|
|
718
743
|
width: '100%',
|
|
719
744
|
height: '80%',
|
|
720
745
|
},
|
|
746
|
+
confirmationPromptText: {
|
|
747
|
+
color: '#fff',
|
|
748
|
+
fontSize: 18,
|
|
749
|
+
fontWeight: '600',
|
|
750
|
+
textAlign: 'center',
|
|
751
|
+
paddingHorizontal: 32,
|
|
752
|
+
marginTop: 24,
|
|
753
|
+
},
|
|
721
754
|
confirmationButtons: {
|
|
722
755
|
flexDirection: 'row',
|
|
723
756
|
justifyContent: 'center',
|
package/package.json
CHANGED
package/src/FullDocScanner.tsx
CHANGED
|
@@ -138,6 +138,7 @@ export interface FullDocScannerStrings {
|
|
|
138
138
|
first?: string;
|
|
139
139
|
second?: string;
|
|
140
140
|
secondBtn?: string;
|
|
141
|
+
secondPrompt?: string;
|
|
141
142
|
}
|
|
142
143
|
|
|
143
144
|
export interface FullDocScannerProps {
|
|
@@ -205,6 +206,7 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
205
206
|
first: strings?.first ?? 'Front',
|
|
206
207
|
second: strings?.second ?? 'Back',
|
|
207
208
|
secondBtn: strings?.secondBtn ?? 'Capture Back Side?',
|
|
209
|
+
secondPrompt: strings?.secondPrompt ?? strings?.secondBtn ?? 'Capture Back Side?',
|
|
208
210
|
}),
|
|
209
211
|
[strings],
|
|
210
212
|
);
|
|
@@ -529,22 +531,29 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
529
531
|
const updatedPhotos = [...capturedPhotos, currentPhoto];
|
|
530
532
|
console.log('[FullDocScanner] Photos captured:', updatedPhotos.length, 'of', maxPhotos);
|
|
531
533
|
|
|
532
|
-
// Business 모드이고 아직 첫 번째 사진만 찍은 경우
|
|
533
|
-
if (isBusinessMode && updatedPhotos.length === 1) {
|
|
534
|
-
// 두 번째 사진 촬영 여부를 물어봄 (UI에서 버튼으로 표시)
|
|
535
|
-
setCapturedPhotos(updatedPhotos);
|
|
536
|
-
setCurrentPhotoIndex(1);
|
|
537
|
-
// 확인 화면을 유지하고 "뒷면 촬영" 버튼을 표시
|
|
538
|
-
return;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
534
|
// 모든 사진 촬영 완료 - 결과 반환
|
|
542
535
|
console.log('[FullDocScanner] All photos captured, returning results');
|
|
543
536
|
onResult(updatedPhotos);
|
|
544
|
-
}, [croppedImageData, rotationDegrees, capturedPhotos,
|
|
537
|
+
}, [croppedImageData, rotationDegrees, capturedPhotos, onResult]);
|
|
545
538
|
|
|
546
539
|
const handleCaptureSecondPhoto = useCallback(() => {
|
|
547
540
|
console.log('[FullDocScanner] Capturing second photo');
|
|
541
|
+
|
|
542
|
+
if (!croppedImageData) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// 현재 사진(앞면)을 먼저 저장
|
|
547
|
+
const rotationNormalized = ((rotationDegrees % 360) + 360) % 360;
|
|
548
|
+
const currentPhoto: FullDocScannerResult = {
|
|
549
|
+
path: croppedImageData.path,
|
|
550
|
+
base64: croppedImageData.base64,
|
|
551
|
+
rotationDegrees: rotationNormalized,
|
|
552
|
+
};
|
|
553
|
+
|
|
554
|
+
setCapturedPhotos([currentPhoto]);
|
|
555
|
+
setCurrentPhotoIndex(1);
|
|
556
|
+
|
|
548
557
|
// 확인 화면을 닫고 카메라로 돌아감
|
|
549
558
|
setCroppedImageData(null);
|
|
550
559
|
setRotationDegrees(0);
|
|
@@ -564,16 +573,40 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
564
573
|
if (docScannerRef.current?.reset) {
|
|
565
574
|
docScannerRef.current.reset();
|
|
566
575
|
}
|
|
567
|
-
}, []);
|
|
576
|
+
}, [croppedImageData, rotationDegrees]);
|
|
568
577
|
|
|
569
578
|
const handleSkipSecondPhoto = useCallback(() => {
|
|
570
|
-
console.log('[FullDocScanner] Skipping second photo');
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
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]);
|
|
574
595
|
|
|
575
596
|
const handleRetake = useCallback(() => {
|
|
576
597
|
console.log('[FullDocScanner] Retake - clearing cropped image and resetting scanner');
|
|
598
|
+
|
|
599
|
+
// Business 모드에서 두 번째 사진을 다시 찍는 경우, 첫 번째 사진 유지
|
|
600
|
+
if (isBusinessMode && capturedPhotos.length === 1) {
|
|
601
|
+
console.log('[FullDocScanner] Retake detected on back photo - keeping front photo');
|
|
602
|
+
setCurrentPhotoIndex(1);
|
|
603
|
+
} else {
|
|
604
|
+
// 첫 번째 사진 또는 일반 모드: 모든 상태 초기화
|
|
605
|
+
console.log('[FullDocScanner] Retake detected - resetting all photos');
|
|
606
|
+
setCapturedPhotos([]);
|
|
607
|
+
setCurrentPhotoIndex(0);
|
|
608
|
+
}
|
|
609
|
+
|
|
577
610
|
setCroppedImageData(null);
|
|
578
611
|
setRotationDegrees(0);
|
|
579
612
|
setProcessing(false);
|
|
@@ -593,7 +626,7 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
593
626
|
if (docScannerRef.current?.reset) {
|
|
594
627
|
docScannerRef.current.reset();
|
|
595
628
|
}
|
|
596
|
-
}, []);
|
|
629
|
+
}, [capturedPhotos.length, isBusinessMode]);
|
|
597
630
|
|
|
598
631
|
const handleRectangleDetect = useCallback((event: RectangleDetectEvent) => {
|
|
599
632
|
const stableCounter = event.stableCounter ?? 0;
|
|
@@ -707,8 +740,8 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
|
|
|
707
740
|
<Text style={styles.confirmButtonText}>{mergedStrings.retake}</Text>
|
|
708
741
|
</TouchableOpacity>
|
|
709
742
|
|
|
710
|
-
{/* Business 모드이고 첫 번째
|
|
711
|
-
{isBusinessMode && capturedPhotos.length ===
|
|
743
|
+
{/* Business 모드이고 첫 번째 사진일 때: 뒷면 촬영 버튼과 확인 버튼 동시 표시 */}
|
|
744
|
+
{isBusinessMode && capturedPhotos.length === 0 ? (
|
|
712
745
|
<>
|
|
713
746
|
<TouchableOpacity
|
|
714
747
|
style={[styles.confirmButton, styles.confirmButtonPrimary]}
|
|
@@ -1008,6 +1041,14 @@ const styles = StyleSheet.create({
|
|
|
1008
1041
|
width: '100%',
|
|
1009
1042
|
height: '80%',
|
|
1010
1043
|
},
|
|
1044
|
+
confirmationPromptText: {
|
|
1045
|
+
color: '#fff',
|
|
1046
|
+
fontSize: 18,
|
|
1047
|
+
fontWeight: '600',
|
|
1048
|
+
textAlign: 'center',
|
|
1049
|
+
paddingHorizontal: 32,
|
|
1050
|
+
marginTop: 24,
|
|
1051
|
+
},
|
|
1011
1052
|
confirmationButtons: {
|
|
1012
1053
|
flexDirection: 'row',
|
|
1013
1054
|
justifyContent: 'center',
|