diff --git a/src/db-sql/migration.ts b/src/db-sql/migration.ts index 50faeef5..25f345b4 100644 --- a/src/db-sql/migration.ts +++ b/src/db-sql/migration.ts @@ -129,7 +129,7 @@ export async function registerMigrations(): Promise { export async function runMigrations( sqlExec: ( sql: string, - params?: SqlValue[], + params?: unknown[], ) => Promise>, ): Promise { await registerMigrations(); diff --git a/src/interfaces/absurd-sql.d.ts b/src/interfaces/absurd-sql.d.ts index e113fe75..b1534f8d 100644 --- a/src/interfaces/absurd-sql.d.ts +++ b/src/interfaces/absurd-sql.d.ts @@ -13,10 +13,10 @@ declare module "@jlongster/sql.js" { } interface AbsurdSqlDatabase { - exec: (sql: string, params?: SqlValue[]) => Promise; + exec: (sql: string, params?: unknown[]) => Promise; run: ( sql: string, - params?: SqlValue[], + params?: unknown[], ) => Promise<{ changes: number; lastId?: number }>; } @@ -49,7 +49,7 @@ declare module "absurd-sql/dist/indexeddb-main-thread" { } export interface SQLiteDatabase { - exec: (sql: string, params?: SqlValue[]) => Promise; + exec: (sql: string, params?: unknown[]) => Promise; close: () => Promise; } diff --git a/src/services/AbsurdSqlDatabaseService.ts b/src/services/AbsurdSqlDatabaseService.ts index 7c03bf64..99d42fec 100644 --- a/src/services/AbsurdSqlDatabaseService.ts +++ b/src/services/AbsurdSqlDatabaseService.ts @@ -1,4 +1,3 @@ -// Remove inline declarations since they are now in src/types/absurd-sql.d.ts import initSqlJs from "@jlongster/sql.js"; import { SQLiteFS } from "absurd-sql"; import IndexedDBBackend from "absurd-sql/dist/indexeddb-backend"; diff --git a/src/services/QRScanner/CapacitorQRScanner.ts b/src/services/QRScanner/CapacitorQRScanner.ts index dc5a1f0b..15cfad1b 100644 --- a/src/services/QRScanner/CapacitorQRScanner.ts +++ b/src/services/QRScanner/CapacitorQRScanner.ts @@ -4,7 +4,7 @@ import { StartScanOptions, LensFacing, } from "@capacitor-mlkit/barcode-scanning"; -import { QRScannerService, ScanListener, QRScannerOptions } from "./types"; +import { QRScannerService, ScanListener, QRScannerOptions, CameraStateListener, CameraState } from "./types"; import { logger } from "@/utils/logger"; export class CapacitorQRScanner implements QRScannerService { @@ -12,6 +12,9 @@ export class CapacitorQRScanner implements QRScannerService { private isScanning = false; private listenerHandles: Array<() => Promise> = []; private cleanupPromise: Promise | null = null; + private cameraStateListeners: Set = new Set(); + private currentState: CameraState = "off"; + private currentStateMessage?: string; async checkPermissions(): Promise { try { @@ -79,8 +82,11 @@ export class CapacitorQRScanner implements QRScannerService { } try { + this.updateCameraState("initializing", "Starting camera..."); + // Ensure we have permissions before starting if (!(await this.checkPermissions())) { + this.updateCameraState("permission_denied", "Camera permission denied"); logger.debug("Requesting camera permissions"); const granted = await this.requestPermissions(); if (!granted) { @@ -90,11 +96,13 @@ export class CapacitorQRScanner implements QRScannerService { // Check if scanning is supported if (!(await this.isSupported())) { + this.updateCameraState("error", "QR scanning not supported on this device"); throw new Error("QR scanning not supported on this device"); } logger.info("Starting MLKit scanner"); this.isScanning = true; + this.updateCameraState("active", "Camera is active"); const scanOptions: StartScanOptions = { formats: [BarcodeFormat.QrCode], @@ -126,6 +134,7 @@ export class CapacitorQRScanner implements QRScannerService { stack: wrappedError.stack, }); this.isScanning = false; + this.updateCameraState("error", wrappedError.message); await this.cleanup(); this.scanListener?.onError?.(wrappedError); throw wrappedError; @@ -140,6 +149,7 @@ export class CapacitorQRScanner implements QRScannerService { try { logger.debug("Stopping QR scanner"); + this.updateCameraState("off", "Camera stopped"); await BarcodeScanner.stopScan(); logger.info("QR scanner stopped successfully"); } catch (error) { @@ -149,6 +159,7 @@ export class CapacitorQRScanner implements QRScannerService { error: wrappedError.message, stack: wrappedError.stack, }); + this.updateCameraState("error", wrappedError.message); this.scanListener?.onError?.(wrappedError); throw wrappedError; } finally { @@ -207,4 +218,23 @@ export class CapacitorQRScanner implements QRScannerService { // No-op for native scanner callback(null); } + + addCameraStateListener(listener: CameraStateListener): void { + this.cameraStateListeners.add(listener); + // Immediately notify the new listener of current state + listener.onStateChange(this.currentState, this.currentStateMessage); + } + + removeCameraStateListener(listener: CameraStateListener): void { + this.cameraStateListeners.delete(listener); + } + + private updateCameraState(state: CameraState, message?: string): void { + this.currentState = state; + this.currentStateMessage = message; + // Notify all listeners of state change + for (const listener of this.cameraStateListeners) { + listener.onStateChange(state, message); + } + } } diff --git a/tsconfig.electron.json b/tsconfig.electron.json index a2277a1c..73aec38b 100644 --- a/tsconfig.electron.json +++ b/tsconfig.electron.json @@ -19,8 +19,9 @@ } }, "include": [ - "src/electron/**/*.ts", - "src/utils/**/*.ts", - "src/constants/**/*.ts" + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue" ] } \ No newline at end of file