import { BarcodeScanner, BarcodeFormat, LensFacing } from '@capacitor-mlkit/barcode-scanning' import type { PluginListenerHandle } from '@capacitor/core' import { QRScannerService, ScanListener } from './types' export class NativeQRScanner implements QRScannerService { private scanListener: ScanListener | null = null private isScanning = false private listenerHandle: PluginListenerHandle | null = null async checkPermissions(): Promise { const { camera } = await BarcodeScanner.checkPermissions() return camera === 'granted' } async requestPermissions(): Promise { const { camera } = await BarcodeScanner.requestPermissions() return camera === 'granted' } async isSupported(): Promise { const { supported } = await BarcodeScanner.isSupported() return supported } async startScan(): Promise { if (this.isScanning) { throw new Error('Scanner is already running') } try { this.isScanning = true await BarcodeScanner.startScan({ formats: [BarcodeFormat.QrCode], lensFacing: LensFacing.Back }) this.listenerHandle = await BarcodeScanner.addListener( 'barcodesScanned', async (result) => { if (result.barcodes.length > 0 && this.scanListener) { const barcode = result.barcodes[0] this.scanListener.onScan(barcode.rawValue) await this.stopScan() } } ) } catch (error) { this.isScanning = false if (this.scanListener?.onError) { this.scanListener.onError(new Error(String(error))) } throw error } } async stopScan(): Promise { if (!this.isScanning) { return } try { await BarcodeScanner.stopScan() this.isScanning = false } catch (error) { if (this.scanListener?.onError) { this.scanListener.onError(new Error(String(error))) } throw error } } addListener(listener: ScanListener): void { this.scanListener = listener } async cleanup(): Promise { await this.stopScan() if (this.listenerHandle) { await this.listenerHandle.remove() this.listenerHandle = null } this.scanListener = null } }