Implements: export presentation as pdf using puppeteer
This commit is contained in:
parent
abe4226147
commit
f0fdc8d70c
4 changed files with 75 additions and 42 deletions
|
|
@ -1,34 +1,44 @@
|
|||
import { ipcMain, shell, dialog } from "electron";
|
||||
import { downloadsDir } from "../utils/constants";
|
||||
import { ipcMain, } from "electron";
|
||||
import { baseDir, downloadsDir, isDev } from "../utils/constants";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import puppeteer from "puppeteer";
|
||||
import { showFileDownloadedDialog } from "../utils/dialog";
|
||||
|
||||
export function setupExportHandlers() {
|
||||
ipcMain.handle("file-downloaded", async (_, filePath: string): Promise<IPCStatus> => {
|
||||
try {
|
||||
const fileName = path.basename(filePath);
|
||||
const destinationPath = path.join(downloadsDir, fileName);
|
||||
const fileName = path.basename(filePath);
|
||||
const destinationPath = path.join(downloadsDir, fileName);
|
||||
|
||||
await fs.promises.rename(filePath, destinationPath);
|
||||
|
||||
const { response } = await dialog.showMessageBox({
|
||||
type: 'question',
|
||||
buttons: ['Open File', 'Open Folder', 'Cancel'],
|
||||
defaultId: 0,
|
||||
title: 'File Downloaded',
|
||||
message: 'What would you like to do?'
|
||||
});
|
||||
|
||||
if (response === 0) {
|
||||
await shell.openPath(destinationPath);
|
||||
} else if (response === 1) {
|
||||
await shell.openPath(downloadsDir);
|
||||
}
|
||||
|
||||
return { success: true };
|
||||
} catch (error: any) {
|
||||
console.error('Error handling downloaded file:', error);
|
||||
return { success: false };
|
||||
}
|
||||
await fs.promises.rename(filePath, destinationPath);
|
||||
const success = await showFileDownloadedDialog(destinationPath);
|
||||
return { success };
|
||||
});
|
||||
|
||||
ipcMain.handle("export-as-pdf", async (_, id: string, title: string) => {
|
||||
const ppt_url = `${process.env.NEXT_PUBLIC_FAST_API}/presentation/${id}`;
|
||||
|
||||
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']
|
||||
});
|
||||
|
||||
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 destinationPath = path.join(downloadsDir, `${title}.pdf`);
|
||||
await fs.promises.writeFile(destinationPath, pdfBuffer);
|
||||
|
||||
const success = await showFileDownloadedDialog(destinationPath);
|
||||
|
||||
return { success };
|
||||
})
|
||||
|
||||
}
|
||||
|
|
@ -10,10 +10,11 @@ contextBridge.exposeInMainWorld('env', {
|
|||
|
||||
contextBridge.exposeInMainWorld('electron', {
|
||||
fileDownloaded: (filePath: string) => ipcRenderer.invoke("file-downloaded", filePath),
|
||||
exportAsPDF: (id: string, title: string) => ipcRenderer.invoke("export-as-pdf", id, title),
|
||||
getUserConfig: () => ipcRenderer.invoke("get-user-config"),
|
||||
setUserConfig: (userConfig: UserConfig) => ipcRenderer.invoke("set-user-config", userConfig),
|
||||
readFile: (filePath: string) => ipcRenderer.invoke("read-file", filePath),
|
||||
getSlideMetadata: (url: string, theme: string, customColors?: any, tempDirectory?: string) =>
|
||||
getSlideMetadata: (url: string, theme: string, customColors?: any, tempDirectory?: string) =>
|
||||
ipcRenderer.invoke("get-slide-metadata", url, theme, customColors, tempDirectory),
|
||||
getFooter: (userId: string) => ipcRenderer.invoke("get-footer", userId),
|
||||
setFooter: (userId: string, properties: any) => ipcRenderer.invoke("set-footer", userId, properties),
|
||||
|
|
|
|||
26
app/utils/dialog.ts
Normal file
26
app/utils/dialog.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { shell } from "electron";
|
||||
import { dialog } from "electron";
|
||||
import path from "path";
|
||||
|
||||
export async function showFileDownloadedDialog(filePath: string): Promise<boolean> {
|
||||
try {
|
||||
const { response } = await dialog.showMessageBox({
|
||||
type: 'question',
|
||||
buttons: ['Open File', 'Open Folder', 'Cancel'],
|
||||
defaultId: 0,
|
||||
title: 'File Downloaded',
|
||||
message: 'What would you like to do?'
|
||||
});
|
||||
|
||||
if (response === 0) {
|
||||
await shell.openPath(filePath);
|
||||
} else if (response === 1) {
|
||||
await shell.openPath(path.dirname(filePath));
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (error: any) {
|
||||
console.error('Error handling downloaded file:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -215,26 +215,22 @@ const Header = ({
|
|||
const handleExportPdf = async () => {
|
||||
if (isStreaming) return;
|
||||
|
||||
setOpen(false);
|
||||
try {
|
||||
setOpen(false);
|
||||
setShowLoader(true);
|
||||
const apiBody = await metaData();
|
||||
toast({
|
||||
title: "Exporting presentation...",
|
||||
description: "Please wait while we export your presentation.",
|
||||
variant: "default",
|
||||
});
|
||||
|
||||
const data = await PresentationGenerationApi.exportAsPDF(apiBody);
|
||||
|
||||
if (data.path) {
|
||||
setShowLoader(false);
|
||||
// @ts-ignore
|
||||
const ipcResponse = await window.electron.fileDownloaded(data.path);
|
||||
|
||||
if (!ipcResponse.success) {
|
||||
throw new Error("Failed to download file");
|
||||
}
|
||||
// @ts-ignore
|
||||
const ipcResponse = await window.electron.exportAsPDF(presentation_id, presentationData!.presentation!.title);
|
||||
if (!ipcResponse.success) {
|
||||
throw new Error("Failed to export as PDF");
|
||||
}
|
||||
setShowLoader(false);
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
setShowLoader(false);
|
||||
toast({
|
||||
title: "Having trouble exporting!",
|
||||
description:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue