backsplash-app
Version:
An AI powered wallpaper app.
208 lines (182 loc) • 7.55 kB
text/typescript
import { ipcMain, BrowserWindow, shell } from "electron";
import { ServerChannels } from "@/ipc/channels/serverChannels";
import { LicenseService } from "@/ipc/services/licenseService";
import { StoreService } from "@/ipc/services/storeService";
import log from "@/logger";
import { LicenseChannels } from "./channels/licenseChannels";
// Track if handlers have been initialized to prevent duplicates
let licenseHandlersInitialized = false;
/**
* Clean up existing license IPC handlers
*/
export const cleanupLicenseIpcHandlers = () => {
try {
// Remove all license-related handlers
ipcMain.removeHandler(ServerChannels.GET_LICENSE_INFO);
ipcMain.removeHandler(LicenseChannels.VALIDATE_LICENSE);
ipcMain.removeHandler(ServerChannels.CLEAR_LICENSE);
ipcMain.removeHandler(ServerChannels.GET_USAGE_STATS);
ipcMain.removeHandler(ServerChannels.RECORD_WALLPAPER_GENERATION);
ipcMain.removeHandler("license:can-generate");
ipcMain.removeHandler("license:remaining-generations");
ipcMain.removeHandler("license:remaining-style-generations");
ipcMain.removeHandler("license:can-select-more-styles");
ipcMain.removeHandler("license:remaining-style-selections");
ipcMain.removeHandler(LicenseChannels.OPEN_EXTERNAL_URL);
licenseHandlersInitialized = false;
log.info("[License IPC] Cleaned up existing IPC handlers");
} catch (error) {
// Ignore errors if handlers don't exist
log.debug("[License IPC] No existing handlers to clean up");
}
};
export const registerLicenseIpc = (storeService: StoreService) => {
// Prevent duplicate handler registration
if (licenseHandlersInitialized) {
log.warn("[License IPC] Handlers already initialized, skipping registration...");
return;
}
// Clean up any existing handlers first
cleanupLicenseIpcHandlers();
log.info("[License IPC] Registering license handlers...");
const licenseService = new LicenseService(storeService);
// Get license info
ipcMain.handle(ServerChannels.GET_LICENSE_INFO, async () => {
try {
const licenseInfo = licenseService.getLicenseInfo();
log.debug("[License IPC] Retrieved license info:", licenseInfo);
return licenseInfo;
} catch (error) {
log.error("[License IPC] Error getting license info:", error);
throw error;
}
});
// Validate license key
ipcMain.handle(LicenseChannels.VALIDATE_LICENSE, async (_event, licenseKey: string) => {
try {
log.info(`[LicenseIPC] Validating license key: ${licenseKey.substring(0, 8)}...`);
// Use the license service which handles the proper validation flow
const result = await licenseService.validateLicenseKey(licenseKey);
log.info(`[LicenseIPC] License validation result: ${result.isValid ? "valid" : "invalid"}`);
return result;
} catch (error) {
log.error("[LicenseIPC] Error validating license:", error);
throw error;
}
});
// Clear license
ipcMain.handle(ServerChannels.CLEAR_LICENSE, async () => {
try {
log.info("[License IPC] Clearing license");
licenseService.clearLicense();
// Broadcast license cleared to all windows
const windows = BrowserWindow.getAllWindows();
windows.forEach((win) => {
if (!win.isDestroyed() && win.webContents) {
win.webContents.send("license:cleared");
}
});
return { success: true };
} catch (error) {
log.error("[License IPC] Error clearing license:", error);
throw error;
}
});
// Get usage stats
ipcMain.handle(ServerChannels.GET_USAGE_STATS, async () => {
try {
const usageStats = licenseService.getUsageStats();
log.debug("[License IPC] Retrieved usage stats:", usageStats);
return usageStats;
} catch (error) {
log.error("[License IPC] Error getting usage stats:", error);
throw error;
}
});
// Record wallpaper generation
ipcMain.handle(ServerChannels.RECORD_WALLPAPER_GENERATION, async (_event, style: string) => {
try {
log.debug(`[License IPC] Recording wallpaper generation for style: ${style}`);
licenseService.recordWallpaperGeneration(style);
// Broadcast usage stats update to all windows
const windows = BrowserWindow.getAllWindows();
windows.forEach((win) => {
if (!win.isDestroyed() && win.webContents) {
win.webContents.send("usage:updated", licenseService.getUsageStats());
}
});
return true;
} catch (error) {
log.error("[License IPC] Error recording wallpaper generation:", error);
throw error;
}
});
// Additional helper methods for checking generation permissions
ipcMain.handle("license:can-generate", async (_event, style: string) => {
try {
const result = licenseService.canGenerateWallpaper(style);
log.debug(`[License IPC] Can generate ${style}:`, result);
return result;
} catch (error) {
log.error("[License IPC] Error checking generation permission:", error);
throw error;
}
});
// Get remaining free generations
ipcMain.handle("license:remaining-generations", async () => {
try {
const remaining = licenseService.getRemainingFreeGenerations();
log.debug(`[License IPC] Remaining free generations: ${remaining}`);
return remaining;
} catch (error) {
log.error("[License IPC] Error getting remaining generations:", error);
throw error;
}
});
// Get remaining generations for a specific style
ipcMain.handle("license:remaining-style-generations", async (_event, style: string) => {
try {
const remaining = licenseService.getRemainingStyleGenerations(style);
log.debug(`[License IPC] Remaining generations for ${style}: ${remaining}`);
return remaining;
} catch (error) {
log.error("[License IPC] Error getting remaining style generations:", error);
throw error;
}
});
// Check if user can select more styles
ipcMain.handle("license:can-select-more-styles", async (_event, currentSelectionCount: number) => {
try {
const result = licenseService.canSelectMoreStyles(currentSelectionCount);
log.debug(`[License IPC] Can select more styles (current: ${currentSelectionCount}):`, result);
return result;
} catch (error) {
log.error("[License IPC] Error checking style selection permission:", error);
throw error;
}
});
// Get remaining style selections
ipcMain.handle("license:remaining-style-selections", async (_event, currentSelectionCount: number) => {
try {
const remaining = licenseService.getRemainingStyleSelections(currentSelectionCount);
log.debug(`[License IPC] Remaining style selections (current: ${currentSelectionCount}): ${remaining}`);
return remaining;
} catch (error) {
log.error("[License IPC] Error getting remaining style selections:", error);
throw error;
}
});
// Open external URL (for license purchase page)
ipcMain.handle(LicenseChannels.OPEN_EXTERNAL_URL, async (_event, url: string) => {
try {
log.info(`[LicenseIPC] Opening external URL: ${url}`);
await shell.openExternal(url);
return { success: true };
} catch (error) {
log.error(`[LicenseIPC] Failed to open external URL: ${url}`, error);
return { success: false, error: error instanceof Error ? error.message : "Unknown error" };
}
});
licenseHandlersInitialized = true;
log.info("[License IPC] License handlers registered successfully.");
};