react-native-rectangle-doc-scanner 3.68.0 → 3.69.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.
@@ -279,35 +279,44 @@ const FullDocScanner = ({ onResult, onClose, detectionConfig, overlayColor = '#3
279
279
  }, []);
280
280
  const handleRectangleDetect = (0, react_1.useCallback)((event) => {
281
281
  const stableCounter = event.stableCounter ?? 0;
282
- const hasRectangle = Boolean(event.rectangleOnScreen ?? event.rectangleCoordinates);
283
- const isGoodRectangle = hasRectangle && event.lastDetectionType === 0;
284
- // Clear timeout immediately when rectangle is lost
285
- if (!hasRectangle || !isGoodRectangle) {
282
+ const rectangleCoordinates = event.rectangleOnScreen ?? event.rectangleCoordinates;
283
+ const hasRectangle = Boolean(rectangleCoordinates);
284
+ const isConfidentRectangle = hasRectangle && (event.lastDetectionType === 0 || stableCounter > 0);
285
+ const scheduleDetectionClear = () => {
286
286
  if (rectangleTimeoutRef.current) {
287
287
  clearTimeout(rectangleTimeoutRef.current);
288
- rectangleTimeoutRef.current = null;
289
288
  }
290
- setRectangleDetected(false);
289
+ rectangleTimeoutRef.current = setTimeout(() => {
290
+ rectangleTimeoutRef.current = null;
291
+ setRectangleDetected((prev) => {
292
+ if (!prev) {
293
+ return prev;
294
+ }
295
+ console.log('[FullDocScanner] Rectangle timeout - clearing detection');
296
+ return false;
297
+ });
298
+ }, 350);
299
+ };
300
+ if (isConfidentRectangle) {
301
+ scheduleDetectionClear();
302
+ setRectangleDetected((prev) => (prev ? prev : true));
291
303
  }
292
- else {
293
- // Rectangle detected - clear any existing timeout
304
+ else if (!hasRectangle) {
294
305
  if (rectangleTimeoutRef.current) {
295
306
  clearTimeout(rectangleTimeoutRef.current);
296
- }
297
- setRectangleDetected(true);
298
- // Set timeout to clear rectangle after brief period of no updates
299
- rectangleTimeoutRef.current = setTimeout(() => {
300
307
  rectangleTimeoutRef.current = null;
301
- setRectangleDetected(false);
302
- console.log('[FullDocScanner] Rectangle timeout - clearing detection');
303
- }, 300);
308
+ }
309
+ setRectangleDetected(false);
310
+ }
311
+ else {
312
+ // Rectangle is present but confidence is low – keep current state but schedule a clear
313
+ scheduleDetectionClear();
304
314
  }
305
315
  console.log('[FullDocScanner] Rectangle detection update', {
306
316
  lastDetectionType: event.lastDetectionType,
307
317
  stableCounter,
308
318
  hasRectangle,
309
- isGoodRectangle,
310
- rectangleDetected: isGoodRectangle,
319
+ isConfidentRectangle,
311
320
  });
312
321
  }, []);
313
322
  (0, react_1.useEffect)(() => () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-rectangle-doc-scanner",
3
- "version": "3.68.0",
3
+ "version": "3.69.0",
4
4
  "description": "Native-backed document scanner for React Native with customizable overlays.",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -367,37 +367,46 @@ export const FullDocScanner: React.FC<FullDocScannerProps> = ({
367
367
 
368
368
  const handleRectangleDetect = useCallback((event: RectangleDetectEvent) => {
369
369
  const stableCounter = event.stableCounter ?? 0;
370
- const hasRectangle = Boolean(event.rectangleOnScreen ?? event.rectangleCoordinates);
371
- const isGoodRectangle = hasRectangle && event.lastDetectionType === 0;
370
+ const rectangleCoordinates = event.rectangleOnScreen ?? event.rectangleCoordinates;
371
+ const hasRectangle = Boolean(rectangleCoordinates);
372
+ const isConfidentRectangle = hasRectangle && (event.lastDetectionType === 0 || stableCounter > 0);
372
373
 
373
- // Clear timeout immediately when rectangle is lost
374
- if (!hasRectangle || !isGoodRectangle) {
374
+ const scheduleDetectionClear = () => {
375
375
  if (rectangleTimeoutRef.current) {
376
376
  clearTimeout(rectangleTimeoutRef.current);
377
- rectangleTimeoutRef.current = null;
378
377
  }
379
- setRectangleDetected(false);
380
- } else {
381
- // Rectangle detected - clear any existing timeout
382
- if (rectangleTimeoutRef.current) {
383
- clearTimeout(rectangleTimeoutRef.current);
384
- }
385
- setRectangleDetected(true);
386
378
 
387
- // Set timeout to clear rectangle after brief period of no updates
388
379
  rectangleTimeoutRef.current = setTimeout(() => {
389
380
  rectangleTimeoutRef.current = null;
390
- setRectangleDetected(false);
391
- console.log('[FullDocScanner] Rectangle timeout - clearing detection');
392
- }, 300);
381
+ setRectangleDetected((prev) => {
382
+ if (!prev) {
383
+ return prev;
384
+ }
385
+ console.log('[FullDocScanner] Rectangle timeout - clearing detection');
386
+ return false;
387
+ });
388
+ }, 350);
389
+ };
390
+
391
+ if (isConfidentRectangle) {
392
+ scheduleDetectionClear();
393
+ setRectangleDetected((prev) => (prev ? prev : true));
394
+ } else if (!hasRectangle) {
395
+ if (rectangleTimeoutRef.current) {
396
+ clearTimeout(rectangleTimeoutRef.current);
397
+ rectangleTimeoutRef.current = null;
398
+ }
399
+ setRectangleDetected(false);
400
+ } else {
401
+ // Rectangle is present but confidence is low – keep current state but schedule a clear
402
+ scheduleDetectionClear();
393
403
  }
394
404
 
395
405
  console.log('[FullDocScanner] Rectangle detection update', {
396
406
  lastDetectionType: event.lastDetectionType,
397
407
  stableCounter,
398
408
  hasRectangle,
399
- isGoodRectangle,
400
- rectangleDetected: isGoodRectangle,
409
+ isConfidentRectangle,
401
410
  });
402
411
  }, []);
403
412
 
@@ -35,22 +35,27 @@ RCT_EXPORT_VIEW_PROPERTY(brightness, float)
35
35
  RCT_EXPORT_VIEW_PROPERTY(contrast, float)
36
36
 
37
37
  // Main capture method - returns a Promise
38
- RCT_EXPORT_METHOD(capture:(nullable NSNumber *)reactTag
38
+ RCT_EXPORT_METHOD(capture:(nullable id)reactTag
39
39
  resolver:(RCTPromiseResolveBlock)resolve
40
40
  rejecter:(RCTPromiseRejectBlock)reject) {
41
41
  NSLog(@"[RNPdfScannerManager] capture called with reactTag: %@", reactTag);
42
42
  dispatch_async(dispatch_get_main_queue(), ^{
43
43
  DocumentScannerView *targetView = nil;
44
+ NSNumber *resolvedTag = ([reactTag isKindOfClass:[NSNumber class]]) ? (NSNumber *)reactTag : nil;
44
45
 
45
- if (reactTag) {
46
- UIView *view = [self.bridge.uiManager viewForReactTag:reactTag];
46
+ if (!resolvedTag && reactTag) {
47
+ NSLog(@"[RNPdfScannerManager] Unexpected reactTag type %@ - falling back to last known view", NSStringFromClass([reactTag class]));
48
+ }
49
+
50
+ if (resolvedTag) {
51
+ UIView *view = [self.bridge.uiManager viewForReactTag:resolvedTag];
47
52
  if ([view isKindOfClass:[DocumentScannerView class]]) {
48
53
  targetView = (DocumentScannerView *)view;
49
54
  self->_scannerView = targetView;
50
55
  } else if (view) {
51
- NSLog(@"[RNPdfScannerManager] View for tag %@ is not DocumentScannerView: %@", reactTag, NSStringFromClass(view.class));
56
+ NSLog(@"[RNPdfScannerManager] View for tag %@ is not DocumentScannerView: %@", resolvedTag, NSStringFromClass(view.class));
52
57
  } else {
53
- NSLog(@"[RNPdfScannerManager] No view found for tag %@", reactTag);
58
+ NSLog(@"[RNPdfScannerManager] No view found for tag %@", resolvedTag);
54
59
  }
55
60
  }
56
61