backsplash-app
Version:
An AI powered wallpaper app.
182 lines (152 loc) • 6.29 kB
text/typescript
import { app, BrowserWindow } from "electron";
import "./logger"; // Import logger first to ensure configuration runs
// Debug environment variables immediately
console.log("=== MAIN PROCESS ENVIRONMENT DEBUG ===");
console.log(`NODE_ENV: ${process.env.NODE_ENV}`);
console.log(`S3_BUCKET: ${process.env.S3_BUCKET || "NOT SET"}`);
console.log(`S3_REGION: ${process.env.S3_REGION || "NOT SET"}`);
console.log(`Process platform: ${process.platform}`);
console.log(`Process arch: ${process.arch}`);
console.log("=== END ENVIRONMENT DEBUG ===");
// // Single instance protection
// const hasLock = app.requestSingleInstanceLock();
// if (!hasLock) {
// console.log("Another instance is already running. Exiting...");
// app.quit();
// } else {
// app.on("second-instance", () => {
// // Someone tried to run a second instance, we should focus our window instead
// console.log("Second instance detected, focusing existing window");
// // If we have a window, show it
// if (BrowserWindow.getAllWindows().length > 0) {
// const mainWindow = BrowserWindow.getAllWindows()[0];
// if (mainWindow.isMinimized()) mainWindow.restore();
// mainWindow.show();
// mainWindow.focus();
// }
// });
// }
// Conditional Sentry initialization
if (process.env.NODE_ENV === "production" && process.env.SENTRY_DSN) {
import("@sentry/electron/main").then((Sentry) => {
Sentry.init({
dsn: process.env.SENTRY_DSN,
});
});
}
import { SchedulerService } from "@/ipc/services/schedulerService";
import { StoreService } from "@/ipc/services/storeService";
import { WallpaperService } from "@/ipc/services/wallpaperService";
import { FilesystemStorageService } from "@/ipc/services/filesystemStorageService";
import { initializeDownloadHandlers, cleanupDownloadHandlers } from "./ipc/handlers/downloadHandlers";
import { UpdateService, getUpdateService } from "@/ipc/services/updateService";
import { cleanupMenuIpcHandlers } from "./ipc/menuIPC";
import { cleanupLicenseIpcHandlers } from "./ipc/licenseIPC";
import { cleanupWallpaperIpcHandlers } from "./ipc/wallpaperIPC";
import { cleanupStoreIpcHandlers } from "./ipc/storeIPC";
import { cleanupServerIpcHandlers } from "./ipc/serverIPC";
// import installExtension, { REACT_DEVELOPER_TOOLS } from "electron-devtools-installer";
import { createAppWindow, cleanupTray } from "./appWindow";
process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = "true";
// Declare service instances here so they are accessible in event handlers
export let storeServiceInstance: StoreService;
export let filesystemStorageServiceInstance: FilesystemStorageService;
export let wallpaperServiceInstance: WallpaperService;
export let schedulerServiceInstance: SchedulerService;
export let updateServiceInstance: UpdateService;
/** Handle creating/removing shortcuts on Windows when installing/uninstalling. */
// if (require("electron-squirrel-startup")) {
// app.quit();
// }
// Configure app to be a menubar/tray application
if (process.platform === "darwin") {
// This will hide the app from the dock and CMD+TAB
app.dock.hide();
}
// Needed for Linux systems
app.setAppUserModelId("com.backsplash.app");
// Main initialization
app.whenReady().then(() => {
// Global service instances (singletons)
storeServiceInstance = new StoreService();
filesystemStorageServiceInstance = new FilesystemStorageService();
wallpaperServiceInstance = new WallpaperService(storeServiceInstance, filesystemStorageServiceInstance);
// SchedulerService: constructor takes store and wallpaper. It initializes its own IPC listeners.
schedulerServiceInstance = new SchedulerService(storeServiceInstance, wallpaperServiceInstance);
// Initialize the update service
updateServiceInstance = getUpdateService(storeServiceInstance);
updateServiceInstance.initIpcHandlers();
// Start periodic update checks (every 4 hours)
updateServiceInstance.startPeriodicUpdateChecks(240);
// Create the application window once services are initialized
if (BrowserWindow.getAllWindows().length === 0) {
const mainWindow = createAppWindow(wallpaperServiceInstance);
// Initialize download handlers with the main window
initializeDownloadHandlers(mainWindow);
}
// installExtension(REACT_DEVELOPER_TOOLS)
// .then((name) => console.info(`Added Extension: ${name}`))
// .catch((err) => console.info("An error occurred: ", err));
});
/**
* Emitted when the application is activated. Various actions can
* trigger this event, such as launching the application for the first time,
* attempting to re-launch the application when it's already running,
* or clicking on the application's dock or taskbar icon.
*/
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0 && wallpaperServiceInstance) {
createAppWindow(wallpaperServiceInstance);
}
});
/**
* Emitted when all windows have been closed.
*/
app.on("window-all-closed", () => {
// Clean up tray when all windows are closed
cleanupTray();
/**
* On OS X it is common for applications and their menu bar
* to stay active until the user quits explicitly with Cmd + Q
*/
if (process.platform !== "darwin") {
app.quit();
}
});
/**
* Clean up resources when the app is about to quit
*/
app.on("before-quit", () => {
// Clean up UpdateService handlers to prevent duplicate registration on restart
if (updateServiceInstance) {
UpdateService.cleanupHandlers();
}
// Clean up all IPC handlers to prevent duplicate registration on restart
cleanupMenuIpcHandlers();
cleanupLicenseIpcHandlers();
cleanupWallpaperIpcHandlers();
cleanupStoreIpcHandlers();
cleanupServerIpcHandlers();
cleanupDownloadHandlers();
// Clean up tray icon to prevent zombie instances
cleanupTray();
});
/**
* Additional cleanup for development hot reloads
*/
process.on("exit", () => {
try {
UpdateService.cleanupHandlers();
// Clean up all IPC handlers
cleanupMenuIpcHandlers();
cleanupLicenseIpcHandlers();
cleanupWallpaperIpcHandlers();
cleanupStoreIpcHandlers();
cleanupServerIpcHandlers();
cleanupDownloadHandlers();
// Clean up tray icon as well
cleanupTray();
} catch (error) {
// Ignore cleanup errors on exit
}
});