@trustchex/react-native-sdk 1.513.1 → 1.513.2
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/lib/module/Shared/Components/IdentityDocumentCamera.js +25 -152
- package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +1 -9
- package/lib/module/Translation/Resources/en.js +0 -2
- package/lib/module/Translation/Resources/tr.js +0 -2
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/en.d.ts +0 -2
- package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/tr.d.ts +0 -2
- package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/Shared/Components/IdentityDocumentCamera.tsx +19 -195
- package/src/Shared/Components/IdentityDocumentCamera.utils.ts +0 -9
- package/src/Translation/Resources/en.ts +0 -4
- package/src/Translation/Resources/tr.ts +0 -4
- package/src/version.ts +1 -1
|
@@ -24,7 +24,7 @@ import { useTheme } from "../Contexts/ThemeContext.js";
|
|
|
24
24
|
import DebugOverlay, { TestModePanel } from "./DebugOverlay.js";
|
|
25
25
|
import { getStatusMessage, getFrameToScreenTransform, transformBoundsToScreen, getScanAreaBounds, angleBetweenPoints, detectDocumentType, determineDocumentTypeToSet, areMRZFieldsEqual, hasRequiredMRZFields, validateFacePosition, isPassportDocumentCode, StableFlag } from "./IdentityDocumentCamera.utils.js";
|
|
26
26
|
import { handlePassportFlow, handleIDFrontFlow, handleIDBackFlow, getNextStepAfterHologram } from "./IdentityDocumentCamera.flows.js";
|
|
27
|
-
import { HOLOGRAM_IMAGE_COUNT, HOLOGRAM_DETECTION_THRESHOLD, HOLOGRAM_DETECTION_RETRY_COUNT, HOLOGRAM_CAPTURE_INTERVAL, HOLOGRAM_MAX_FRAMES_WITHOUT_FACE, MIN_BRIGHTNESS_THRESHOLD,
|
|
27
|
+
import { HOLOGRAM_IMAGE_COUNT, HOLOGRAM_DETECTION_THRESHOLD, HOLOGRAM_DETECTION_RETRY_COUNT, HOLOGRAM_CAPTURE_INTERVAL, HOLOGRAM_MAX_FRAMES_WITHOUT_FACE, MIN_BRIGHTNESS_THRESHOLD, FACE_EDGE_MARGIN_PERCENT, MAX_CONSECUTIVE_QUALITY_FAILURES, REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS, HELP_PROMPT_DELAY_MS, SIGNATURE_TEXT_REGEX, MRZ_BLOCK_PATTERN, MIN_CARD_FACE_SIZE_PERCENT } from "./IdentityDocumentCamera.constants.js";
|
|
28
28
|
|
|
29
29
|
// Re-export types for backward compatibility
|
|
30
30
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
@@ -72,11 +72,6 @@ const IdentityDocumentCamera = ({
|
|
|
72
72
|
const [currentSecondaryFaceImage, setCurrentSecondaryFaceImage] = useState(undefined);
|
|
73
73
|
const [isBrightnessLow, setIsBrightnessLow] = useState(false);
|
|
74
74
|
const [isFrameBlurry, setIsFrameBlurry] = useState(false);
|
|
75
|
-
// Glare was being silently rejected (frames dropped with no user feedback), so
|
|
76
|
-
// a user fighting reflections just saw the scan hang. Surface it so we can show
|
|
77
|
-
// an actionable "move away from glare" hint. Set at each glare rejection;
|
|
78
|
-
// cleared when a frame passes the brightness check (a fresh, glare-free frame).
|
|
79
|
-
const [isGlareDetected, setIsGlareDetected] = useState(false);
|
|
80
75
|
const [hasGuideShown, setHasGuideShown] = useState(false);
|
|
81
76
|
// "Having trouble?" escape: if a scan step doesn't complete within
|
|
82
77
|
// HELP_PROMPT_DELAY_MS the user is otherwise stuck on a live camera forever
|
|
@@ -99,7 +94,7 @@ const IdentityDocumentCamera = ({
|
|
|
99
94
|
const consecutiveQualityFailures = useRef(0);
|
|
100
95
|
const mrzDetectionCurrentRetryCount = useRef(0);
|
|
101
96
|
|
|
102
|
-
// Hysteresis for the on-screen quality guidance. Brightness/blur
|
|
97
|
+
// Hysteresis for the on-screen quality guidance. Brightness/blur are
|
|
103
98
|
// measured every frame; feeding the raw per-frame booleans straight into
|
|
104
99
|
// state made the guidance strobe (a single blurry hand-shake frame flipped
|
|
105
100
|
// "hold steady" on and off). These smooth each flag: it appears after a few
|
|
@@ -108,19 +103,11 @@ const IdentityDocumentCamera = ({
|
|
|
108
103
|
// problems), clear slow (don't flicker off on one good frame).
|
|
109
104
|
const brightnessLowFlag = useRef(new StableFlag(2, 5));
|
|
110
105
|
const blurryFlag = useRef(new StableFlag(3, 6));
|
|
111
|
-
const glareFlag = useRef(new StableFlag(2, 5));
|
|
112
|
-
// Glare is asserted by accept-time helpers that run inside the (separately
|
|
113
|
-
// scoped) handleFaceAndText callback, so it can't flow through a handler
|
|
114
|
-
// local. This ref is cleared at the top of each frame and set true if any
|
|
115
|
-
// glare check in that frame found glare; the handler reads it to feed
|
|
116
|
-
// `glareFlag`. `hadGlareText` distinguishes "card present but glaring" from
|
|
117
|
-
// an empty view so the warning only shows over an actual document.
|
|
118
|
-
const rawGlareRef = useRef(false);
|
|
119
106
|
// Whether a document was visible in the PREVIOUS frame (recognized text,
|
|
120
107
|
// barcode, or face). The quality guidance is stabilized BEFORE the quality
|
|
121
108
|
// gate (so dark/blurry frames — which the gate early-returns on — can still
|
|
122
109
|
// raise their warnings), but document-presence is only known LATER in the
|
|
123
|
-
// frame, so blur
|
|
110
|
+
// frame, so blur is gated on the previous frame's value. One-frame lag
|
|
124
111
|
// at ~8fps is imperceptible and the hysteresis smooths it.
|
|
125
112
|
const documentPresentRef = useRef(false);
|
|
126
113
|
|
|
@@ -191,8 +178,7 @@ const IdentityDocumentCamera = ({
|
|
|
191
178
|
frameW: 0,
|
|
192
179
|
frameH: 0,
|
|
193
180
|
hadLowBrightness: false,
|
|
194
|
-
hadBlurryFrames: false
|
|
195
|
-
hadGlare: false
|
|
181
|
+
hadBlurryFrames: false
|
|
196
182
|
});
|
|
197
183
|
const [faceDetectionEnabled, setFaceDetectionEnabled] = useState(true);
|
|
198
184
|
const faceImages = useRef([]);
|
|
@@ -258,8 +244,7 @@ const IdentityDocumentCamera = ({
|
|
|
258
244
|
frameW: 0,
|
|
259
245
|
frameH: 0,
|
|
260
246
|
hadLowBrightness: false,
|
|
261
|
-
hadBlurryFrames: false
|
|
262
|
-
hadGlare: false
|
|
247
|
+
hadBlurryFrames: false
|
|
263
248
|
};
|
|
264
249
|
cachedBarcode.current = null;
|
|
265
250
|
isCompletionCallbackInvoked.current = false;
|
|
@@ -295,7 +280,7 @@ const IdentityDocumentCamera = ({
|
|
|
295
280
|
}, [isFocused, hasPermission, hasGuideShown]);
|
|
296
281
|
useEffect(() => {
|
|
297
282
|
if (!hasGuideShown || !appContext.currentWorkflowStep?.data?.voiceGuidanceActive) return;
|
|
298
|
-
const message = getStatusMessage(nextStep, status, detectedDocumentType, isBrightnessLow, isFrameBlurry,
|
|
283
|
+
const message = getStatusMessage(nextStep, status, detectedDocumentType, isBrightnessLow, isFrameBlurry, allElementsDetected, elementsOutsideScanArea, t);
|
|
299
284
|
if (message) {
|
|
300
285
|
if (nextStep === 'COMPLETED') {
|
|
301
286
|
if (isCompletionAnnouncementSpoken.current) {
|
|
@@ -308,7 +293,7 @@ const IdentityDocumentCamera = ({
|
|
|
308
293
|
const shouldBypassInterval = nextStep !== 'COMPLETED';
|
|
309
294
|
speak(message, shouldBypassInterval);
|
|
310
295
|
}
|
|
311
|
-
}, [appContext.currentWorkflowStep?.data?.voiceGuidanceActive, hasGuideShown, isBrightnessLow, isFrameBlurry,
|
|
296
|
+
}, [appContext.currentWorkflowStep?.data?.voiceGuidanceActive, hasGuideShown, isBrightnessLow, isFrameBlurry, nextStep, status, detectedDocumentType, allElementsDetected, elementsOutsideScanArea, t]);
|
|
312
297
|
useEffect(() => {
|
|
313
298
|
if (status === 'INCORRECT') {
|
|
314
299
|
const timeout = setTimeout(() => {
|
|
@@ -436,54 +421,12 @@ const IdentityDocumentCamera = ({
|
|
|
436
421
|
}
|
|
437
422
|
};
|
|
438
423
|
|
|
439
|
-
// Check if face image has glare (brightness exceeds threshold). Also surfaces
|
|
440
|
-
// the result to `isGlareDetected` so the user gets an actionable hint instead
|
|
441
|
-
// of a silently-stalled scan.
|
|
442
|
-
const checkFaceGlare = async faceImage => {
|
|
443
|
-
try {
|
|
444
|
-
// Check entire face region for glare
|
|
445
|
-
const hasGlare = await OpenCVModule.isRectangularRegionBright(faceImage, 0, 0, 100,
|
|
446
|
-
// Full face width
|
|
447
|
-
100,
|
|
448
|
-
// Full face height
|
|
449
|
-
MAX_BRIGHTNESS_THRESHOLD);
|
|
450
|
-
// OR-accumulate into the per-frame glare signal (reset at frame top); the
|
|
451
|
-
// frame handler feeds it through the stabilized UI flag. Also record the
|
|
452
|
-
// diagnostic.
|
|
453
|
-
if (hasGlare) {
|
|
454
|
-
rawGlareRef.current = true;
|
|
455
|
-
diagStats.current.hadGlare = true;
|
|
456
|
-
}
|
|
457
|
-
return hasGlare;
|
|
458
|
-
} catch (error) {
|
|
459
|
-
return false; // Assume no glare on error
|
|
460
|
-
}
|
|
461
|
-
};
|
|
462
|
-
|
|
463
424
|
// Check if face is fully visible (not cropped at edges)
|
|
464
425
|
const isFaceFullyVisible = (face, frameWidth, frameHeight) => {
|
|
465
426
|
const margin = FACE_EDGE_MARGIN_PERCENT;
|
|
466
427
|
const bounds = face.bounds;
|
|
467
428
|
return bounds.x >= frameWidth * margin && bounds.y >= frameHeight * margin && bounds.x + bounds.width <= frameWidth * (1 - margin) && bounds.y + bounds.height <= frameHeight * (1 - margin);
|
|
468
429
|
};
|
|
469
|
-
|
|
470
|
-
// Check if document image has glare
|
|
471
|
-
const checkDocumentGlare = async (image, width, height) => {
|
|
472
|
-
try {
|
|
473
|
-
// Check center 80% region for glare (document area)
|
|
474
|
-
const hasGlare = await OpenCVModule.isRectangularRegionBright(image, Math.round(width * 0.1), Math.round(height * 0.1), Math.round(width * 0.8), Math.round(height * 0.8), MAX_BRIGHTNESS_THRESHOLD);
|
|
475
|
-
// OR-accumulate into the per-frame glare signal (reset at frame top); the
|
|
476
|
-
// frame handler feeds it through the stabilized UI flag. Also record the
|
|
477
|
-
// diagnostic.
|
|
478
|
-
if (hasGlare) {
|
|
479
|
-
rawGlareRef.current = true;
|
|
480
|
-
diagStats.current.hadGlare = true;
|
|
481
|
-
}
|
|
482
|
-
return hasGlare;
|
|
483
|
-
} catch (error) {
|
|
484
|
-
return false;
|
|
485
|
-
}
|
|
486
|
-
};
|
|
487
430
|
const setNextStepAndVibrate = useCallback((nextStepType, fromStep) => {
|
|
488
431
|
if (fromStep) {
|
|
489
432
|
setCompletedStep(fromStep);
|
|
@@ -550,12 +493,9 @@ const IdentityDocumentCamera = ({
|
|
|
550
493
|
// carried over from the previous side).
|
|
551
494
|
brightnessLowFlag.current.reset(false);
|
|
552
495
|
blurryFlag.current.reset(false);
|
|
553
|
-
glareFlag.current.reset(false);
|
|
554
|
-
rawGlareRef.current = false;
|
|
555
496
|
documentPresentRef.current = false;
|
|
556
497
|
setIsBrightnessLow(false);
|
|
557
498
|
setIsFrameBlurry(false);
|
|
558
|
-
setIsGlareDetected(false);
|
|
559
499
|
if (nextStepType !== 'COMPLETED') {
|
|
560
500
|
setTimeout(() => {
|
|
561
501
|
setStatus('SEARCHING');
|
|
@@ -818,13 +758,11 @@ const IdentityDocumentCamera = ({
|
|
|
818
758
|
if (shouldCropFaces && croppedFaces.length > 0 && croppedFaces[0] && facePositionValid && !currentFaceImage) {
|
|
819
759
|
// Validate face quality before accepting
|
|
820
760
|
const faceFullyVisible = primaryFaces[0] && isFaceFullyVisible(primaryFaces[0], frameWidth, frameHeight);
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
// Reject face with glare or partially visible
|
|
761
|
+
if (!faceFullyVisible) {
|
|
762
|
+
// Reject partially visible face
|
|
824
763
|
if (isDebugEnabled()) {
|
|
825
764
|
debugLog('IdentityDocumentCamera', '[FACE] Rejected', {
|
|
826
|
-
fullyVisible: faceFullyVisible
|
|
827
|
-
hasGlare
|
|
765
|
+
fullyVisible: faceFullyVisible
|
|
828
766
|
});
|
|
829
767
|
}
|
|
830
768
|
// Continue scanning without locking this face
|
|
@@ -940,16 +878,6 @@ const IdentityDocumentCamera = ({
|
|
|
940
878
|
setStatus(mrzText ? 'SCANNING' : 'SEARCHING');
|
|
941
879
|
return;
|
|
942
880
|
}
|
|
943
|
-
|
|
944
|
-
// Check for glare on ID back before accepting
|
|
945
|
-
const hasGlare = await checkDocumentGlare(image, frameWidth, frameHeight);
|
|
946
|
-
if (hasGlare) {
|
|
947
|
-
if (isDebugEnabled()) {
|
|
948
|
-
debugLog('IdentityDocumentCamera', '[ID_BACK] Rejected - glare detected');
|
|
949
|
-
}
|
|
950
|
-
setStatus('SCANNING');
|
|
951
|
-
return;
|
|
952
|
-
}
|
|
953
881
|
if (isDebugEnabled()) {
|
|
954
882
|
debugLog('IdentityDocumentCamera', '[ID_BACK] MRZ validated', {
|
|
955
883
|
documentNumber: parsedMRZData?.fields?.documentNumber,
|
|
@@ -1071,22 +999,13 @@ const IdentityDocumentCamera = ({
|
|
|
1071
999
|
if (!isTorchOnRef.current) {
|
|
1072
1000
|
setIsTorchOn(true);
|
|
1073
1001
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
if (
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
if (isDebugEnabled()) {
|
|
1082
|
-
debugLog('IdentityDocumentCamera', '[HOLOGRAM] Frame captured', {
|
|
1083
|
-
frameIndex: faceImages.current.length - 1,
|
|
1084
|
-
totalFrames: faceImages.current.length
|
|
1085
|
-
});
|
|
1086
|
-
}
|
|
1087
|
-
} else if (isDebugEnabled()) {
|
|
1088
|
-
debugLog('IdentityDocumentCamera', '[HOLOGRAM] Rejected glare frame', {
|
|
1089
|
-
collectedCount: faceImages.current.length
|
|
1002
|
+
faceImages.current.push(primaryFaceOnly);
|
|
1003
|
+
lastHologramCaptureTime.current = Date.now();
|
|
1004
|
+
hologramImageCountRef.current = faceImages.current.length;
|
|
1005
|
+
if (isDebugEnabled()) {
|
|
1006
|
+
debugLog('IdentityDocumentCamera', '[HOLOGRAM] Frame captured', {
|
|
1007
|
+
frameIndex: faceImages.current.length - 1,
|
|
1008
|
+
totalFrames: faceImages.current.length
|
|
1090
1009
|
});
|
|
1091
1010
|
}
|
|
1092
1011
|
if (faceImages.current.length > 0) {
|
|
@@ -1356,16 +1275,6 @@ const IdentityDocumentCamera = ({
|
|
|
1356
1275
|
continueScanning(true);
|
|
1357
1276
|
return;
|
|
1358
1277
|
}
|
|
1359
|
-
|
|
1360
|
-
// Check for glare on passport before accepting
|
|
1361
|
-
const hasGlare = await checkDocumentGlare(image, frameWidth, frameHeight);
|
|
1362
|
-
if (hasGlare) {
|
|
1363
|
-
if (isDebugEnabled()) {
|
|
1364
|
-
debugLog('IdentityDocumentCamera', '[PASSPORT] Rejected - glare detected');
|
|
1365
|
-
}
|
|
1366
|
-
continueScanning(false);
|
|
1367
|
-
return;
|
|
1368
|
-
}
|
|
1369
1278
|
setDetectedDocumentType('PASSPORT');
|
|
1370
1279
|
setStatus('SCANNED');
|
|
1371
1280
|
const nextPassportStep = flowResult.nextAction === 'PROCEED_TO_COMPLETED' ? 'COMPLETED' : 'SCAN_HOLOGRAM';
|
|
@@ -1382,16 +1291,6 @@ const IdentityDocumentCamera = ({
|
|
|
1382
1291
|
continueScanning(flowResult.nextAction !== 'REJECT_AS_PASSPORT');
|
|
1383
1292
|
return;
|
|
1384
1293
|
}
|
|
1385
|
-
|
|
1386
|
-
// Check for glare on ID front before accepting
|
|
1387
|
-
const hasGlare = await checkDocumentGlare(image, frameWidth, frameHeight);
|
|
1388
|
-
if (hasGlare) {
|
|
1389
|
-
if (isDebugEnabled()) {
|
|
1390
|
-
debugLog('IdentityDocumentCamera', '[ID_FRONT] Rejected - glare detected');
|
|
1391
|
-
}
|
|
1392
|
-
continueScanning(false);
|
|
1393
|
-
return;
|
|
1394
|
-
}
|
|
1395
1294
|
setDetectedDocumentType('ID_FRONT');
|
|
1396
1295
|
setStatus('SCANNED');
|
|
1397
1296
|
const nextIdFrontStep = onlyMRZScan ? 'SCAN_ID_BACK' : 'SCAN_HOLOGRAM';
|
|
@@ -1460,18 +1359,6 @@ const IdentityDocumentCamera = ({
|
|
|
1460
1359
|
const rawBrightnessLow = !isRegionBright;
|
|
1461
1360
|
if (rawBrightnessLow) diagStats.current.hadLowBrightness = true;
|
|
1462
1361
|
|
|
1463
|
-
// Per-frame glare is asserted by the accept-time helpers (checkDocumentGlare
|
|
1464
|
-
// /checkFaceGlare), but those run inside handleFaceAndText which is fired
|
|
1465
|
-
// (async, un-awaited) LATER in this handler — so this frame's glare result
|
|
1466
|
-
// isn't known yet at the stabilization block below. We therefore feed the
|
|
1467
|
-
// stabilizer the PREVIOUS frame's glare signal (captured here before the
|
|
1468
|
-
// reset). At ~8fps the one-frame lag is imperceptible and the hysteresis
|
|
1469
|
-
// smooths it anyway; without this the read would always see false and the
|
|
1470
|
-
// glare warning could never fire. Reset after capturing so a now-clean
|
|
1471
|
-
// view clears (no latch).
|
|
1472
|
-
const prevFrameGlare = rawGlareRef.current;
|
|
1473
|
-
rawGlareRef.current = false;
|
|
1474
|
-
|
|
1475
1362
|
// Check blur only in center region (area of interest) to avoid false positives
|
|
1476
1363
|
// from iOS depth-of-field background blur
|
|
1477
1364
|
let isNotBlurry = true;
|
|
@@ -1521,8 +1408,8 @@ const IdentityDocumentCamera = ({
|
|
|
1521
1408
|
// MUST run BEFORE the quality-gate early-return below: a dark or blurry
|
|
1522
1409
|
// frame is exactly what makes hasAcceptableQuality false, so if this ran
|
|
1523
1410
|
// after the gate the "too dark" / "hold steady" warnings could never
|
|
1524
|
-
// raise (their triggering frames would have already returned). Blur
|
|
1525
|
-
//
|
|
1411
|
+
// raise (their triggering frames would have already returned). Blur
|
|
1412
|
+
// is gated on document presence; brightness shows regardless, since a
|
|
1526
1413
|
// dark room is worth flagging before the card is even framed.
|
|
1527
1414
|
//
|
|
1528
1415
|
// Presence combines the previous frame's confirmed value (documentPresent-
|
|
@@ -1531,13 +1418,12 @@ const IdentityDocumentCamera = ({
|
|
|
1531
1418
|
// processing). Without the raw proxy, a document that is blurry/dark from
|
|
1532
1419
|
// its very first framed moment would keep failing the quality gate and
|
|
1533
1420
|
// early-returning before documentPresentRef is ever set true — suppressing
|
|
1534
|
-
// its blur
|
|
1421
|
+
// its blur hints for ~30 frames. The proxy lets the hint fire on the
|
|
1535
1422
|
// first framed frame.
|
|
1536
1423
|
const rawDocumentPresent = (frame.faces?.length ?? 0) > 0 || (frame.textBlocks?.length ?? 0) > 0 || (frame.barcodes?.length ?? 0) > 0;
|
|
1537
1424
|
const documentWasPresent = documentPresentRef.current || rawDocumentPresent;
|
|
1538
1425
|
setIsBrightnessLow(brightnessLowFlag.current.push(rawBrightnessLow));
|
|
1539
1426
|
setIsFrameBlurry(blurryFlag.current.push(documentWasPresent && isBlurry));
|
|
1540
|
-
setIsGlareDetected(glareFlag.current.push(documentWasPresent && prevFrameGlare));
|
|
1541
1427
|
// -------------------------------------------------------------------
|
|
1542
1428
|
|
|
1543
1429
|
// Store quality metrics in ref for access in handleFaceAndText callback
|
|
@@ -1979,12 +1865,6 @@ const IdentityDocumentCamera = ({
|
|
|
1979
1865
|
current: 3,
|
|
1980
1866
|
total: 3
|
|
1981
1867
|
})}` : ''
|
|
1982
|
-
}), nextStep === 'SCAN_HOLOGRAM' && status !== 'SCANNED' && /*#__PURE__*/_jsx(TextView, {
|
|
1983
|
-
style: styles.hologramProgress,
|
|
1984
|
-
children: t('identityDocumentCamera.hologramProgress', {
|
|
1985
|
-
current: hologramImageCount,
|
|
1986
|
-
total: HOLOGRAM_IMAGE_COUNT
|
|
1987
|
-
})
|
|
1988
1868
|
}), /*#__PURE__*/_jsx(AnimatedText, {
|
|
1989
1869
|
style: [styles.topZoneText,
|
|
1990
1870
|
// Priority order for coloring (later styles override earlier ones)
|
|
@@ -1997,12 +1877,12 @@ const IdentityDocumentCamera = ({
|
|
|
1997
1877
|
opacity: errorFlashAnim
|
|
1998
1878
|
},
|
|
1999
1879
|
// 3. Warning (yellow) - quality issues
|
|
2000
|
-
(isBrightnessLow || isFrameBlurry
|
|
1880
|
+
(isBrightnessLow || isFrameBlurry) && styles.topZoneTextWarning,
|
|
2001
1881
|
// 4. Scanning (green) - all elements detected AND inside scan area
|
|
2002
|
-
status === 'SCANNING' && allElementsDetected && elementsOutsideScanArea.length === 0 && !isBrightnessLow && !isFrameBlurry &&
|
|
1882
|
+
status === 'SCANNING' && allElementsDetected && elementsOutsideScanArea.length === 0 && !isBrightnessLow && !isFrameBlurry && styles.topZoneTextScanning
|
|
2003
1883
|
// 5. Default (white) - aligning (not all detected OR elements outside scan area)
|
|
2004
1884
|
],
|
|
2005
|
-
children: getStatusMessage(nextStep, status, detectedDocumentType, isBrightnessLow, isFrameBlurry,
|
|
1885
|
+
children: getStatusMessage(nextStep, status, detectedDocumentType, isBrightnessLow, isFrameBlurry, allElementsDetected, elementsOutsideScanArea, t)
|
|
2006
1886
|
})]
|
|
2007
1887
|
}), /*#__PURE__*/_jsx(View, {
|
|
2008
1888
|
style: styles.leftZone
|
|
@@ -2034,7 +1914,7 @@ const IdentityDocumentCamera = ({
|
|
|
2034
1914
|
loop: true,
|
|
2035
1915
|
autoPlay: true
|
|
2036
1916
|
}) : null
|
|
2037
|
-
}), isDebugEnabled() && /*#__PURE__*/_jsx(DebugOverlay, {
|
|
1917
|
+
}), __DEV__ && isDebugEnabled() && /*#__PURE__*/_jsx(DebugOverlay, {
|
|
2038
1918
|
nextStep: nextStep,
|
|
2039
1919
|
status: status,
|
|
2040
1920
|
detectedDocumentType: detectedDocumentType,
|
|
@@ -2054,7 +1934,7 @@ const IdentityDocumentCamera = ({
|
|
|
2054
1934
|
hologramImageCount: hologramImageCount,
|
|
2055
1935
|
allElementsDetected: allElementsDetected,
|
|
2056
1936
|
elementsOutsideScanArea: elementsOutsideScanArea
|
|
2057
|
-
}), testMode && testModeData && /*#__PURE__*/_jsx(TestModePanel, {
|
|
1937
|
+
}), __DEV__ && testMode && testModeData && /*#__PURE__*/_jsx(TestModePanel, {
|
|
2058
1938
|
mrzText: testModeData.mrzText
|
|
2059
1939
|
}), showHelpPrompt && !helpSheetVisible && nextStep !== 'COMPLETED' && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
2060
1940
|
style: styles.helpPrompt,
|
|
@@ -2171,13 +2051,6 @@ const styles = StyleSheet.create({
|
|
|
2171
2051
|
fontWeight: '500',
|
|
2172
2052
|
marginBottom: 4
|
|
2173
2053
|
},
|
|
2174
|
-
hologramProgress: {
|
|
2175
|
-
color: '#4CAF50',
|
|
2176
|
-
fontSize: 14,
|
|
2177
|
-
textAlign: 'center',
|
|
2178
|
-
fontWeight: '600',
|
|
2179
|
-
marginBottom: 4
|
|
2180
|
-
},
|
|
2181
2054
|
topZoneText: {
|
|
2182
2055
|
color: 'white',
|
|
2183
2056
|
fontSize: 20,
|
|
@@ -147,7 +147,7 @@ export function transformBoundsToScreen(bounds, scale, offsetX, offsetY) {
|
|
|
147
147
|
* Unified status message logic used by both voice guidance and render text.
|
|
148
148
|
* Returns the appropriate i18n key arguments for the current scan state.
|
|
149
149
|
*/
|
|
150
|
-
export function getStatusMessage(nextStep, status, detectedDocumentType, isBrightnessLow, isFrameBlurry,
|
|
150
|
+
export function getStatusMessage(nextStep, status, detectedDocumentType, isBrightnessLow, isFrameBlurry, allElementsDetected, elementsOutsideScanArea, t) {
|
|
151
151
|
if (nextStep === 'COMPLETED') {
|
|
152
152
|
return t('identityDocumentCamera.scanCompleted');
|
|
153
153
|
}
|
|
@@ -173,14 +173,6 @@ export function getStatusMessage(nextStep, status, detectedDocumentType, isBrigh
|
|
|
173
173
|
if (isBrightnessLow) {
|
|
174
174
|
return t('identityDocumentCamera.lowBrightness');
|
|
175
175
|
}
|
|
176
|
-
|
|
177
|
-
// Glare is a primary failure mode (reflections off the laminate/photo). It was
|
|
178
|
-
// previously detected but never communicated, so the scan just appeared to
|
|
179
|
-
// hang. Tell the user how to fix it. Ranked above blur because a glare hotspot
|
|
180
|
-
// both blocks acceptance and often reads as a "sharp" (non-blurry) frame.
|
|
181
|
-
if (isGlareDetected) {
|
|
182
|
-
return t('identityDocumentCamera.reduceGlare');
|
|
183
|
-
}
|
|
184
176
|
if (isFrameBlurry) {
|
|
185
177
|
return t('identityDocumentCamera.avoidBlur');
|
|
186
178
|
}
|
|
@@ -182,10 +182,8 @@ export default {
|
|
|
182
182
|
'identityDocumentCamera.frontSide': 'Front',
|
|
183
183
|
'identityDocumentCamera.backSide': 'Back',
|
|
184
184
|
'identityDocumentCamera.hologramCheck': 'Hologram',
|
|
185
|
-
'identityDocumentCamera.hologramProgress': 'Capturing hologram… {{current}}/{{total}}',
|
|
186
185
|
'identityDocumentCamera.keepSteady': 'Keep device steady',
|
|
187
186
|
'identityDocumentCamera.avoidBlur': 'Keep device steady',
|
|
188
|
-
'identityDocumentCamera.reduceGlare': 'Glare detected. Tilt the document or move away from direct light.',
|
|
189
187
|
'identityDocumentCamera.wrongSideFront': 'Show the front side of your document',
|
|
190
188
|
'identityDocumentCamera.wrongSideBack': 'Show the back side of your document',
|
|
191
189
|
'identityDocumentCamera.idCardDetected': 'ID detected',
|
|
@@ -182,10 +182,8 @@ export default {
|
|
|
182
182
|
'identityDocumentCamera.frontSide': 'Ön',
|
|
183
183
|
'identityDocumentCamera.backSide': 'Arka',
|
|
184
184
|
'identityDocumentCamera.hologramCheck': 'Hologram',
|
|
185
|
-
'identityDocumentCamera.hologramProgress': 'Hologram yakalanıyor… {{current}}/{{total}}',
|
|
186
185
|
'identityDocumentCamera.keepSteady': 'Cihazı sabit tutun',
|
|
187
186
|
'identityDocumentCamera.avoidBlur': 'Cihazı sabit tutun',
|
|
188
|
-
'identityDocumentCamera.reduceGlare': 'Parlama algılandı. Belgeyi hafifçe eğin veya doğrudan ışıktan uzaklaşın.',
|
|
189
187
|
'identityDocumentCamera.wrongSideFront': 'Belgenizin ön yüzünü gösterin',
|
|
190
188
|
'identityDocumentCamera.wrongSideBack': 'Belgenizin arka yüzünü gösterin',
|
|
191
189
|
'identityDocumentCamera.idCardDetected': 'Kimlik kartı algılandı',
|
package/lib/module/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"AA4EA,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,2BAA2B,EAK5B,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAMnE,QAAA,MAAM,sBAAsB,GAAI,uDAI7B,2BAA2B,4CAksF7B,CAAC;AAmLF,eAAe,sBAAsB,CAAC"}
|
|
@@ -82,7 +82,7 @@ export declare function transformBoundsToScreen(bounds: {
|
|
|
82
82
|
* Unified status message logic used by both voice guidance and render text.
|
|
83
83
|
* Returns the appropriate i18n key arguments for the current scan state.
|
|
84
84
|
*/
|
|
85
|
-
export declare function getStatusMessage(nextStep: ScanStep, status: ScanStatus, detectedDocumentType: DocumentType, isBrightnessLow: boolean, isFrameBlurry: boolean,
|
|
85
|
+
export declare function getStatusMessage(nextStep: ScanStep, status: ScanStatus, detectedDocumentType: DocumentType, isBrightnessLow: boolean, isFrameBlurry: boolean, allElementsDetected: boolean, elementsOutsideScanArea: string[], t: (key: string, params?: Record<string, unknown>) => string): string;
|
|
86
86
|
/**
|
|
87
87
|
* Calculate angle from two points in degrees
|
|
88
88
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityDocumentCamera.utils.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,IAAI,EACL,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAQpD;;;;;;;;;;;GAWG;AACH,qBAAa,UAAU;IAMnB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAN9B,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAU;gBAGN,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACpC,OAAO,UAAQ;IAMjB,sEAAsE;IACtE,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;IAc3B,wEAAwE;IACxE,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAM3B,IAAI,OAAO,IAAI,OAAO,CAErB;CACF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG7E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,OAAO,CAGT;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAEvE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM;;;;;EAmBpB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;;;;;sBAW9C,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM;EAIjE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC/D,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM;;;;;EAQhB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,UAAU,EAClB,oBAAoB,EAAE,YAAY,EAClC,eAAe,EAAE,OAAO,EACxB,aAAa,EAAE,OAAO,EACtB,
|
|
1
|
+
{"version":3,"file":"IdentityDocumentCamera.utils.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,IAAI,EACL,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAQpD;;;;;;;;;;;GAWG;AACH,qBAAa,UAAU;IAMnB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAN9B,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAU;gBAGN,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACpC,OAAO,UAAQ;IAMjB,sEAAsE;IACtE,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;IAc3B,wEAAwE;IACxE,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAM3B,IAAI,OAAO,IAAI,OAAO,CAErB;CACF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG7E;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,OAAO,CAGT;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAEvE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM;;;;;EAmBpB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;;;;;sBAW9C,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM;EAIjE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAC/D,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM;;;;;EAQhB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,UAAU,EAClB,oBAAoB,EAAE,YAAY,EAClC,eAAe,EAAE,OAAO,EACxB,aAAa,EAAE,OAAO,EACtB,mBAAmB,EAAE,OAAO,EAC5B,uBAAuB,EAAE,MAAM,EAAE,EACjC,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAC3D,MAAM,CA8FR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5B,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3B,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EAC5B,EAAE,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3B,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,YAAY,CA6Ed;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,IAAI,EAAE,EACtB,eAAe,CAAC,EAAE,SAAS,EAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,GACtB,YAAY,CAcd;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAWrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAOzD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACtE,eAAe,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACxE,cAAc,EAAE,OAAO,GACtB,OAAO,CAkBT"}
|
|
@@ -180,10 +180,8 @@ declare const _default: {
|
|
|
180
180
|
'identityDocumentCamera.frontSide': string;
|
|
181
181
|
'identityDocumentCamera.backSide': string;
|
|
182
182
|
'identityDocumentCamera.hologramCheck': string;
|
|
183
|
-
'identityDocumentCamera.hologramProgress': string;
|
|
184
183
|
'identityDocumentCamera.keepSteady': string;
|
|
185
184
|
'identityDocumentCamera.avoidBlur': string;
|
|
186
|
-
'identityDocumentCamera.reduceGlare': string;
|
|
187
185
|
'identityDocumentCamera.wrongSideFront': string;
|
|
188
186
|
'identityDocumentCamera.wrongSideBack': string;
|
|
189
187
|
'identityDocumentCamera.idCardDetected': string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../../src/Translation/Resources/en.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../../src/Translation/Resources/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAkVE"}
|
|
@@ -180,10 +180,8 @@ declare const _default: {
|
|
|
180
180
|
'identityDocumentCamera.frontSide': string;
|
|
181
181
|
'identityDocumentCamera.backSide': string;
|
|
182
182
|
'identityDocumentCamera.hologramCheck': string;
|
|
183
|
-
'identityDocumentCamera.hologramProgress': string;
|
|
184
183
|
'identityDocumentCamera.keepSteady': string;
|
|
185
184
|
'identityDocumentCamera.avoidBlur': string;
|
|
186
|
-
'identityDocumentCamera.reduceGlare': string;
|
|
187
185
|
'identityDocumentCamera.wrongSideFront': string;
|
|
188
186
|
'identityDocumentCamera.wrongSideBack': string;
|
|
189
187
|
'identityDocumentCamera.idCardDetected': string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../../../../src/Translation/Resources/tr.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../../../../src/Translation/Resources/tr.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAqVE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "1.513.
|
|
1
|
+
export declare const SDK_VERSION = "1.513.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -65,7 +65,6 @@ import {
|
|
|
65
65
|
HOLOGRAM_CAPTURE_INTERVAL,
|
|
66
66
|
HOLOGRAM_MAX_FRAMES_WITHOUT_FACE,
|
|
67
67
|
MIN_BRIGHTNESS_THRESHOLD,
|
|
68
|
-
MAX_BRIGHTNESS_THRESHOLD,
|
|
69
68
|
FACE_EDGE_MARGIN_PERCENT,
|
|
70
69
|
MAX_CONSECUTIVE_QUALITY_FAILURES,
|
|
71
70
|
REQUIRED_CONSISTENT_MRZ_READS,
|
|
@@ -141,11 +140,6 @@ const IdentityDocumentCamera = ({
|
|
|
141
140
|
>(undefined);
|
|
142
141
|
const [isBrightnessLow, setIsBrightnessLow] = useState(false);
|
|
143
142
|
const [isFrameBlurry, setIsFrameBlurry] = useState(false);
|
|
144
|
-
// Glare was being silently rejected (frames dropped with no user feedback), so
|
|
145
|
-
// a user fighting reflections just saw the scan hang. Surface it so we can show
|
|
146
|
-
// an actionable "move away from glare" hint. Set at each glare rejection;
|
|
147
|
-
// cleared when a frame passes the brightness check (a fresh, glare-free frame).
|
|
148
|
-
const [isGlareDetected, setIsGlareDetected] = useState(false);
|
|
149
143
|
const [hasGuideShown, setHasGuideShown] = useState(false);
|
|
150
144
|
// "Having trouble?" escape: if a scan step doesn't complete within
|
|
151
145
|
// HELP_PROMPT_DELAY_MS the user is otherwise stuck on a live camera forever
|
|
@@ -176,7 +170,7 @@ const IdentityDocumentCamera = ({
|
|
|
176
170
|
const consecutiveQualityFailures = useRef(0);
|
|
177
171
|
const mrzDetectionCurrentRetryCount = useRef(0);
|
|
178
172
|
|
|
179
|
-
// Hysteresis for the on-screen quality guidance. Brightness/blur
|
|
173
|
+
// Hysteresis for the on-screen quality guidance. Brightness/blur are
|
|
180
174
|
// measured every frame; feeding the raw per-frame booleans straight into
|
|
181
175
|
// state made the guidance strobe (a single blurry hand-shake frame flipped
|
|
182
176
|
// "hold steady" on and off). These smooth each flag: it appears after a few
|
|
@@ -185,19 +179,11 @@ const IdentityDocumentCamera = ({
|
|
|
185
179
|
// problems), clear slow (don't flicker off on one good frame).
|
|
186
180
|
const brightnessLowFlag = useRef(new StableFlag(2, 5));
|
|
187
181
|
const blurryFlag = useRef(new StableFlag(3, 6));
|
|
188
|
-
const glareFlag = useRef(new StableFlag(2, 5));
|
|
189
|
-
// Glare is asserted by accept-time helpers that run inside the (separately
|
|
190
|
-
// scoped) handleFaceAndText callback, so it can't flow through a handler
|
|
191
|
-
// local. This ref is cleared at the top of each frame and set true if any
|
|
192
|
-
// glare check in that frame found glare; the handler reads it to feed
|
|
193
|
-
// `glareFlag`. `hadGlareText` distinguishes "card present but glaring" from
|
|
194
|
-
// an empty view so the warning only shows over an actual document.
|
|
195
|
-
const rawGlareRef = useRef(false);
|
|
196
182
|
// Whether a document was visible in the PREVIOUS frame (recognized text,
|
|
197
183
|
// barcode, or face). The quality guidance is stabilized BEFORE the quality
|
|
198
184
|
// gate (so dark/blurry frames — which the gate early-returns on — can still
|
|
199
185
|
// raise their warnings), but document-presence is only known LATER in the
|
|
200
|
-
// frame, so blur
|
|
186
|
+
// frame, so blur is gated on the previous frame's value. One-frame lag
|
|
201
187
|
// at ~8fps is imperceptible and the hysteresis smooths it.
|
|
202
188
|
const documentPresentRef = useRef(false);
|
|
203
189
|
|
|
@@ -275,7 +261,6 @@ const IdentityDocumentCamera = ({
|
|
|
275
261
|
frameH: 0,
|
|
276
262
|
hadLowBrightness: false,
|
|
277
263
|
hadBlurryFrames: false,
|
|
278
|
-
hadGlare: false,
|
|
279
264
|
});
|
|
280
265
|
const [faceDetectionEnabled, setFaceDetectionEnabled] = useState(true);
|
|
281
266
|
const faceImages = useRef<string[]>([]);
|
|
@@ -390,7 +375,6 @@ const IdentityDocumentCamera = ({
|
|
|
390
375
|
frameH: 0,
|
|
391
376
|
hadLowBrightness: false,
|
|
392
377
|
hadBlurryFrames: false,
|
|
393
|
-
hadGlare: false,
|
|
394
378
|
};
|
|
395
379
|
cachedBarcode.current = null;
|
|
396
380
|
isCompletionCallbackInvoked.current = false;
|
|
@@ -439,7 +423,6 @@ const IdentityDocumentCamera = ({
|
|
|
439
423
|
detectedDocumentType,
|
|
440
424
|
isBrightnessLow,
|
|
441
425
|
isFrameBlurry,
|
|
442
|
-
isGlareDetected,
|
|
443
426
|
allElementsDetected,
|
|
444
427
|
elementsOutsideScanArea,
|
|
445
428
|
t
|
|
@@ -462,7 +445,6 @@ const IdentityDocumentCamera = ({
|
|
|
462
445
|
hasGuideShown,
|
|
463
446
|
isBrightnessLow,
|
|
464
447
|
isFrameBlurry,
|
|
465
|
-
isGlareDetected,
|
|
466
448
|
nextStep,
|
|
467
449
|
status,
|
|
468
450
|
detectedDocumentType,
|
|
@@ -630,33 +612,6 @@ const IdentityDocumentCamera = ({
|
|
|
630
612
|
}
|
|
631
613
|
};
|
|
632
614
|
|
|
633
|
-
// Check if face image has glare (brightness exceeds threshold). Also surfaces
|
|
634
|
-
// the result to `isGlareDetected` so the user gets an actionable hint instead
|
|
635
|
-
// of a silently-stalled scan.
|
|
636
|
-
const checkFaceGlare = async (faceImage: string): Promise<boolean> => {
|
|
637
|
-
try {
|
|
638
|
-
// Check entire face region for glare
|
|
639
|
-
const hasGlare = await OpenCVModule.isRectangularRegionBright(
|
|
640
|
-
faceImage,
|
|
641
|
-
0,
|
|
642
|
-
0,
|
|
643
|
-
100, // Full face width
|
|
644
|
-
100, // Full face height
|
|
645
|
-
MAX_BRIGHTNESS_THRESHOLD
|
|
646
|
-
);
|
|
647
|
-
// OR-accumulate into the per-frame glare signal (reset at frame top); the
|
|
648
|
-
// frame handler feeds it through the stabilized UI flag. Also record the
|
|
649
|
-
// diagnostic.
|
|
650
|
-
if (hasGlare) {
|
|
651
|
-
rawGlareRef.current = true;
|
|
652
|
-
diagStats.current.hadGlare = true;
|
|
653
|
-
}
|
|
654
|
-
return hasGlare;
|
|
655
|
-
} catch (error) {
|
|
656
|
-
return false; // Assume no glare on error
|
|
657
|
-
}
|
|
658
|
-
};
|
|
659
|
-
|
|
660
615
|
// Check if face is fully visible (not cropped at edges)
|
|
661
616
|
const isFaceFullyVisible = (
|
|
662
617
|
face: Face,
|
|
@@ -673,35 +628,6 @@ const IdentityDocumentCamera = ({
|
|
|
673
628
|
);
|
|
674
629
|
};
|
|
675
630
|
|
|
676
|
-
// Check if document image has glare
|
|
677
|
-
const checkDocumentGlare = async (
|
|
678
|
-
image: string,
|
|
679
|
-
width: number,
|
|
680
|
-
height: number
|
|
681
|
-
): Promise<boolean> => {
|
|
682
|
-
try {
|
|
683
|
-
// Check center 80% region for glare (document area)
|
|
684
|
-
const hasGlare = await OpenCVModule.isRectangularRegionBright(
|
|
685
|
-
image,
|
|
686
|
-
Math.round(width * 0.1),
|
|
687
|
-
Math.round(height * 0.1),
|
|
688
|
-
Math.round(width * 0.8),
|
|
689
|
-
Math.round(height * 0.8),
|
|
690
|
-
MAX_BRIGHTNESS_THRESHOLD
|
|
691
|
-
);
|
|
692
|
-
// OR-accumulate into the per-frame glare signal (reset at frame top); the
|
|
693
|
-
// frame handler feeds it through the stabilized UI flag. Also record the
|
|
694
|
-
// diagnostic.
|
|
695
|
-
if (hasGlare) {
|
|
696
|
-
rawGlareRef.current = true;
|
|
697
|
-
diagStats.current.hadGlare = true;
|
|
698
|
-
}
|
|
699
|
-
return hasGlare;
|
|
700
|
-
} catch (error) {
|
|
701
|
-
return false;
|
|
702
|
-
}
|
|
703
|
-
};
|
|
704
|
-
|
|
705
631
|
const setNextStepAndVibrate = useCallback(
|
|
706
632
|
(
|
|
707
633
|
nextStepType:
|
|
@@ -780,12 +706,9 @@ const IdentityDocumentCamera = ({
|
|
|
780
706
|
// carried over from the previous side).
|
|
781
707
|
brightnessLowFlag.current.reset(false);
|
|
782
708
|
blurryFlag.current.reset(false);
|
|
783
|
-
glareFlag.current.reset(false);
|
|
784
|
-
rawGlareRef.current = false;
|
|
785
709
|
documentPresentRef.current = false;
|
|
786
710
|
setIsBrightnessLow(false);
|
|
787
711
|
setIsFrameBlurry(false);
|
|
788
|
-
setIsGlareDetected(false);
|
|
789
712
|
|
|
790
713
|
if (nextStepType !== 'COMPLETED') {
|
|
791
714
|
setTimeout(() => {
|
|
@@ -1189,14 +1112,12 @@ const IdentityDocumentCamera = ({
|
|
|
1189
1112
|
const faceFullyVisible =
|
|
1190
1113
|
primaryFaces[0] &&
|
|
1191
1114
|
isFaceFullyVisible(primaryFaces[0], frameWidth, frameHeight);
|
|
1192
|
-
const hasGlare = await checkFaceGlare(croppedFaces[0]);
|
|
1193
1115
|
|
|
1194
|
-
if (!faceFullyVisible
|
|
1195
|
-
// Reject
|
|
1116
|
+
if (!faceFullyVisible) {
|
|
1117
|
+
// Reject partially visible face
|
|
1196
1118
|
if (isDebugEnabled()) {
|
|
1197
1119
|
debugLog('IdentityDocumentCamera', '[FACE] Rejected', {
|
|
1198
1120
|
fullyVisible: faceFullyVisible,
|
|
1199
|
-
hasGlare,
|
|
1200
1121
|
});
|
|
1201
1122
|
}
|
|
1202
1123
|
// Continue scanning without locking this face
|
|
@@ -1337,23 +1258,6 @@ const IdentityDocumentCamera = ({
|
|
|
1337
1258
|
return;
|
|
1338
1259
|
}
|
|
1339
1260
|
|
|
1340
|
-
// Check for glare on ID back before accepting
|
|
1341
|
-
const hasGlare = await checkDocumentGlare(
|
|
1342
|
-
image,
|
|
1343
|
-
frameWidth,
|
|
1344
|
-
frameHeight
|
|
1345
|
-
);
|
|
1346
|
-
if (hasGlare) {
|
|
1347
|
-
if (isDebugEnabled()) {
|
|
1348
|
-
debugLog(
|
|
1349
|
-
'IdentityDocumentCamera',
|
|
1350
|
-
'[ID_BACK] Rejected - glare detected'
|
|
1351
|
-
);
|
|
1352
|
-
}
|
|
1353
|
-
setStatus('SCANNING');
|
|
1354
|
-
return;
|
|
1355
|
-
}
|
|
1356
|
-
|
|
1357
1261
|
if (isDebugEnabled()) {
|
|
1358
1262
|
debugLog('IdentityDocumentCamera', '[ID_BACK] MRZ validated', {
|
|
1359
1263
|
documentNumber: parsedMRZData?.fields?.documentNumber,
|
|
@@ -1530,29 +1434,17 @@ const IdentityDocumentCamera = ({
|
|
|
1530
1434
|
setIsTorchOn(true);
|
|
1531
1435
|
}
|
|
1532
1436
|
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
faceImages.current.push(primaryFaceOnly);
|
|
1537
|
-
lastHologramCaptureTime.current = Date.now();
|
|
1538
|
-
hologramImageCountRef.current = faceImages.current.length;
|
|
1437
|
+
faceImages.current.push(primaryFaceOnly);
|
|
1438
|
+
lastHologramCaptureTime.current = Date.now();
|
|
1439
|
+
hologramImageCountRef.current = faceImages.current.length;
|
|
1539
1440
|
|
|
1540
|
-
|
|
1541
|
-
debugLog(
|
|
1542
|
-
'IdentityDocumentCamera',
|
|
1543
|
-
'[HOLOGRAM] Frame captured',
|
|
1544
|
-
{
|
|
1545
|
-
frameIndex: faceImages.current.length - 1,
|
|
1546
|
-
totalFrames: faceImages.current.length,
|
|
1547
|
-
}
|
|
1548
|
-
);
|
|
1549
|
-
}
|
|
1550
|
-
} else if (isDebugEnabled()) {
|
|
1441
|
+
if (isDebugEnabled()) {
|
|
1551
1442
|
debugLog(
|
|
1552
1443
|
'IdentityDocumentCamera',
|
|
1553
|
-
'[HOLOGRAM]
|
|
1444
|
+
'[HOLOGRAM] Frame captured',
|
|
1554
1445
|
{
|
|
1555
|
-
|
|
1446
|
+
frameIndex: faceImages.current.length - 1,
|
|
1447
|
+
totalFrames: faceImages.current.length,
|
|
1556
1448
|
}
|
|
1557
1449
|
);
|
|
1558
1450
|
}
|
|
@@ -1955,23 +1847,6 @@ const IdentityDocumentCamera = ({
|
|
|
1955
1847
|
return;
|
|
1956
1848
|
}
|
|
1957
1849
|
|
|
1958
|
-
// Check for glare on passport before accepting
|
|
1959
|
-
const hasGlare = await checkDocumentGlare(
|
|
1960
|
-
image,
|
|
1961
|
-
frameWidth,
|
|
1962
|
-
frameHeight
|
|
1963
|
-
);
|
|
1964
|
-
if (hasGlare) {
|
|
1965
|
-
if (isDebugEnabled()) {
|
|
1966
|
-
debugLog(
|
|
1967
|
-
'IdentityDocumentCamera',
|
|
1968
|
-
'[PASSPORT] Rejected - glare detected'
|
|
1969
|
-
);
|
|
1970
|
-
}
|
|
1971
|
-
continueScanning(false);
|
|
1972
|
-
return;
|
|
1973
|
-
}
|
|
1974
|
-
|
|
1975
1850
|
setDetectedDocumentType('PASSPORT');
|
|
1976
1851
|
setStatus('SCANNED');
|
|
1977
1852
|
|
|
@@ -2005,23 +1880,6 @@ const IdentityDocumentCamera = ({
|
|
|
2005
1880
|
return;
|
|
2006
1881
|
}
|
|
2007
1882
|
|
|
2008
|
-
// Check for glare on ID front before accepting
|
|
2009
|
-
const hasGlare = await checkDocumentGlare(
|
|
2010
|
-
image,
|
|
2011
|
-
frameWidth,
|
|
2012
|
-
frameHeight
|
|
2013
|
-
);
|
|
2014
|
-
if (hasGlare) {
|
|
2015
|
-
if (isDebugEnabled()) {
|
|
2016
|
-
debugLog(
|
|
2017
|
-
'IdentityDocumentCamera',
|
|
2018
|
-
'[ID_FRONT] Rejected - glare detected'
|
|
2019
|
-
);
|
|
2020
|
-
}
|
|
2021
|
-
continueScanning(false);
|
|
2022
|
-
return;
|
|
2023
|
-
}
|
|
2024
|
-
|
|
2025
1883
|
setDetectedDocumentType('ID_FRONT');
|
|
2026
1884
|
setStatus('SCANNED');
|
|
2027
1885
|
|
|
@@ -2136,18 +1994,6 @@ const IdentityDocumentCamera = ({
|
|
|
2136
1994
|
const rawBrightnessLow = !isRegionBright;
|
|
2137
1995
|
if (rawBrightnessLow) diagStats.current.hadLowBrightness = true;
|
|
2138
1996
|
|
|
2139
|
-
// Per-frame glare is asserted by the accept-time helpers (checkDocumentGlare
|
|
2140
|
-
// /checkFaceGlare), but those run inside handleFaceAndText which is fired
|
|
2141
|
-
// (async, un-awaited) LATER in this handler — so this frame's glare result
|
|
2142
|
-
// isn't known yet at the stabilization block below. We therefore feed the
|
|
2143
|
-
// stabilizer the PREVIOUS frame's glare signal (captured here before the
|
|
2144
|
-
// reset). At ~8fps the one-frame lag is imperceptible and the hysteresis
|
|
2145
|
-
// smooths it anyway; without this the read would always see false and the
|
|
2146
|
-
// glare warning could never fire. Reset after capturing so a now-clean
|
|
2147
|
-
// view clears (no latch).
|
|
2148
|
-
const prevFrameGlare = rawGlareRef.current;
|
|
2149
|
-
rawGlareRef.current = false;
|
|
2150
|
-
|
|
2151
1997
|
// Check blur only in center region (area of interest) to avoid false positives
|
|
2152
1998
|
// from iOS depth-of-field background blur
|
|
2153
1999
|
let isNotBlurry = true;
|
|
@@ -2197,8 +2043,8 @@ const IdentityDocumentCamera = ({
|
|
|
2197
2043
|
// MUST run BEFORE the quality-gate early-return below: a dark or blurry
|
|
2198
2044
|
// frame is exactly what makes hasAcceptableQuality false, so if this ran
|
|
2199
2045
|
// after the gate the "too dark" / "hold steady" warnings could never
|
|
2200
|
-
// raise (their triggering frames would have already returned). Blur
|
|
2201
|
-
//
|
|
2046
|
+
// raise (their triggering frames would have already returned). Blur
|
|
2047
|
+
// is gated on document presence; brightness shows regardless, since a
|
|
2202
2048
|
// dark room is worth flagging before the card is even framed.
|
|
2203
2049
|
//
|
|
2204
2050
|
// Presence combines the previous frame's confirmed value (documentPresent-
|
|
@@ -2207,7 +2053,7 @@ const IdentityDocumentCamera = ({
|
|
|
2207
2053
|
// processing). Without the raw proxy, a document that is blurry/dark from
|
|
2208
2054
|
// its very first framed moment would keep failing the quality gate and
|
|
2209
2055
|
// early-returning before documentPresentRef is ever set true — suppressing
|
|
2210
|
-
// its blur
|
|
2056
|
+
// its blur hints for ~30 frames. The proxy lets the hint fire on the
|
|
2211
2057
|
// first framed frame.
|
|
2212
2058
|
const rawDocumentPresent =
|
|
2213
2059
|
(frame.faces?.length ?? 0) > 0 ||
|
|
@@ -2217,9 +2063,6 @@ const IdentityDocumentCamera = ({
|
|
|
2217
2063
|
documentPresentRef.current || rawDocumentPresent;
|
|
2218
2064
|
setIsBrightnessLow(brightnessLowFlag.current.push(rawBrightnessLow));
|
|
2219
2065
|
setIsFrameBlurry(blurryFlag.current.push(documentWasPresent && isBlurry));
|
|
2220
|
-
setIsGlareDetected(
|
|
2221
|
-
glareFlag.current.push(documentWasPresent && prevFrameGlare)
|
|
2222
|
-
);
|
|
2223
2066
|
// -------------------------------------------------------------------
|
|
2224
2067
|
|
|
2225
2068
|
// Store quality metrics in ref for access in handleFaceAndText callback
|
|
@@ -2800,18 +2643,6 @@ const IdentityDocumentCamera = ({
|
|
|
2800
2643
|
</TextView>
|
|
2801
2644
|
)}
|
|
2802
2645
|
|
|
2803
|
-
{/* Hologram capture progress — 16 frames are collected while the user
|
|
2804
|
-
tilts the document; show N/16 so "tilt slowly" feels responsive
|
|
2805
|
-
instead of a silent wait. */}
|
|
2806
|
-
{nextStep === 'SCAN_HOLOGRAM' && status !== 'SCANNED' && (
|
|
2807
|
-
<TextView style={styles.hologramProgress}>
|
|
2808
|
-
{t('identityDocumentCamera.hologramProgress', {
|
|
2809
|
-
current: hologramImageCount,
|
|
2810
|
-
total: HOLOGRAM_IMAGE_COUNT,
|
|
2811
|
-
})}
|
|
2812
|
-
</TextView>
|
|
2813
|
-
)}
|
|
2814
|
-
|
|
2815
2646
|
<AnimatedText
|
|
2816
2647
|
style={[
|
|
2817
2648
|
styles.topZoneText,
|
|
@@ -2827,7 +2658,7 @@ const IdentityDocumentCamera = ({
|
|
|
2827
2658
|
opacity: errorFlashAnim,
|
|
2828
2659
|
},
|
|
2829
2660
|
// 3. Warning (yellow) - quality issues
|
|
2830
|
-
(isBrightnessLow || isFrameBlurry
|
|
2661
|
+
(isBrightnessLow || isFrameBlurry) &&
|
|
2831
2662
|
styles.topZoneTextWarning,
|
|
2832
2663
|
// 4. Scanning (green) - all elements detected AND inside scan area
|
|
2833
2664
|
status === 'SCANNING' &&
|
|
@@ -2835,7 +2666,6 @@ const IdentityDocumentCamera = ({
|
|
|
2835
2666
|
elementsOutsideScanArea.length === 0 &&
|
|
2836
2667
|
!isBrightnessLow &&
|
|
2837
2668
|
!isFrameBlurry &&
|
|
2838
|
-
!isGlareDetected &&
|
|
2839
2669
|
styles.topZoneTextScanning,
|
|
2840
2670
|
// 5. Default (white) - aligning (not all detected OR elements outside scan area)
|
|
2841
2671
|
]}
|
|
@@ -2846,7 +2676,6 @@ const IdentityDocumentCamera = ({
|
|
|
2846
2676
|
detectedDocumentType,
|
|
2847
2677
|
isBrightnessLow,
|
|
2848
2678
|
isFrameBlurry,
|
|
2849
|
-
isGlareDetected,
|
|
2850
2679
|
allElementsDetected,
|
|
2851
2680
|
elementsOutsideScanArea,
|
|
2852
2681
|
t
|
|
@@ -2899,7 +2728,9 @@ const IdentityDocumentCamera = ({
|
|
|
2899
2728
|
/>
|
|
2900
2729
|
) : null}
|
|
2901
2730
|
</View>
|
|
2902
|
-
{
|
|
2731
|
+
{/* Debug overlay is DEV-only: hard-gated on __DEV__ so a release build
|
|
2732
|
+
can never render it, even if a consumer passes debug={true}. */}
|
|
2733
|
+
{__DEV__ && isDebugEnabled() && (
|
|
2903
2734
|
<DebugOverlay
|
|
2904
2735
|
nextStep={nextStep}
|
|
2905
2736
|
status={status}
|
|
@@ -2922,7 +2753,7 @@ const IdentityDocumentCamera = ({
|
|
|
2922
2753
|
elementsOutsideScanArea={elementsOutsideScanArea}
|
|
2923
2754
|
/>
|
|
2924
2755
|
)}
|
|
2925
|
-
{testMode && testModeData && (
|
|
2756
|
+
{__DEV__ && testMode && testModeData && (
|
|
2926
2757
|
<TestModePanel mrzText={testModeData.mrzText} />
|
|
2927
2758
|
)}
|
|
2928
2759
|
|
|
@@ -3070,13 +2901,6 @@ const styles = StyleSheet.create({
|
|
|
3070
2901
|
fontWeight: '500',
|
|
3071
2902
|
marginBottom: 4,
|
|
3072
2903
|
},
|
|
3073
|
-
hologramProgress: {
|
|
3074
|
-
color: '#4CAF50',
|
|
3075
|
-
fontSize: 14,
|
|
3076
|
-
textAlign: 'center',
|
|
3077
|
-
fontWeight: '600',
|
|
3078
|
-
marginBottom: 4,
|
|
3079
|
-
},
|
|
3080
2904
|
topZoneText: {
|
|
3081
2905
|
color: 'white',
|
|
3082
2906
|
fontSize: 20,
|
|
@@ -172,7 +172,6 @@ export function getStatusMessage(
|
|
|
172
172
|
detectedDocumentType: DocumentType,
|
|
173
173
|
isBrightnessLow: boolean,
|
|
174
174
|
isFrameBlurry: boolean,
|
|
175
|
-
isGlareDetected: boolean,
|
|
176
175
|
allElementsDetected: boolean,
|
|
177
176
|
elementsOutsideScanArea: string[],
|
|
178
177
|
t: (key: string, params?: Record<string, unknown>) => string
|
|
@@ -204,14 +203,6 @@ export function getStatusMessage(
|
|
|
204
203
|
return t('identityDocumentCamera.lowBrightness');
|
|
205
204
|
}
|
|
206
205
|
|
|
207
|
-
// Glare is a primary failure mode (reflections off the laminate/photo). It was
|
|
208
|
-
// previously detected but never communicated, so the scan just appeared to
|
|
209
|
-
// hang. Tell the user how to fix it. Ranked above blur because a glare hotspot
|
|
210
|
-
// both blocks acceptance and often reads as a "sharp" (non-blurry) frame.
|
|
211
|
-
if (isGlareDetected) {
|
|
212
|
-
return t('identityDocumentCamera.reduceGlare');
|
|
213
|
-
}
|
|
214
|
-
|
|
215
206
|
if (isFrameBlurry) {
|
|
216
207
|
return t('identityDocumentCamera.avoidBlur');
|
|
217
208
|
}
|
|
@@ -238,12 +238,8 @@ export default {
|
|
|
238
238
|
'identityDocumentCamera.frontSide': 'Front',
|
|
239
239
|
'identityDocumentCamera.backSide': 'Back',
|
|
240
240
|
'identityDocumentCamera.hologramCheck': 'Hologram',
|
|
241
|
-
'identityDocumentCamera.hologramProgress':
|
|
242
|
-
'Capturing hologram… {{current}}/{{total}}',
|
|
243
241
|
'identityDocumentCamera.keepSteady': 'Keep device steady',
|
|
244
242
|
'identityDocumentCamera.avoidBlur': 'Keep device steady',
|
|
245
|
-
'identityDocumentCamera.reduceGlare':
|
|
246
|
-
'Glare detected. Tilt the document or move away from direct light.',
|
|
247
243
|
'identityDocumentCamera.wrongSideFront':
|
|
248
244
|
'Show the front side of your document',
|
|
249
245
|
'identityDocumentCamera.wrongSideBack': 'Show the back side of your document',
|
|
@@ -239,12 +239,8 @@ export default {
|
|
|
239
239
|
'identityDocumentCamera.frontSide': 'Ön',
|
|
240
240
|
'identityDocumentCamera.backSide': 'Arka',
|
|
241
241
|
'identityDocumentCamera.hologramCheck': 'Hologram',
|
|
242
|
-
'identityDocumentCamera.hologramProgress':
|
|
243
|
-
'Hologram yakalanıyor… {{current}}/{{total}}',
|
|
244
242
|
'identityDocumentCamera.keepSteady': 'Cihazı sabit tutun',
|
|
245
243
|
'identityDocumentCamera.avoidBlur': 'Cihazı sabit tutun',
|
|
246
|
-
'identityDocumentCamera.reduceGlare':
|
|
247
|
-
'Parlama algılandı. Belgeyi hafifçe eğin veya doğrudan ışıktan uzaklaşın.',
|
|
248
244
|
'identityDocumentCamera.wrongSideFront': 'Belgenizin ön yüzünü gösterin',
|
|
249
245
|
'identityDocumentCamera.wrongSideBack': 'Belgenizin arka yüzünü gösterin',
|
|
250
246
|
'identityDocumentCamera.idCardDetected': 'Kimlik kartı algılandı',
|
package/src/version.ts
CHANGED