pdf export added

This commit is contained in:
shiva raj badu 2025-05-14 01:08:30 +05:45
parent c822c9fb8f
commit 7aeed5f68a
4 changed files with 39 additions and 50 deletions

View file

@ -1,4 +1,4 @@
import { ipcMain, } from "electron";
import { BrowserWindow, ipcMain, } from "electron";
import { baseDir, downloadsDir, isDev } from "../utils/constants";
import fs from "fs";
import path from "path";
@ -16,29 +16,38 @@ export function setupExportHandlers() {
});
ipcMain.handle("export-as-pdf", async (_, id: string, title: string) => {
const ppt_url = `${process.env.NEXT_PUBLIC_FAST_API}/presentation/${id}`;
const ppt_url = `${process.env.NEXT_PUBLIC_URL}/pdf-maker?id=${id}`;
const browser = new BrowserWindow({
width: 1280,
height: 720,
icon: path.join(baseDir, "resources/ui/assets/images/presenton_short_filled.png"),
webPreferences: {
webSecurity: false,
const browser = await puppeteer.launch({
headless: true,
executablePath: isDev ? undefined : path.join(baseDir, "dependencies/chrome-headless-shell/linux_build/chrome-headless-shell"),
args: ['--no-sandbox', '--disable-setuid-sandbox']
preload: path.join(__dirname, '../preloads/index.js'),
},
show: false,
});
browser.loadURL(ppt_url);
browser.webContents.on('did-finish-load', async () => {
await new Promise(async (resolve, reject) => {
setTimeout(async () => {
resolve(true);
}, 5000);
});
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 720 });
await page.goto(ppt_url, { waitUntil: "networkidle0", timeout: 30000 });
const pdfBuffer = await page.pdf({
height: 720,
const pdfBuffer = await browser.webContents.printToPDF({
printBackground: true,
pageSize:{width:1280/96,height:720/96},
margins:{top:0,right:0,bottom:0,left:0}
});
browser.close();
const destinationPath = path.join(downloadsDir, `${title}.pdf`);
await fs.promises.writeFile(destinationPath, pdfBuffer);
const success = await showFileDownloadedDialog(destinationPath);
return { success };
});
const destinationPath = path.join(downloadsDir, `${title}.pdf`);
await fs.promises.writeFile(destinationPath, pdfBuffer);
const success = await showFileDownloadedDialog(destinationPath);
return { success };
return { success: false };
})
}

View file

@ -86,7 +86,7 @@ app.whenReady().then(async () => {
console.log(`FastAPI port: ${fastApiPort}, NextJS port: ${nextjsPort}`);
//? Setup environment variables to be used in the preloads
setupEnv(fastApiPort);
setupEnv(fastApiPort, nextjsPort);
setupIpcHandlers();
await startServers(fastApiPort, nextjsPort);

View file

@ -26,10 +26,11 @@ export function getUserConfig(): UserConfig {
return JSON.parse(configData)
}
export function setupEnv(fastApiPort: number) {
export function setupEnv(fastApiPort: number, nextjsPort: number) {
process.env.NEXT_PUBLIC_FAST_API = `${localhost}:${fastApiPort}`;
process.env.TEMP_DIRECTORY = tempDir;
process.env.NEXT_PUBLIC_USER_CONFIG_PATH = userConfigPath;
process.env.NEXT_PUBLIC_URL = `${localhost}:${nextjsPort}`;
}

View file

@ -7,46 +7,22 @@ import { Skeleton } from "@/components/ui/skeleton";
import { DashboardApi } from "@/app/dashboard/api/dashboard";
import SlideContent from "../presentation/components/SlideContent";
import {
deletePresentationSlide,
setPresentationData,
} from "@/store/slices/presentationGeneration";
import { toast } from "@/hooks/use-toast";
import { Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { AlertCircle } from "lucide-react";
import { setThemeColors, ThemeColors } from "../store/themeSlice";
import { ThemeType } from "../upload/type";
import { PresentationGenerationApi } from "../services/api/presentation-generation";
import { renderSlideContent } from "../components/slide_config";
// Custom debounce function
function useDebounce<T extends (...args: any[]) => void>(
callback: T,
delay: number
) {
const timeoutRef = useRef<NodeJS.Timeout>();
return useCallback(
(...args: Parameters<T>) => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
timeoutRef.current = setTimeout(() => {
callback(...args);
}, delay);
},
[callback, delay]
);
}
const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
@ -107,7 +83,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
const language = presentationData?.presentation?.language || "English";
// Regular view
return (
<div className="h-screen flex overflow-hidden flex-col">
<div className="flex overflow-hidden flex-col">
{error ? (
<div className="flex flex-col items-center justify-center h-screen bg-gray-100">
<div
@ -135,7 +111,7 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
<div style={{
background: currentColors.background,
}} className="flex-1 h-[calc(100vh-100px)] overflow-y-auto">
}} className="">
<div
className="mx-auto flex flex-col items-center overflow-hidden justify-center slide-theme"
data-theme={currentTheme}
@ -161,7 +137,10 @@ const PresentationPage = ({ presentation_id }: { presentation_id: string }) => {
presentationData.slides &&
presentationData.slides.length > 0 &&
presentationData.slides.map((slide, index) => (
renderSlideContent(slide, language)
<div key={index}>
{renderSlideContent(slide, language)}
</div>
))}
</>
)}