Browse Source

chore: cleanup and test

pull/132/head
Matthew Raymer 2 months ago
parent
commit
2855d4b8d5
  1. 3
      android/app/capacitor.build.gradle
  2. 4
      android/app/src/main/assets/capacitor.plugins.json
  3. 6
      android/capacitor.settings.gradle
  4. 30
      package-lock.json
  5. 25
      src/components/QRScanner/QRScannerDialog.vue
  6. 12
      src/services/QRScanner/CapacitorQRScanner.ts
  7. 18
      src/services/QRScanner/QRScannerFactory.ts
  8. 20
      src/services/platforms/CapacitorPlatformService.ts

3
android/app/capacitor.build.gradle

@ -9,12 +9,13 @@ android {
apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle" apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies { dependencies {
implementation project(':capacitor-mlkit-barcode-scanning')
implementation project(':capacitor-app') implementation project(':capacitor-app')
implementation project(':capacitor-camera') implementation project(':capacitor-camera')
implementation project(':capacitor-filesystem') implementation project(':capacitor-filesystem')
implementation project(':capacitor-share') implementation project(':capacitor-share')
implementation project(':capawesome-capacitor-file-picker') implementation project(':capawesome-capacitor-file-picker')
implementation project(':capacitor-mlkit-barcode-scanning')
} }

4
android/app/src/main/assets/capacitor.plugins.json

@ -1,4 +1,8 @@
[ [
{
"pkg": "@capacitor-mlkit/barcode-scanning",
"classpath": "io.capawesome.capacitorjs.plugins.mlkit.barcodescanning.BarcodeScannerPlugin"
},
{ {
"pkg": "@capacitor/app", "pkg": "@capacitor/app",
"classpath": "com.capacitorjs.plugins.app.AppPlugin" "classpath": "com.capacitorjs.plugins.app.AppPlugin"

6
android/capacitor.settings.gradle

@ -2,6 +2,9 @@
include ':capacitor-android' include ':capacitor-android'
project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor') project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/android/capacitor')
include ':capacitor-mlkit-barcode-scanning'
project(':capacitor-mlkit-barcode-scanning').projectDir = new File('../node_modules/@capacitor-mlkit/barcode-scanning/android')
include ':capacitor-app' include ':capacitor-app'
project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android') project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android')
@ -16,6 +19,3 @@ project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/sh
include ':capawesome-capacitor-file-picker' include ':capawesome-capacitor-file-picker'
project(':capawesome-capacitor-file-picker').projectDir = new File('../node_modules/@capawesome/capacitor-file-picker/android') project(':capawesome-capacitor-file-picker').projectDir = new File('../node_modules/@capawesome/capacitor-file-picker/android')
include ':capacitor-mlkit-barcode-scanning'
project(':capacitor-mlkit-barcode-scanning').projectDir = new File('../node_modules/@capacitor-mlkit/barcode-scanning/android')

30
package-lock.json

@ -2607,9 +2607,9 @@
} }
}, },
"node_modules/@capacitor-mlkit/barcode-scanning": { "node_modules/@capacitor-mlkit/barcode-scanning": {
"version": "6.0.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/@capacitor-mlkit/barcode-scanning/-/barcode-scanning-6.0.0.tgz", "resolved": "https://registry.npmjs.org/@capacitor-mlkit/barcode-scanning/-/barcode-scanning-6.2.0.tgz",
"integrity": "sha512-zW5UKgFtUui9qFV8PBxPzX+07gntyt5owW4S/GhOt4xWGaoxDZWERaA+XJnXgmMxS/MnPIHX2mL+mhMd1A0enQ==", "integrity": "sha512-XnnErDabpCUty9flugqB646ERejCxrtKcKOJrdoh9ZVLTQXUnyjxUDWOlqHVxrBHy+e86ZgpZX7D5zcaNvS0lQ==",
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -10544,9 +10544,9 @@
} }
}, },
"node_modules/@veramo/did-provider-peer/node_modules/did-jwt": { "node_modules/@veramo/did-provider-peer/node_modules/did-jwt": {
"version": "8.0.11", "version": "8.0.12",
"resolved": "https://registry.npmjs.org/did-jwt/-/did-jwt-8.0.11.tgz", "resolved": "https://registry.npmjs.org/did-jwt/-/did-jwt-8.0.12.tgz",
"integrity": "sha512-Uz2BRDr/PoLyXXPLSziNVVvFc3XgZCnB2bDla+5/FGgbdbWDzVqOyTUMxSNbUlsmrmHeZMH3KnaybW+PfplGNA==", "integrity": "sha512-tfKeyT/5RkfvUVj/yIKi3ytElQsSj7Aq8V6zIX0gXFf4tVde32m3zJr4GJqlQiRyb7QE91zSsnyOXiWCPMZIXw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@noble/ciphers": "^1.0.0", "@noble/ciphers": "^1.0.0",
@ -10561,9 +10561,9 @@
} }
}, },
"node_modules/@veramo/did-provider-peer/node_modules/did-jwt-vc": { "node_modules/@veramo/did-provider-peer/node_modules/did-jwt-vc": {
"version": "4.0.9", "version": "4.0.10",
"resolved": "https://registry.npmjs.org/did-jwt-vc/-/did-jwt-vc-4.0.9.tgz", "resolved": "https://registry.npmjs.org/did-jwt-vc/-/did-jwt-vc-4.0.10.tgz",
"integrity": "sha512-kDpVLZFf2nO/taasDR3Hw/ow56pZFZzI677urWhAELach+3Q6lijQhBMNnuAyjUVWr1NiHOnBp1QHzBBf8zN7w==", "integrity": "sha512-Ctxnrdqzk1FbIB+EP9hDnrBnQZ2Fye59YpoooqxhqtHGFQKuX90FdeWHMdEA/En6/DM59eCVoTOwzvk2NEc+BQ==",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"did-jwt": "^8.0.0", "did-jwt": "^8.0.0",
@ -15413,9 +15413,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.139", "version": "1.5.140",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.139.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.140.tgz",
"integrity": "sha512-GGnRYOTdN5LYpwbIr0rwP/ZHOQSvAF6TG0LSzp28uCBb9JiXHJGmaaKw29qjNJc5bGnnp6kXJqRnGMQoELwi5w==", "integrity": "sha512-o82Rj+ONp4Ip7Cl1r7lrqx/pXhbp/lh9DpKcMNscFJdh8ebyRofnc7Sh01B4jx403RI0oqTBvlZ7OBIZLMr2+Q==",
"devOptional": true, "devOptional": true,
"license": "ISC" "license": "ISC"
}, },
@ -16256,9 +16256,9 @@
} }
}, },
"node_modules/ethr-did/node_modules/did-jwt": { "node_modules/ethr-did/node_modules/did-jwt": {
"version": "8.0.11", "version": "8.0.12",
"resolved": "https://registry.npmjs.org/did-jwt/-/did-jwt-8.0.11.tgz", "resolved": "https://registry.npmjs.org/did-jwt/-/did-jwt-8.0.12.tgz",
"integrity": "sha512-Uz2BRDr/PoLyXXPLSziNVVvFc3XgZCnB2bDla+5/FGgbdbWDzVqOyTUMxSNbUlsmrmHeZMH3KnaybW+PfplGNA==", "integrity": "sha512-tfKeyT/5RkfvUVj/yIKi3ytElQsSj7Aq8V6zIX0gXFf4tVde32m3zJr4GJqlQiRyb7QE91zSsnyOXiWCPMZIXw==",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@noble/ciphers": "^1.0.0", "@noble/ciphers": "^1.0.0",

25
src/components/QRScanner/QRScannerDialog.vue

@ -33,7 +33,10 @@
<!-- Scanner --> <!-- Scanner -->
<div class="p-4"> <div class="p-4">
<div v-if="useQRReader && !isNativePlatform" class="relative aspect-square"> <div
v-if="useQRReader && !isNativePlatform"
class="relative aspect-square"
>
<qrcode-stream <qrcode-stream
:camera="options?.camera === 'front' ? 'user' : 'environment'" :camera="options?.camera === 'front' ? 'user' : 'environment'"
@decode="onDecode" @decode="onDecode"
@ -45,7 +48,11 @@
</div> </div>
<div v-else class="text-center py-8"> <div v-else class="text-center py-8">
<p class="text-gray-500"> <p class="text-gray-500">
{{ isNativePlatform ? 'Using native camera scanner...' : 'QR code scanning is not supported in this browser.' }} {{
isNativePlatform
? "Using native camera scanner..."
: "QR code scanning is not supported in this browser."
}}
</p> </p>
</div> </div>
</div> </div>
@ -86,20 +93,24 @@ export default class QRScannerDialog extends Vue {
visible = true; visible = true;
error: string | null = null; error: string | null = null;
useQRReader = __USE_QR_READER__; useQRReader = __USE_QR_READER__;
isNativePlatform = Capacitor.isNativePlatform() || __IS_MOBILE__ || Capacitor.getPlatform() === 'android' || Capacitor.getPlatform() === 'ios'; isNativePlatform =
Capacitor.isNativePlatform() ||
__IS_MOBILE__ ||
Capacitor.getPlatform() === "android" ||
Capacitor.getPlatform() === "ios";
created() { created() {
logger.log('QRScannerDialog platform detection:', { logger.log("QRScannerDialog platform detection:", {
capacitorNative: Capacitor.isNativePlatform(), capacitorNative: Capacitor.isNativePlatform(),
isMobile: __IS_MOBILE__, isMobile: __IS_MOBILE__,
platform: Capacitor.getPlatform(), platform: Capacitor.getPlatform(),
useQRReader: this.useQRReader, useQRReader: this.useQRReader,
isNativePlatform: this.isNativePlatform isNativePlatform: this.isNativePlatform,
}); });
// If on native platform, close immediately and don't initialize web scanner // If on native platform, close immediately and don't initialize web scanner
if (this.isNativePlatform) { if (this.isNativePlatform) {
logger.log('Closing QR dialog on native platform'); logger.log("Closing QR dialog on native platform");
this.$nextTick(() => this.close()); this.$nextTick(() => this.close());
} }
} }
@ -107,7 +118,7 @@ export default class QRScannerDialog extends Vue {
async onInit(promise: Promise<void>): Promise<void> { async onInit(promise: Promise<void>): Promise<void> {
// Don't initialize on mobile platforms // Don't initialize on mobile platforms
if (this.isNativePlatform) { if (this.isNativePlatform) {
logger.log('Skipping web scanner initialization on native platform'); logger.log("Skipping web scanner initialization on native platform");
return; return;
} }

12
src/services/QRScanner/CapacitorQRScanner.ts

@ -54,9 +54,9 @@ export class CapacitorQRScanner implements QRScannerService {
try { try {
// Ensure we have permissions before starting // Ensure we have permissions before starting
logger.log('Checking camera permissions...'); logger.log("Checking camera permissions...");
if (!(await this.checkPermissions())) { if (!(await this.checkPermissions())) {
logger.log('Requesting camera permissions...'); logger.log("Requesting camera permissions...");
const granted = await this.requestPermissions(); const granted = await this.requestPermissions();
if (!granted) { if (!granted) {
throw new Error("Camera permission denied"); throw new Error("Camera permission denied");
@ -64,12 +64,12 @@ export class CapacitorQRScanner implements QRScannerService {
} }
// Check if scanning is supported // Check if scanning is supported
logger.log('Checking scanner support...'); logger.log("Checking scanner support...");
if (!(await this.isSupported())) { if (!(await this.isSupported())) {
throw new Error("QR scanning not supported on this device"); throw new Error("QR scanning not supported on this device");
} }
logger.log('Starting MLKit scanner...'); logger.log("Starting MLKit scanner...");
this.isScanning = true; this.isScanning = true;
const scanOptions: StartScanOptions = { const scanOptions: StartScanOptions = {
@ -78,9 +78,9 @@ export class CapacitorQRScanner implements QRScannerService {
options?.camera === "front" ? LensFacing.Front : LensFacing.Back, options?.camera === "front" ? LensFacing.Front : LensFacing.Back,
}; };
logger.log('Scanner options:', scanOptions); logger.log("Scanner options:", scanOptions);
const result = await BarcodeScanner.scan(scanOptions); const result = await BarcodeScanner.scan(scanOptions);
logger.log('Scan result:', result); logger.log("Scan result:", result);
if (result.barcodes.length > 0) { if (result.barcodes.length > 0) {
this.scanListener?.onScan(result.barcodes[0].rawValue); this.scanListener?.onScan(result.barcodes[0].rawValue);

18
src/services/QRScanner/QRScannerFactory.ts

@ -15,15 +15,15 @@ export class QRScannerFactory {
const isMobile = __IS_MOBILE__; const isMobile = __IS_MOBILE__;
const platform = Capacitor.getPlatform(); const platform = Capacitor.getPlatform();
logger.log('Platform detection:', { logger.log("Platform detection:", {
capacitorNative, capacitorNative,
isMobile, isMobile,
platform, platform,
userAgent: navigator.userAgent userAgent: navigator.userAgent,
}); });
// Force native scanner on Android/iOS // Force native scanner on Android/iOS
if (platform === 'android' || platform === 'ios') { if (platform === "android" || platform === "ios") {
return true; return true;
} }
@ -36,16 +36,20 @@ export class QRScannerFactory {
static getInstance(): QRScannerService { static getInstance(): QRScannerService {
if (!this.instance) { if (!this.instance) {
const isNative = this.isNativePlatform(); const isNative = this.isNativePlatform();
logger.log(`Creating QR scanner for platform: ${isNative ? 'native' : 'web'}`); logger.log(
`Creating QR scanner for platform: ${isNative ? "native" : "web"}`,
);
if (isNative) { if (isNative) {
logger.log('Using native MLKit scanner'); logger.log("Using native MLKit scanner");
this.instance = new CapacitorQRScanner(); this.instance = new CapacitorQRScanner();
} else if (__USE_QR_READER__) { } else if (__USE_QR_READER__) {
logger.log('Using web QR scanner'); logger.log("Using web QR scanner");
this.instance = new WebDialogQRScanner(); this.instance = new WebDialogQRScanner();
} else { } else {
throw new Error("No QR scanner implementation available for this platform"); throw new Error(
"No QR scanner implementation available for this platform",
);
} }
} }
return this.instance!; // We know it's not null here return this.instance!; // We know it's not null here

20
src/services/platforms/CapacitorPlatformService.ts

@ -318,12 +318,12 @@ export class CapacitorPlatformService implements PlatformService {
async writeAndShareFile(fileName: string, content: string): Promise<void> { async writeAndShareFile(fileName: string, content: string): Promise<void> {
const timestamp = new Date().toISOString(); const timestamp = new Date().toISOString();
const logData = { const logData = {
action: 'writeAndShareFile', action: "writeAndShareFile",
fileName, fileName,
contentLength: content.length, contentLength: content.length,
timestamp, timestamp,
}; };
logger.log('[CapacitorPlatformService]', JSON.stringify(logData, null, 2)); logger.log("[CapacitorPlatformService]", JSON.stringify(logData, null, 2));
try { try {
const { uri } = await Filesystem.writeFile({ const { uri } = await Filesystem.writeFile({
@ -334,13 +334,16 @@ export class CapacitorPlatformService implements PlatformService {
recursive: true, recursive: true,
}); });
logger.log('[CapacitorPlatformService] File write successful:', { uri, timestamp: new Date().toISOString() }); logger.log("[CapacitorPlatformService] File write successful:", {
uri,
timestamp: new Date().toISOString(),
});
await Share.share({ await Share.share({
title: 'TimeSafari Backup', title: "TimeSafari Backup",
text: 'Here is your backup file.', text: "Here is your backup file.",
url: uri, url: uri,
dialogTitle: 'Share your backup file', dialogTitle: "Share your backup file",
}); });
} catch (error) { } catch (error) {
const err = error as Error; const err = error as Error;
@ -349,7 +352,10 @@ export class CapacitorPlatformService implements PlatformService {
stack: err.stack, stack: err.stack,
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
}; };
logger.error('[CapacitorPlatformService] Error writing or sharing file:', JSON.stringify(errLog, null, 2)); logger.error(
"[CapacitorPlatformService] Error writing or sharing file:",
JSON.stringify(errLog, null, 2),
);
throw new Error(`Failed to write or share file: ${err.message}`); throw new Error(`Failed to write or share file: ${err.message}`);
} }
} }

Loading…
Cancel
Save