Completely remove Progressive Web App features including VitePWA plugin, service workers, install prompts, and platform service PWA methods. Delete PWA component, service worker files, help images, and update build configurations. Simplify application architecture by removing PWA complexity while maintaining core functionality.
170 lines
5.8 KiB
TypeScript
170 lines
5.8 KiB
TypeScript
/**
|
|
* @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<void> {
|
|
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 {}
|
|
}
|