feature(qrcode): reboot qrcode reader

This commit is contained in:
Matthew Raymer
2025-04-21 10:13:12 +00:00
parent 2b7b07441e
commit ff605b3676
11 changed files with 1676 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
import {
BarcodeScanner,
BarcodeFormat,
StartScanOptions,
LensFacing,
} from "@capacitor-mlkit/barcode-scanning";
import { QRScannerService, ScanListener, QRScannerOptions } from "./types";
import { logger } from "@/utils/logger";
export class CapacitorQRScanner implements QRScannerService {
private scanListener: ScanListener | null = null;
private isScanning = false;
async checkPermissions(): Promise<boolean> {
try {
const { camera } = await BarcodeScanner.checkPermissions();
return camera === "granted";
} catch (error) {
logger.error("Error checking camera permissions:", error);
return false;
}
}
async requestPermissions(): Promise<boolean> {
try {
// First check if we already have permissions
if (await this.checkPermissions()) {
return true;
}
// Request permissions if we don't have them
const { camera } = await BarcodeScanner.requestPermissions();
return camera === "granted";
} catch (error) {
logger.error("Error requesting camera permissions:", error);
return false;
}
}
async isSupported(): Promise<boolean> {
try {
const { supported } = await BarcodeScanner.isSupported();
return supported;
} catch (error) {
logger.error("Error checking scanner support:", error);
return false;
}
}
async startScan(options?: QRScannerOptions): Promise<void> {
if (this.isScanning) {
return;
}
try {
// Ensure we have permissions before starting
logger.log('Checking camera permissions...');
if (!(await this.checkPermissions())) {
logger.log('Requesting camera permissions...');
const granted = await this.requestPermissions();
if (!granted) {
throw new Error("Camera permission denied");
}
}
// Check if scanning is supported
logger.log('Checking scanner support...');
if (!(await this.isSupported())) {
throw new Error("QR scanning not supported on this device");
}
logger.log('Starting MLKit scanner...');
this.isScanning = true;
const scanOptions: StartScanOptions = {
formats: [BarcodeFormat.QrCode],
lensFacing:
options?.camera === "front" ? LensFacing.Front : LensFacing.Back,
};
logger.log('Scanner options:', scanOptions);
const result = await BarcodeScanner.scan(scanOptions);
logger.log('Scan result:', result);
if (result.barcodes.length > 0) {
this.scanListener?.onScan(result.barcodes[0].rawValue);
}
} catch (error) {
logger.error("Error during QR scan:", error);
this.scanListener?.onError?.(error as Error);
} finally {
this.isScanning = false;
}
}
async stopScan(): Promise<void> {
if (!this.isScanning) {
return;
}
try {
await BarcodeScanner.stopScan();
this.isScanning = false;
} catch (error) {
logger.error("Error stopping QR scan:", error);
this.scanListener?.onError?.(error as Error);
}
}
addListener(listener: ScanListener): void {
this.scanListener = listener;
}
async cleanup(): Promise<void> {
await this.stopScan();
this.scanListener = null;
}
}