webapp/src/composables/useQRScanner.ts
padreug d31db59359 Fix QR scanner loading state condition and remove unused video element reference
- Updated the loading state condition in qr-scanner.vue to check for camera permission correctly.
- Removed the unused videoElement reference in useQRScanner.ts to clean up the code.

These changes improve the functionality and clarity of the QR scanner component.
2025-09-18 23:01:01 +02:00

109 lines
No EOL
2.6 KiB
TypeScript

import { ref, onUnmounted } from 'vue'
import QrScanner from 'qr-scanner'
export function useQRScanner() {
const isScanning = ref(false)
const hasPermission = ref<boolean | null>(null)
const error = ref<string | null>(null)
const scanResult = ref<string | null>(null)
let qrScanner: QrScanner | null = null
const startScanning = async (videoEl: HTMLVideoElement, onResult: (result: string) => void) => {
try {
error.value = null
// Check if camera is available
const hasCamera = await QrScanner.hasCamera()
if (!hasCamera) {
throw new Error('No camera found')
}
// Request camera permission
await navigator.mediaDevices.getUserMedia({ video: true })
hasPermission.value = true
// Create QR scanner instance
qrScanner = new QrScanner(
videoEl,
(result) => {
scanResult.value = result.data
onResult(result.data)
},
{
highlightScanRegion: true,
highlightCodeOutline: true,
maxScansPerSecond: 5,
}
)
await qrScanner.start()
isScanning.value = true
} catch (err) {
console.error('Failed to start QR scanner:', err)
hasPermission.value = false
if (err instanceof Error) {
if (err.name === 'NotAllowedError') {
error.value = 'Camera permission denied. Please allow camera access and try again.'
} else if (err.name === 'NotFoundError') {
error.value = 'No camera found on this device.'
} else if (err.name === 'NotSupportedError') {
error.value = 'Camera not supported on this device.'
} else {
error.value = err.message
}
} else {
error.value = 'Failed to access camera'
}
}
}
const stopScanning = () => {
if (qrScanner) {
qrScanner.stop()
qrScanner.destroy()
qrScanner = null
}
isScanning.value = false
scanResult.value = null
}
const toggleFlash = async () => {
if (qrScanner) {
try {
await qrScanner.toggleFlash()
} catch (err) {
console.error('Failed to toggle flash:', err)
}
}
}
const hasFlash = async (): Promise<boolean> => {
if (qrScanner) {
try {
return await qrScanner.hasFlash()
} catch (err) {
return false
}
}
return false
}
// Cleanup on unmount
onUnmounted(() => {
stopScanning()
})
return {
isScanning,
hasPermission,
error,
scanResult,
startScanning,
stopScanning,
toggleFlash,
hasFlash
}
}