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:
Cursor Agent
2026-05-27 19:51:08 +00:00
parent 4e5fa5d42e
commit 64584315e5
6 changed files with 203 additions and 83 deletions
+28 -39
View File
@@ -9,6 +9,7 @@
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"@undecaf/barcode-detector-polyfill": "^0.9.23",
"@vitejs/plugin-react": "^4.3.4",
"@zxing/browser": "^0.2.0",
"appwrite": "^25.0.0",
@@ -1160,9 +1161,6 @@
"cpu": [
"arm"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1176,9 +1174,6 @@
"cpu": [
"arm"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1192,9 +1187,6 @@
"cpu": [
"arm64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1208,9 +1200,6 @@
"cpu": [
"arm64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1224,9 +1213,6 @@
"cpu": [
"loong64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1240,9 +1226,6 @@
"cpu": [
"loong64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1256,9 +1239,6 @@
"cpu": [
"ppc64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1272,9 +1252,6 @@
"cpu": [
"ppc64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1288,9 +1265,6 @@
"cpu": [
"riscv64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1304,9 +1278,6 @@
"cpu": [
"riscv64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1320,9 +1291,6 @@
"cpu": [
"s390x"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1336,9 +1304,6 @@
"cpu": [
"x64"
],
"libc": [
"glibc"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1352,9 +1317,6 @@
"cpu": [
"x64"
],
"libc": [
"musl"
],
"license": "MIT",
"optional": true,
"os": [
@@ -1880,6 +1842,24 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/@undecaf/barcode-detector-polyfill": {
"version": "0.9.23",
"resolved": "https://registry.npmjs.org/@undecaf/barcode-detector-polyfill/-/barcode-detector-polyfill-0.9.23.tgz",
"integrity": "sha512-qVr7jSUbE5a30X9dByDym2NzsqyH+MFwyFiu4QSHDQMLCImTJj/et7pEcOtGqlL4UB5J6J3d0hK4/5d4MMowYA==",
"license": "MIT",
"dependencies": {
"@undecaf/zbar-wasm": "^0.9.16"
}
},
"node_modules/@undecaf/zbar-wasm": {
"version": "0.9.16",
"resolved": "https://registry.npmjs.org/@undecaf/zbar-wasm/-/zbar-wasm-0.9.16.tgz",
"integrity": "sha512-T5PcT6g+tLScGjR4WmnRErNvfKqEc3kRg2ux14wHmIDNbvNeXa0BkFK19PRK/jb6zGy5NyWtn4ko6KeNuZc/fQ==",
"license": "LGPL-2.1+",
"dependencies": {
"jschardet": "^3.0.0"
}
},
"node_modules/@vitejs/plugin-react": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
@@ -3622,6 +3602,15 @@
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/jschardet": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/jschardet/-/jschardet-3.1.4.tgz",
"integrity": "sha512-/kmVISmrwVwtyYU40iQUOp3SUPk2dhNCMsZBQX0R1/jZ8maaXJ/oZIzUOiyOqcgtLnETFKYChbJ5iDC/eWmFHg==",
"license": "LGPL-2.1+",
"engines": {
"node": ">=0.1.90"
}
},
"node_modules/jsesc": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",