diff --git a/src/components/DataExportSection.vue b/src/components/DataExportSection.vue index 0c14b570..bd7cafdf 100644 --- a/src/components/DataExportSection.vue +++ b/src/components/DataExportSection.vue @@ -139,22 +139,7 @@ export default class DataExportSection extends Vue { const blob = await db.export({ prettyJson: true }); const fileName = `${db.name}-backup.json`; - if (this.platformService.isWeb()) { - // Web platform: Use download link - this.downloadUrl = URL.createObjectURL(blob); - const downloadAnchor = this.$refs.downloadLink as HTMLAnchorElement; - downloadAnchor.href = this.downloadUrl; - downloadAnchor.download = fileName; - downloadAnchor.click(); - setTimeout(() => URL.revokeObjectURL(this.downloadUrl), 1000); - } else if (this.platformService.isCapacitor()) { - // Capacitor platform: Write to app directory - const content = await blob.text(); - await this.platformService.writeFile(fileName, content); - } else { - // Other platforms: Use platform service - await this.platformService.writeFile(fileName, await blob.text()); - } + await this.platformService.exportDatabase(blob, fileName); this.$notify( { diff --git a/src/services/PlatformService.ts b/src/services/PlatformService.ts index 821261ee..c58f6d71 100644 --- a/src/services/PlatformService.ts +++ b/src/services/PlatformService.ts @@ -46,6 +46,15 @@ export interface PlatformService { */ listFiles(directory: string): Promise; + /** + * Exports a database blob to a file, handling platform-specific save operations. + * @param blob - The database blob to export + * @param fileName - The name of the file to save + * @returns Promise that resolves when the export is complete + * @throws Error if export fails + */ + exportDatabase(blob: Blob, fileName: string): Promise; + // Camera operations /** * Activates the device camera to take a picture. diff --git a/src/services/platforms/CapacitorPlatformService.ts b/src/services/platforms/CapacitorPlatformService.ts index b6ba1198..b3bcffa8 100644 --- a/src/services/platforms/CapacitorPlatformService.ts +++ b/src/services/platforms/CapacitorPlatformService.ts @@ -2,6 +2,7 @@ import { ImageResult, PlatformService } from "../PlatformService"; import { Filesystem, Directory } from "@capacitor/filesystem"; import { Camera, CameraResultType, CameraSource } from "@capacitor/camera"; import { logger } from "../../utils/logger"; +import { Share } from "@capacitor/share"; /** * Platform service implementation for Capacitor (mobile) platform. @@ -188,4 +189,55 @@ export class CapacitorPlatformService implements PlatformService { // This is just a placeholder for the interface return Promise.resolve(); } + + async exportDatabase(blob: Blob, fileName: string): Promise { + // Create a File object from the Blob + const file = new File([blob], fileName, { type: 'application/json' }); + + try { + // Use the native share sheet + await navigator.share({ + files: [file], + title: fileName, + }); + } catch (error) { + // Fallback to Capacitor Share API if Web Share API fails + // First save to temporary file + const base64Data = await this.blobToBase64(blob); + const result = await Filesystem.writeFile({ + path: fileName, + data: base64Data, + directory: Directory.Cache, // Use Cache instead of Documents for temporary files + recursive: true + }); + + // Then share using Capacitor Share API + await Share.share({ + title: fileName, + url: result.uri + }); + + // Clean up the temporary file + try { + await Filesystem.deleteFile({ + path: fileName, + directory: Directory.Cache + }); + } catch (cleanupError) { + logger.warn('Failed to clean up temporary file:', cleanupError); + } + } + } + + private async blobToBase64(blob: Blob): Promise { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onloadend = () => { + const base64data = reader.result as string; + resolve(base64data.split(',')[1]); + }; + reader.onerror = reject; + reader.readAsDataURL(blob); + }); + } } diff --git a/src/services/platforms/WebPlatformService.ts b/src/services/platforms/WebPlatformService.ts index 9a65278a..7e94357f 100644 --- a/src/services/platforms/WebPlatformService.ts +++ b/src/services/platforms/WebPlatformService.ts @@ -209,4 +209,13 @@ export class WebPlatformService implements PlatformService { // Web platform can handle deep links through URL parameters return Promise.resolve(); } + + async exportDatabase(blob: Blob, fileName: string): Promise { + const downloadUrl = URL.createObjectURL(blob); + const downloadAnchor = document.createElement('a'); + downloadAnchor.href = downloadUrl; + downloadAnchor.download = fileName; + downloadAnchor.click(); + setTimeout(() => URL.revokeObjectURL(downloadUrl), 1000); + } }