forked from jsnbuchanan/crowd-funder-for-time-pwa
feat(qr-scanner): Add camera state management to CapacitorQRScanner
- Add camera state tracking and listener management - Implement addCameraStateListener and removeCameraStateListener methods - Add state transitions during scanning operations - Improve error handling with state updates - Add proper type imports for CameraState and CameraStateListener This change ensures CapacitorQRScanner fully implements the QRScannerService interface and provides proper camera state feedback to consumers. Camera state is now tracked through the entire lifecycle of scanning operations, with appropriate state transitions for initialization, active scanning, errors, and cleanup.
This commit is contained in:
@@ -129,7 +129,7 @@ export async function registerMigrations(): Promise<void> {
|
||||
export async function runMigrations(
|
||||
sqlExec: (
|
||||
sql: string,
|
||||
params?: SqlValue[],
|
||||
params?: unknown[],
|
||||
) => Promise<Array<QueryExecResult>>,
|
||||
): Promise<void> {
|
||||
await registerMigrations();
|
||||
|
||||
6
src/interfaces/absurd-sql.d.ts
vendored
6
src/interfaces/absurd-sql.d.ts
vendored
@@ -13,10 +13,10 @@ declare module "@jlongster/sql.js" {
|
||||
}
|
||||
|
||||
interface AbsurdSqlDatabase {
|
||||
exec: (sql: string, params?: SqlValue[]) => Promise<QueryExecResult[]>;
|
||||
exec: (sql: string, params?: unknown[]) => Promise<QueryExecResult[]>;
|
||||
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<QueryExecResult[]>;
|
||||
exec: (sql: string, params?: unknown[]) => Promise<QueryExecResult[]>;
|
||||
close: () => Promise<void>;
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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<void>> = [];
|
||||
private cleanupPromise: Promise<void> | null = null;
|
||||
private cameraStateListeners: Set<CameraStateListener> = new Set();
|
||||
private currentState: CameraState = "off";
|
||||
private currentStateMessage?: string;
|
||||
|
||||
async checkPermissions(): Promise<boolean> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"src/electron/**/*.ts",
|
||||
"src/utils/**/*.ts",
|
||||
"src/constants/**/*.ts"
|
||||
"src/**/*.ts",
|
||||
"src/**/*.d.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user