Files
crowd-funder-for-time-pwa/src/services/QRScanner/WebDialogQRScanner.ts
Matthew Raymer e5518cd47c fix: update Vue template syntax and improve Vite config
- Fix Vue template syntax in App.vue by using proper event handler format
- Update Vite config to properly handle ESM imports and crypto modules
- Add manual chunks for better code splitting
- Improve environment variable handling in vite-env.d.ts
- Fix TypeScript linting errors in App.vue
2025-04-18 09:59:33 +00:00

91 lines
2.5 KiB
TypeScript

import type { QRScannerService, ScanListener } from './types'
import QRScannerDialog from '../../components/QRScannerDialog.vue'
import { createApp, type App } from 'vue'
import { logger } from '../../utils/logger'
// Import platform-specific flags from Vite config
declare const __USE_QR_READER__: boolean
export class WebDialogQRScanner implements QRScannerService {
private dialogInstance: App | null = null
private dialogComponent: InstanceType<typeof QRScannerDialog> | null = null
private scanListener: ScanListener | null = null
async checkPermissions(): Promise<boolean> {
try {
const permissions = await navigator.permissions.query({
name: 'camera' as PermissionName
})
return permissions.state === 'granted'
} catch (error) {
logger.error('Error checking camera permissions:', error)
return false
}
}
async requestPermissions(): Promise<boolean> {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'environment' }
})
stream.getTracks().forEach((track) => track.stop())
return true
} catch (error) {
logger.error('Error requesting camera permissions:', error)
return false
}
}
async isSupported(): Promise<boolean> {
if (!__USE_QR_READER__) {
return false
}
return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia)
}
async startScan(): Promise<void> {
if (!__USE_QR_READER__) {
throw new Error('Web QR scanner is not supported on this platform')
}
if (!this.dialogInstance) {
const div = document.createElement('div')
document.body.appendChild(div)
this.dialogInstance = createApp(QRScannerDialog)
this.dialogComponent = this.dialogInstance.mount(div) as InstanceType<
typeof QRScannerDialog
>
}
if (this.dialogComponent && this.scanListener) {
this.dialogComponent.open((result: string) => {
if (this.scanListener) {
this.scanListener.onScan(result)
}
})
}
}
async stopScan(): Promise<void> {
if (this.dialogComponent) {
this.dialogComponent.close()
}
}
addListener(listener: ScanListener): void {
this.scanListener = listener
}
async cleanup(): Promise<void> {
if (this.dialogComponent) {
this.dialogComponent.close()
}
if (this.dialogInstance) {
this.dialogInstance.unmount()
this.dialogInstance = null
this.dialogComponent = null
}
}
}