forked from trent_larson/crowd-funder-for-time-pwa
- Add @capacitor/camera@6.0.0 for cross-platform photo capture - Add @capacitor/filesystem@6.0.0 for file system operations - Maintain compatibility with existing Capacitor core v6.2.1 These plugins enable native camera access and file system operations for the Capacitor platform implementation.
122 lines
3.2 KiB
TypeScript
122 lines
3.2 KiB
TypeScript
import { ImageResult, PlatformService } from "../PlatformService";
|
|
import { Capacitor } from "@capacitor/core";
|
|
import { Filesystem, Directory } from "@capacitor/filesystem";
|
|
import { Camera, CameraResultType, CameraSource } from "@capacitor/camera";
|
|
import { App } from "@capacitor/app";
|
|
import { logger } from "../../utils/logger";
|
|
|
|
export class CapacitorPlatformService implements PlatformService {
|
|
async readFile(path: string): Promise<string> {
|
|
const file = await Filesystem.readFile({
|
|
path,
|
|
directory: Directory.Data,
|
|
});
|
|
return file.data;
|
|
}
|
|
|
|
async writeFile(path: string, content: string): Promise<void> {
|
|
await Filesystem.writeFile({
|
|
path,
|
|
data: content,
|
|
directory: Directory.Data,
|
|
});
|
|
}
|
|
|
|
async deleteFile(path: string): Promise<void> {
|
|
await Filesystem.deleteFile({
|
|
path,
|
|
directory: Directory.Data,
|
|
});
|
|
}
|
|
|
|
async listFiles(directory: string): Promise<string[]> {
|
|
const result = await Filesystem.readdir({
|
|
path: directory,
|
|
directory: Directory.Data,
|
|
});
|
|
return result.files;
|
|
}
|
|
|
|
async takePicture(): Promise<ImageResult> {
|
|
try {
|
|
const image = await Camera.getPhoto({
|
|
quality: 90,
|
|
allowEditing: true,
|
|
resultType: CameraResultType.Base64,
|
|
source: CameraSource.Camera,
|
|
});
|
|
|
|
const blob = await this.processImageData(image.base64String);
|
|
return {
|
|
blob,
|
|
fileName: `photo_${Date.now()}.${image.format || "jpg"}`,
|
|
};
|
|
} catch (error) {
|
|
logger.error("Error taking picture with Capacitor:", error);
|
|
throw new Error("Failed to take picture");
|
|
}
|
|
}
|
|
|
|
async pickImage(): Promise<ImageResult> {
|
|
try {
|
|
const image = await Camera.getPhoto({
|
|
quality: 90,
|
|
allowEditing: true,
|
|
resultType: CameraResultType.Base64,
|
|
source: CameraSource.Photos,
|
|
});
|
|
|
|
const blob = await this.processImageData(image.base64String);
|
|
return {
|
|
blob,
|
|
fileName: `photo_${Date.now()}.${image.format || "jpg"}`,
|
|
};
|
|
} catch (error) {
|
|
logger.error("Error picking image with Capacitor:", error);
|
|
throw new Error("Failed to pick image");
|
|
}
|
|
}
|
|
|
|
private async processImageData(base64String?: string): Promise<Blob> {
|
|
if (!base64String) {
|
|
throw new Error("No image data received");
|
|
}
|
|
|
|
// Convert base64 to blob
|
|
const byteCharacters = atob(base64String);
|
|
const byteArrays = [];
|
|
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
|
|
const slice = byteCharacters.slice(offset, offset + 512);
|
|
const byteNumbers = new Array(slice.length);
|
|
for (let i = 0; i < slice.length; i++) {
|
|
byteNumbers[i] = slice.charCodeAt(i);
|
|
}
|
|
const byteArray = new Uint8Array(byteNumbers);
|
|
byteArrays.push(byteArray);
|
|
}
|
|
return new Blob(byteArrays, { type: "image/jpeg" });
|
|
}
|
|
|
|
isCapacitor(): boolean {
|
|
return true;
|
|
}
|
|
|
|
isElectron(): boolean {
|
|
return false;
|
|
}
|
|
|
|
isPyWebView(): boolean {
|
|
return false;
|
|
}
|
|
|
|
isWeb(): boolean {
|
|
return false;
|
|
}
|
|
|
|
async handleDeepLink(url: string): Promise<void> {
|
|
// Capacitor handles deep links automatically
|
|
// This is just a placeholder for the interface
|
|
return Promise.resolve();
|
|
}
|
|
}
|