presenton/electron/app/main.ts
2026-02-20 12:02:23 +05:45

151 lines
5.6 KiB
TypeScript

require("dotenv").config();
import { app, BrowserWindow } from "electron";
import path from "path";
import { findUnusedPorts, killProcess, setupEnv, setUserConfig } from "./utils";
import { startFastApiServer, startNextJsServer } from "./utils/servers";
import { ChildProcessByStdio } from "child_process";
import { appDataDir, baseDir, ensureDirectoriesExist, fastapiDir, isDev, localhost, nextjsDir, tempDir, userConfigPath, userDataDir } from "./utils/constants";
import { setupIpcHandlers } from "./ipc";
var win: BrowserWindow | undefined;
var fastApiProcess: ChildProcessByStdio<any, any, any> | undefined;
var nextjsProcess: any;
app.commandLine.appendSwitch('gtk-version', '3');
const createWindow = () => {
win = new BrowserWindow({
width: 1280,
height: 720,
icon: path.join(baseDir, "resources/ui/assets/images/presenton_short_filled.png"),
webPreferences: {
webSecurity: false,
preload: path.join(__dirname, 'preloads/index.js'),
},
});
};
async function startServers(fastApiPort: number, nextjsPort: number) {
try {
fastApiProcess = await startFastApiServer(
fastapiDir,
fastApiPort,
{
DEBUG: isDev ? "True" : "False",
CAN_CHANGE_KEYS: process.env.CAN_CHANGE_KEYS,
LLM: process.env.LLM,
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
OPENAI_MODEL: process.env.OPENAI_MODEL,
GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,
GOOGLE_MODEL: process.env.GOOGLE_MODEL,
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
ANTHROPIC_MODEL: process.env.ANTHROPIC_MODEL,
OLLAMA_URL: process.env.OLLAMA_URL,
OLLAMA_MODEL: process.env.OLLAMA_MODEL,
CUSTOM_LLM_URL: process.env.CUSTOM_LLM_URL,
CUSTOM_LLM_API_KEY: process.env.CUSTOM_LLM_API_KEY,
CUSTOM_MODEL: process.env.CUSTOM_MODEL,
PEXELS_API_KEY: process.env.PEXELS_API_KEY,
PIXABAY_API_KEY: process.env.PIXABAY_API_KEY,
IMAGE_PROVIDER: process.env.IMAGE_PROVIDER,
DISABLE_IMAGE_GENERATION: process.env.DISABLE_IMAGE_GENERATION,
EXTENDED_REASONING: process.env.EXTENDED_REASONING,
TOOL_CALLS: process.env.TOOL_CALLS,
DISABLE_THINKING: process.env.DISABLE_THINKING,
WEB_GROUNDING: process.env.WEB_GROUNDING,
DATABASE_URL: process.env.DATABASE_URL,
DISABLE_ANONYMOUS_TRACKING: process.env.DISABLE_ANONYMOUS_TRACKING,
COMFYUI_URL: process.env.COMFYUI_URL,
COMFYUI_WORKFLOW: process.env.COMFYUI_WORKFLOW,
DALL_E_3_QUALITY: process.env.DALL_E_3_QUALITY,
GPT_IMAGE_1_5_QUALITY: process.env.GPT_IMAGE_1_5_QUALITY,
APP_DATA_DIRECTORY: appDataDir,
TEMP_DIRECTORY: tempDir,
USER_CONFIG_PATH: userConfigPath,
},
isDev,
);
nextjsProcess = await startNextJsServer(
nextjsDir,
nextjsPort,
{
NEXT_PUBLIC_FAST_API: process.env.NEXT_PUBLIC_FAST_API,
TEMP_DIRECTORY: process.env.TEMP_DIRECTORY,
NEXT_PUBLIC_URL: process.env.NEXT_PUBLIC_URL,
NEXT_PUBLIC_USER_CONFIG_PATH: process.env.NEXT_PUBLIC_USER_CONFIG_PATH,
USER_CONFIG_PATH: process.env.NEXT_PUBLIC_USER_CONFIG_PATH,
APP_DATA_DIRECTORY: appDataDir,
},
isDev,
)
} catch (error) {
console.error("Server startup error:", error);
}
}
async function stopServers() {
if (fastApiProcess?.pid) {
await killProcess(fastApiProcess.pid);
}
if (nextjsProcess) {
if (isDev) {
await killProcess(nextjsProcess.pid);
} else {
nextjsProcess.close();
}
}
}
app.whenReady().then(async () => {
// Ensure all required directories exist before starting
ensureDirectoriesExist();
createWindow();
win?.loadFile(path.join(baseDir, "resources/ui/homepage/index.html"));
setUserConfig({
CAN_CHANGE_KEYS: process.env.CAN_CHANGE_KEYS,
LLM: process.env.LLM,
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
OPENAI_MODEL: process.env.OPENAI_MODEL,
GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,
GOOGLE_MODEL: process.env.GOOGLE_MODEL,
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
ANTHROPIC_MODEL: process.env.ANTHROPIC_MODEL,
OLLAMA_URL: process.env.OLLAMA_URL,
OLLAMA_MODEL: process.env.OLLAMA_MODEL,
CUSTOM_LLM_URL: process.env.CUSTOM_LLM_URL,
CUSTOM_LLM_API_KEY: process.env.CUSTOM_LLM_API_KEY,
CUSTOM_MODEL: process.env.CUSTOM_MODEL,
PEXELS_API_KEY: process.env.PEXELS_API_KEY,
PIXABAY_API_KEY: process.env.PIXABAY_API_KEY,
IMAGE_PROVIDER: process.env.IMAGE_PROVIDER,
DISABLE_IMAGE_GENERATION: process.env.DISABLE_IMAGE_GENERATION,
EXTENDED_REASONING: process.env.EXTENDED_REASONING,
TOOL_CALLS: process.env.TOOL_CALLS,
DISABLE_THINKING: process.env.DISABLE_THINKING,
WEB_GROUNDING: process.env.WEB_GROUNDING,
DATABASE_URL: process.env.DATABASE_URL,
DISABLE_ANONYMOUS_TRACKING: process.env.DISABLE_ANONYMOUS_TRACKING,
COMFYUI_URL: process.env.COMFYUI_URL,
COMFYUI_WORKFLOW: process.env.COMFYUI_WORKFLOW,
DALL_E_3_QUALITY: process.env.DALL_E_3_QUALITY,
GPT_IMAGE_1_5_QUALITY: process.env.GPT_IMAGE_1_5_QUALITY,
})
const [fastApiPort, nextjsPort] = await findUnusedPorts();
console.log(`FastAPI port: ${fastApiPort}, NextJS port: ${nextjsPort}`);
//? Setup environment variables to be used in the preloads
setupEnv(fastApiPort, nextjsPort);
setupIpcHandlers();
await startServers(fastApiPort, nextjsPort);
win?.loadURL(`${localhost}:${nextjsPort}`);
});
app.on("window-all-closed", async () => {
await stopServers();
app.quit();
});