Fix barcode scanner on iOS Safari
iOS WebKit does not provide a reliable native Barcode Detection API, and ZXing often failed due to strict camera constraints and video startup timing. - Install @undecaf/barcode-detector-polyfill (ZBar WASM) on Apple devices - Fall back through progressively looser getUserMedia constraints - Wait for video metadata/playback before decoding frames - Throttle native scans on iOS and tune ZXing retry intervals - Defer scanner startup until the modal video element is mounted Co-authored-by: Ned Halksworth <hello@nedhalksworth.com>
This commit is contained in:
co-authored by
Ned Halksworth
parent
4e5fa5d42e
commit
64584315e5
@@ -191,24 +191,32 @@ export function BarcodeScannerModal({
|
||||
window.setTimeout(() => closeButtonRef.current?.focus(), 80);
|
||||
|
||||
let active = true;
|
||||
const video = videoRef.current;
|
||||
if (!video) return undefined;
|
||||
let frameId = 0;
|
||||
|
||||
void startBarcodeScanner(video, handleScannerResult, handleScannerError)
|
||||
.then((controller) => {
|
||||
if (!active) {
|
||||
controller.stop();
|
||||
return;
|
||||
}
|
||||
controllerRef.current = controller;
|
||||
setScannerMode(controller.mode);
|
||||
setPhase("scanning");
|
||||
})
|
||||
.catch((error: BarcodeScannerError) => {
|
||||
if (!active) return;
|
||||
setScannerError(error);
|
||||
setPhase("error");
|
||||
});
|
||||
const startScanner = () => {
|
||||
const video = videoRef.current;
|
||||
if (!video || !active) return;
|
||||
|
||||
void startBarcodeScanner(video, handleScannerResult, handleScannerError)
|
||||
.then((controller) => {
|
||||
if (!active) {
|
||||
controller.stop();
|
||||
return;
|
||||
}
|
||||
controllerRef.current = controller;
|
||||
setScannerMode(controller.mode);
|
||||
setPhase("scanning");
|
||||
})
|
||||
.catch((error: BarcodeScannerError) => {
|
||||
if (!active) return;
|
||||
setScannerError(error);
|
||||
setPhase("error");
|
||||
});
|
||||
};
|
||||
|
||||
frameId = window.requestAnimationFrame(() => {
|
||||
window.requestAnimationFrame(startScanner);
|
||||
});
|
||||
|
||||
void listBarcodeCatalog()
|
||||
.then((catalog) => {
|
||||
@@ -224,6 +232,7 @@ export function BarcodeScannerModal({
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
window.cancelAnimationFrame(frameId);
|
||||
stopScanner();
|
||||
};
|
||||
}, [applyManualDefaults, handleScannerError, handleScannerResult, open, stopScanner, userId]);
|
||||
@@ -335,6 +344,7 @@ export function BarcodeScannerModal({
|
||||
<video
|
||||
ref={videoRef}
|
||||
className="aspect-[3/4] w-full bg-black object-cover sm:aspect-video"
|
||||
autoPlay
|
||||
muted
|
||||
playsInline
|
||||
aria-label="Live camera preview"
|
||||
|
||||
Reference in New Issue
Block a user