Files
crowd-funder-for-time-pwa/src/components/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

75 lines
2.0 KiB
TypeScript

import type { QRScannerService, ScanListener } from './types'
import QRScannerDialog from './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 dialogApp: App | null = null
private dialogElement: HTMLDivElement | null = null
private scanListener: ScanListener | null = null
async checkPermissions(): Promise<boolean> {
return navigator?.mediaDevices !== undefined
}
async requestPermissions(): Promise<boolean> {
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true })
stream.getTracks().forEach((track) => track.stop())
return true
} catch (error) {
logger.error('Failed to get camera permissions:', error)
return false
}
}
async isSupported(): Promise<boolean> {
return Promise.resolve(
__USE_QR_READER__ && navigator?.mediaDevices !== undefined
)
}
async startScan(): Promise<void> {
if (!(await this.isSupported())) {
throw new Error('QR scanning is not supported in this environment')
}
this.dialogElement = document.createElement('div')
document.body.appendChild(this.dialogElement)
this.dialogApp = createApp(QRScannerDialog, {
onScan: (result: string) => {
if (this.scanListener) {
this.scanListener.onScan(result)
}
},
onClose: () => {
this.stopScan()
}
})
this.dialogApp.mount(this.dialogElement)
}
async stopScan(): Promise<void> {
if (this.dialogApp && this.dialogElement) {
this.dialogApp.unmount()
this.dialogElement.remove()
this.dialogApp = null
this.dialogElement = null
}
}
addListener(listener: ScanListener): void {
this.scanListener = listener
}
async cleanup(): Promise<void> {
await this.stopScan()
this.scanListener = null
}
}