feat: Improve database export with native sharing on mobile
- Enhance CapacitorPlatformService to use native share sheet via Web Share API - Add fallback to Capacitor Share API with temporary file storage - Implement WebPlatformService export with direct download for desktop - Clean up temporary files and URLs after sharing/download The changes provide a more platform-appropriate experience: - Mobile: Uses system share sheet for flexible saving/sharing options - Desktop: Direct download to user's download folder
This commit is contained in:
@@ -139,22 +139,7 @@ export default class DataExportSection extends Vue {
|
|||||||
const blob = await db.export({ prettyJson: true });
|
const blob = await db.export({ prettyJson: true });
|
||||||
const fileName = `${db.name}-backup.json`;
|
const fileName = `${db.name}-backup.json`;
|
||||||
|
|
||||||
if (this.platformService.isWeb()) {
|
await this.platformService.exportDatabase(blob, fileName);
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -46,6 +46,15 @@ export interface PlatformService {
|
|||||||
*/
|
*/
|
||||||
listFiles(directory: string): Promise<string[]>;
|
listFiles(directory: string): Promise<string[]>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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<void>;
|
||||||
|
|
||||||
// Camera operations
|
// Camera operations
|
||||||
/**
|
/**
|
||||||
* Activates the device camera to take a picture.
|
* Activates the device camera to take a picture.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { ImageResult, PlatformService } from "../PlatformService";
|
|||||||
import { Filesystem, Directory } from "@capacitor/filesystem";
|
import { Filesystem, Directory } from "@capacitor/filesystem";
|
||||||
import { Camera, CameraResultType, CameraSource } from "@capacitor/camera";
|
import { Camera, CameraResultType, CameraSource } from "@capacitor/camera";
|
||||||
import { logger } from "../../utils/logger";
|
import { logger } from "../../utils/logger";
|
||||||
|
import { Share } from "@capacitor/share";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Platform service implementation for Capacitor (mobile) platform.
|
* Platform service implementation for Capacitor (mobile) platform.
|
||||||
@@ -188,4 +189,55 @@ export class CapacitorPlatformService implements PlatformService {
|
|||||||
// This is just a placeholder for the interface
|
// This is just a placeholder for the interface
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async exportDatabase(blob: Blob, fileName: string): Promise<void> {
|
||||||
|
// 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<string> {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,4 +209,13 @@ export class WebPlatformService implements PlatformService {
|
|||||||
// Web platform can handle deep links through URL parameters
|
// Web platform can handle deep links through URL parameters
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async exportDatabase(blob: Blob, fileName: string): Promise<void> {
|
||||||
|
const downloadUrl = URL.createObjectURL(blob);
|
||||||
|
const downloadAnchor = document.createElement('a');
|
||||||
|
downloadAnchor.href = downloadUrl;
|
||||||
|
downloadAnchor.download = fileName;
|
||||||
|
downloadAnchor.click();
|
||||||
|
setTimeout(() => URL.revokeObjectURL(downloadUrl), 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user