fix(qr): improve QR scanner implementation and error handling

- Implement robust QR scanner factory with platform detection
- Add proper camera permissions to Android manifest
- Improve error handling and logging across scanner implementations
- Add continuous scanning mode for Capacitor/MLKit scanner
- Enhance UI feedback during scanning process
- Fix build configuration for proper platform detection
- Clean up resources properly in scanner components
- Add TypeScript improvements and error wrapping

The changes include:
- Adding CAMERA permission to AndroidManifest.xml
- Setting proper build flags (__IS_MOBILE__, __USE_QR_READER__)
- Implementing continuous scanning mode for better UX
- Adding proper cleanup of scanner resources
- Improving error handling and type safety
- Enhancing UI with loading states and error messages
This commit is contained in:
Matthew Raymer
2025-04-22 10:00:37 +00:00
parent 2855d4b8d5
commit a8812714a3
10 changed files with 548 additions and 451 deletions

View File

@@ -80,15 +80,21 @@ import { QRScannerOptions } from "@/services/QRScanner/types";
import { logger } from "@/utils/logger";
import { Capacitor } from "@capacitor/core";
interface ScanProps {
onScan: (result: string) => void;
onError?: (error: Error) => void;
options?: QRScannerOptions;
}
@Component({
components: {
QrcodeStream,
},
})
export default class QRScannerDialog extends Vue {
@Prop({ type: Function, required: true }) onScan!: (result: string) => void;
@Prop({ type: Function }) onError?: (error: Error) => void;
@Prop({ type: Object }) options?: QRScannerOptions;
@Prop({ type: Function, required: true }) onScan!: ScanProps['onScan'];
@Prop({ type: Function }) onError?: ScanProps['onError'];
@Prop({ type: Object }) options?: ScanProps['options'];
visible = true;
error: string | null = null;
@@ -126,11 +132,12 @@ export default class QRScannerDialog extends Vue {
await promise;
this.error = null;
} catch (error) {
this.error = error instanceof Error ? error.message : String(error);
const wrappedError = error instanceof Error ? error : new Error(String(error));
this.error = wrappedError.message;
if (this.onError) {
this.onError(error instanceof Error ? error : new Error(String(error)));
this.onError(wrappedError);
}
logger.error("Error initializing QR scanner:", error);
logger.error("Error initializing QR scanner:", wrappedError);
}
}
@@ -139,11 +146,12 @@ export default class QRScannerDialog extends Vue {
this.onScan(result);
this.close();
} catch (error) {
this.error = error instanceof Error ? error.message : String(error);
const wrappedError = error instanceof Error ? error : new Error(String(error));
this.error = wrappedError.message;
if (this.onError) {
this.onError(error instanceof Error ? error : new Error(String(error)));
this.onError(wrappedError);
}
logger.error("Error handling QR scan result:", error);
logger.error("Error handling QR scan result:", wrappedError);
}
}