Skip to content

Commit

Permalink
feat: BarcodeDetector polyfill only if no native support
Browse files Browse the repository at this point in the history
See: #447
  • Loading branch information
gruhn committed Sep 2, 2024
1 parent a5dbaa2 commit 5cdc631
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
# Icon must end with two \r
Icon

# VitePress
.vitepress/cache
.vitepress/dist

# Thumbnails
._*
Expand Down
37 changes: 32 additions & 5 deletions src/misc/scanner.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,37 @@
import { type DetectedBarcode, type BarcodeFormat, BarcodeDetector } from 'barcode-detector/pure'
import { type DetectedBarcode, type BarcodeFormat, BarcodeDetector, type BarcodeDetectorOptions } from 'barcode-detector/pure'
import { eventOn } from './callforth'
import { DropImageFetchError } from './errors'

declare global {
interface Window {
BarcodeDetector?: typeof BarcodeDetector
}
}

/**
* Wrapper function that creates `BarcodeDetector` instances. The native API is used
* if it's available. Otherwise the polyfill is used.
*
* Note, that we can't just monkey the API on load, i.e.
*
* globalThis.BarcodeDetector ??= BarcodeDetector
*
* because that is not SSR compatible. If the polyfill is applied during SSR, then
* it's actually missing at runtime.
*/
function createBarcodeDetector(options: BarcodeDetectorOptions): BarcodeDetector {
if (window.BarcodeDetector === undefined) {
console.debug('[vue-qrcode-reader] BarcodeDetector not available: will use polyfill.')
return new BarcodeDetector(options)
} else {
console.debug('[vue-qrcode-reader] BarcodeDetector available: will use native API.')
return new window.BarcodeDetector(options)
}
}

let barcodeDetector: BarcodeDetector
export const setScanningFormats = (formats: BarcodeFormat[]) => {
barcodeDetector = new BarcodeDetector({ formats })
barcodeDetector = createBarcodeDetector({ formats })
}

type ScanHandler = (_: DetectedBarcode[]) => void
Expand All @@ -28,7 +55,7 @@ export const keepScanning = async (
}
) => {
console.debug('[vue-qrcode-reader] start scanning')
barcodeDetector = new BarcodeDetector({ formats })
barcodeDetector = createBarcodeDetector({ formats })

const processFrame =
(state: { lastScanned: number; contentBefore: string[]; lastScanHadContent: boolean }) =>
Expand Down Expand Up @@ -140,7 +167,7 @@ export const processFile = async (
file: File,
formats: BarcodeFormat[] = ['qr_code']
): Promise<DetectedBarcode[]> => {
const barcodeDetector = new BarcodeDetector({
const barcodeDetector = createBarcodeDetector({
formats
})

Expand All @@ -151,7 +178,7 @@ export const processUrl = async (
url: string,
formats: BarcodeFormat[] = ['qr_code']
): Promise<DetectedBarcode[]> => {
const barcodeDetector = new BarcodeDetector({
const barcodeDetector = createBarcodeDetector({
formats
})

Expand Down
4 changes: 2 additions & 2 deletions src/misc/shimGetUserMedia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { shimGetUserMedia as safariShim } from 'webrtc-adapter/dist/safari/safar
import { detectBrowser } from 'webrtc-adapter/dist/utils'

import { StreamApiNotSupportedError } from './errors'
import { indempotent } from './util'
import { idempotent } from './util'

export default indempotent(() => {
export default idempotent(() => {
const browserDetails = detectBrowser(window)

switch (browserDetails.browser) {
Expand Down
2 changes: 1 addition & 1 deletion src/misc/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Takes a function `action` and returns a new function, that behaves
* like action but when called a second time does nothing.
*/
export const indempotent = <T>(action: (x: any) => T) => {
export const idempotent = <T>(action: (x: any) => T) => {
let called = false
let result: T | undefined = undefined

Expand Down

0 comments on commit 5cdc631

Please sign in to comment.