/** * @fileoverview Electron Platform Service Implementation * @author Matthew Raymer * * Provides platform-specific functionality for Electron desktop applications. * This service extends CapacitorPlatformService to leverage Capacitor's APIs * while overriding desktop-specific behaviors. * * Key Features: * - Desktop-specific capabilities configuration * - Native IPC-based file operations with proper security * - Direct saving to user's Downloads folder via main process * - Native desktop integration support * * Architecture: * - Extends CapacitorPlatformService for API compatibility * - Overrides methods for desktop-specific implementations * - Maintains cross-platform service interface * * @since 1.0.0 */ import { CapacitorPlatformService } from "./CapacitorPlatformService"; import { logger } from "../../utils/logger"; /** * Electron-specific platform service implementation. * * This service handles the unique requirements of the Electron platform: * - Desktop-specific capabilities and UI patterns * - File system operations using Capacitor's Filesystem API * - Native desktop integration features * - Proper error handling with web fallbacks * * @extends CapacitorPlatformService * @example * ```typescript * const electronService = new ElectronPlatformService(); * await electronService.writeAndShareFile('backup.json', jsonData); * ``` */ export class ElectronPlatformService extends CapacitorPlatformService { /** * Gets the capabilities of the Electron platform. * Overrides the mobile-focused capabilities from CapacitorPlatformService * to provide desktop-specific feature flags. * * @returns Platform capabilities object specific to Electron */ getCapabilities() { return { hasFileSystem: true, hasCamera: false, // Desktop typically doesn't have integrated cameras for our use case isMobile: false, // Electron is desktop, not mobile isIOS: false, hasFileDownload: true, // Desktop supports direct file downloads needsFileHandlingInstructions: false, // Desktop users are familiar with file handling isNativeApp: true, // Electron is a native app }; } /** * Handles file export for Electron platform using native IPC. * * This method provides a secure, native file export mechanism that: * 1. Uses Electron's IPC (Inter-Process Communication) for secure file operations * 2. Writes files directly to the user's Downloads folder via the main process * 3. Provides exact file path feedback and proper error handling * 4. Falls back to web-style downloads if IPC is unavailable * * @param fileName - The name of the file to save (with date stamp) * @param content - The content to write to the file * @returns Promise that resolves when the file is successfully saved * @throws {Error} If both native IPC and fallback mechanisms fail * * @example * ```typescript * await electronService.writeAndShareFile('TimeSafari-backup-contacts-2025-07-06.json', jsonData); * ``` * * @note This implementation follows Electron's security best practices by: * - Using contextBridge to expose safe IPC methods * - Handling file operations in the main process with full filesystem access * - Providing exact file paths for better user experience * - Maintaining secure separation between renderer and main processes */ async writeAndShareFile(fileName: string, content: string): Promise { logger.info( `[ElectronPlatformService] Using native IPC for reliable file export: ${fileName}`, ); try { // Check if we're running in Electron with the API available if (typeof window !== "undefined" && window.electronAPI) { // Use the native Electron IPC API for file exports const result = await window.electronAPI.exportData(fileName, content); if (result.success) { logger.info( `[ElectronPlatformService] File exported successfully to: ${result.path}`, ); logger.info( `[ElectronPlatformService] File saved to Downloads folder: ${fileName}`, ); } else { logger.error( `[ElectronPlatformService] Native export failed: ${result.error}`, ); throw new Error(`Native file export failed: ${result.error}`); } } else { // Fallback to web-style download if Electron API is not available logger.warn( "[ElectronPlatformService] Electron API not available, falling back to web download", ); const blob = new Blob([content], { type: "application/json" }); const url = URL.createObjectURL(blob); const downloadLink = document.createElement("a"); downloadLink.href = url; downloadLink.download = fileName; downloadLink.style.display = "none"; document.body.appendChild(downloadLink); downloadLink.click(); document.body.removeChild(downloadLink); setTimeout(() => URL.revokeObjectURL(url), 1000); logger.info( `[ElectronPlatformService] Fallback download initiated: ${fileName}`, ); } } catch (error) { logger.error("[ElectronPlatformService] File export failed:", error); throw new Error(`Failed to export file: ${error}`); } } /** * Checks if running on Electron platform. * * @returns true, as this is the Electron implementation */ isElectron(): boolean { return true; } /** * Checks if running on Capacitor platform. * * @returns false, as this is Electron, not pure Capacitor */ isCapacitor(): boolean { return false; } /** * Checks if running on web platform. * * @returns false, as this is not web */ isWeb(): boolean { return false; } // --- PWA/Web-only methods (no-op for Electron) --- public registerServiceWorker(): void {} public get isPWAEnabled(): boolean { return false; } }