diff --git a/README.md b/README.md index 584d59df..ab65791d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ --- -![Demo](resources/readme/demo.gif) +![Demo](readme_assets/demo.gif) ## ✨ More Freedom with AI Presentations @@ -21,25 +21,25 @@ ## Features ### 1. Add prompt, select number of slides and language -![Demo](resources/readme/images/prompting.png) +![Demo](readme_assets/images/prompting.png) ### 2. Select theme -![Demo](resources/readme/images/select-theme.png) +![Demo](readme_assets/images/select-theme.png) ### 3. Review and edit outline -![Demo](resources/readme/images/outline.png) +![Demo](readme_assets/images/outline.png) ### 4. Select theme -![Demo](resources/readme/images/select-theme.png) +![Demo](readme_assets/images/select-theme.png) ### 5. Present on app -![Demo](resources/readme/images/present.png) +![Demo](readme_assets/images/present.png) ### 6. Change theme -![Demo](resources/readme/images/change-theme.png) +![Demo](readme_assets/images/change-theme.png) ### 7. Export presentation as PDF and PPTX -![Demo](resources/readme/images/export-presentation.png) +![Demo](readme_assets/images/export-presentation.png) ## License diff --git a/app/main.ts b/app/main.ts index 0f915502..456b699a 100644 --- a/app/main.ts +++ b/app/main.ts @@ -2,9 +2,9 @@ require("dotenv").config(); import { app, BrowserWindow } from "electron"; import path from "path"; import { findUnusedPorts, killProcess, setupEnv, setUserConfig } from "./utils"; -import { startFastApiServer } from "./utils/servers"; +import { startFastApiServer, startNextJsServer } from "./utils/servers"; import { ChildProcessByStdio } from "child_process"; -import { baseDir, fastapiDir, isDev, tempDir, userConfigPath, userDataDir } from "./utils/constants"; +import { baseDir, fastapiDir, isDev, localhost, nextjsDir, tempDir, userConfigPath, userDataDir } from "./utils/constants"; import { setupIpcHandlers } from "./ipc"; var win: BrowserWindow | undefined; @@ -23,7 +23,7 @@ const createWindow = () => { }); }; -async function startServers(fastApiPort: number) { +async function startServers(fastApiPort: number, nextjsPort: number) { try { fastApiProcess = await startFastApiServer( fastapiDir, @@ -40,6 +40,17 @@ async function startServers(fastApiPort: number) { }, 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, + }, + isDev, + ) } catch (error) { console.error("Server startup error:", error); } @@ -65,17 +76,15 @@ app.whenReady().then(async () => { GOOGLE_API_KEY: process.env.GOOGLE_API_KEY, }) - const [fastApiPort] = await findUnusedPorts(); - console.log(`FastAPI port: ${fastApiPort}`); + const [fastApiPort, nextjsPort] = await findUnusedPorts(); + console.log(`FastAPI port: ${fastApiPort}, NextJS port: ${nextjsPort}`); - //? Setup environment variables to be used in the preload.ts file + //? Setup environment variables to be used in the preloads setupEnv(fastApiPort); setupIpcHandlers(); - await startServers(fastApiPort); - - //? Load the NextJS UI - win?.loadFile(path.join(baseDir, "resources/nextjs/index.html")); + await startServers(fastApiPort, nextjsPort); + win?.loadURL(`${localhost}:${nextjsPort}`); }); app.on("window-all-closed", async () => { diff --git a/app/utils/index.ts b/app/utils/index.ts index 856e7ee7..212fff7a 100644 --- a/app/utils/index.ts +++ b/app/utils/index.ts @@ -48,8 +48,9 @@ export function killProcess(pid: number) { }) } -export async function findUnusedPorts(startPort: number = 40000, count: number = 1): Promise { +export async function findUnusedPorts(startPort: number = 40000, count: number = 2): Promise { const ports: number[] = []; + console.log(`Finding ${count} unused ports starting from ${startPort}`); const isPortAvailable = (port: number): Promise => { return new Promise((resolve) => { diff --git a/app/utils/servers.ts b/app/utils/servers.ts index 8511a07d..e9a3c22f 100644 --- a/app/utils/servers.ts +++ b/app/utils/servers.ts @@ -37,4 +37,39 @@ export async function startFastApiServer( // Wait for FastAPI server to start await execAsync(`npx wait-on ${localhost}:${port}/docs`); return fastApiProcess; -} \ No newline at end of file +} + +export async function startNextJsServer( + directory: string, + port: number, + env: NextJsEnv, + isDev: boolean, +) { + // Start NextJS development server + const startCommand = isDev ? [ + "npm", + ["run", "dev", "--", "-p", port.toString()], + ] : [ + "npx", + ["-y", "serve", "-p", port.toString()], + ]; + + const nextjsProcess = spawn( + startCommand[0] as string, + startCommand[1] as string[], + { + cwd: directory, + stdio: ["inherit", "pipe", "pipe"], + env: { ...process.env, ...env }, + } + ); + nextjsProcess.stdout.on("data", (data: any) => { + console.log(`NextJS: ${data}`); + }); + nextjsProcess.stderr.on("data", (data: any) => { + console.error(`NextJS Error: ${data}`); + }); + // Wait for NextJS server to start + await execAsync(`npx wait-on ${localhost}:${port}`); + return nextjsProcess; +} diff --git a/package.json b/package.json index e6bf7a77..fd944bc9 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,14 @@ "email": "contact@presenton.ai" }, "scripts": { - "dev": "tsc && electron --gtk-version=3 .", + "dev": "rm -rf app_dist && tsc && electron --gtk-version=3 .", "setup:env": "npm install && cd servers/fastapi && poetry install && cd ../../servers/nextjs && npm install", - "build:ts": "tsc", + "build:ts": "rm -rf app_dist && tsc", "build:css": "tailwindcss -i ./resources/ui/assets/css/tailwind.import.css -o ./resources/ui/assets/css/tailwind.css --watch", - "build:nextjs": "rm -rf resources/nextjs && cd servers/nextjs && npm run build && cp -r out ../../.resources/nextjs", + "build:nextjs": "rm -rf resources/nextjs && cd servers/nextjs && npm run build && mv out ../../resources/nextjs", "build:fastapi": "rm -rf resources/fastapi && cd servers/fastapi && .venv/bin/pyinstaller --distpath ../../resources server.spec", - "build:electron": "tsc && node build.js", - "clean:build": "rm -rf resources/nextjs && rm -rf resources/fastapi" + "build:electron": "rm -rf app_dist && tsc && node build.js", + "clean:build": "rm -rf resources/nextjs && rm -rf resources/fastapi && rm -rf app_dist" }, "devDependencies": { "electron": "^36.1.0", diff --git a/resources/readme/demo.gif b/readme_assets/demo.gif similarity index 100% rename from resources/readme/demo.gif rename to readme_assets/demo.gif diff --git a/resources/readme/images/change-theme.png b/readme_assets/images/change-theme.png similarity index 100% rename from resources/readme/images/change-theme.png rename to readme_assets/images/change-theme.png diff --git a/resources/readme/images/export-presentation.png b/readme_assets/images/export-presentation.png similarity index 100% rename from resources/readme/images/export-presentation.png rename to readme_assets/images/export-presentation.png diff --git a/resources/readme/images/outline.png b/readme_assets/images/outline.png similarity index 100% rename from resources/readme/images/outline.png rename to readme_assets/images/outline.png diff --git a/resources/readme/images/present.png b/readme_assets/images/present.png similarity index 100% rename from resources/readme/images/present.png rename to readme_assets/images/present.png diff --git a/resources/readme/images/prompting.png b/readme_assets/images/prompting.png similarity index 100% rename from resources/readme/images/prompting.png rename to readme_assets/images/prompting.png diff --git a/resources/readme/images/select-theme.png b/readme_assets/images/select-theme.png similarity index 100% rename from resources/readme/images/select-theme.png rename to readme_assets/images/select-theme.png