Uses: npx server to serve nextjs static build
16
README.md
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
---
|
||||
|
||||

|
||||

|
||||
|
||||
## ✨ More Freedom with AI Presentations
|
||||
|
||||
|
|
@ -21,25 +21,25 @@
|
|||
## Features
|
||||
|
||||
### 1. Add prompt, select number of slides and language
|
||||

|
||||

|
||||
|
||||
### 2. Select theme
|
||||

|
||||

|
||||
|
||||
### 3. Review and edit outline
|
||||

|
||||

|
||||
|
||||
### 4. Select theme
|
||||

|
||||

|
||||
|
||||
### 5. Present on app
|
||||

|
||||

|
||||
|
||||
### 6. Change theme
|
||||

|
||||

|
||||
|
||||
### 7. Export presentation as PDF and PPTX
|
||||

|
||||

|
||||
|
||||
|
||||
## License
|
||||
|
|
|
|||
29
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 () => {
|
||||
|
|
|
|||
|
|
@ -48,8 +48,9 @@ export function killProcess(pid: number) {
|
|||
})
|
||||
}
|
||||
|
||||
export async function findUnusedPorts(startPort: number = 40000, count: number = 1): Promise<number[]> {
|
||||
export async function findUnusedPorts(startPort: number = 40000, count: number = 2): Promise<number[]> {
|
||||
const ports: number[] = [];
|
||||
console.log(`Finding ${count} unused ports starting from ${startPort}`);
|
||||
|
||||
const isPortAvailable = (port: number): Promise<boolean> => {
|
||||
return new Promise((resolve) => {
|
||||
|
|
|
|||
|
|
@ -37,4 +37,39 @@ export async function startFastApiServer(
|
|||
// Wait for FastAPI server to start
|
||||
await execAsync(`npx wait-on ${localhost}:${port}/docs`);
|
||||
return fastApiProcess;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
10
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",
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 5.7 MiB After Width: | Height: | Size: 5.7 MiB |
|
Before Width: | Height: | Size: 532 KiB After Width: | Height: | Size: 532 KiB |
|
Before Width: | Height: | Size: 583 KiB After Width: | Height: | Size: 583 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 514 KiB After Width: | Height: | Size: 514 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |