mirror of
https://github.com/zadam/trilium.git
synced 2026-05-06 09:36:37 +02:00
feat(print/pdf): add toggle for landscape
This commit is contained in:
@@ -2308,7 +2308,8 @@
|
||||
"print_preview": {
|
||||
"title": "Print preview",
|
||||
"close": "Close",
|
||||
"save": "Save as PDF"
|
||||
"save": "Save as PDF",
|
||||
"landscape": "Landscape"
|
||||
},
|
||||
"pdf": {
|
||||
"attachments_one": "{{count}} attachment",
|
||||
|
||||
@@ -147,9 +147,9 @@ export default function NoteDetail() {
|
||||
toast.closePersistent("printing");
|
||||
handlePrintReport(printReport);
|
||||
};
|
||||
const onPreviewResult = (_e: any, { buffer, title }: { buffer: Uint8Array; title: string }) => {
|
||||
const onPreviewResult = (_e: any, { buffer, title, notePath, pageSize, landscape }: { buffer: Uint8Array; title: string; notePath: string; pageSize: string; landscape: boolean }) => {
|
||||
toast.closePersistent("printing");
|
||||
appContext.triggerCommand("showPrintPreview", { pdfBuffer: buffer, title });
|
||||
appContext.triggerCommand("showPrintPreview", { pdfBuffer: buffer, title, notePath, pageSize, landscape });
|
||||
};
|
||||
ipcRenderer.on("print-progress", onPrintProgress);
|
||||
ipcRenderer.on("print-done", onPrintDone);
|
||||
|
||||
@@ -1,29 +1,52 @@
|
||||
import { useRef, useState } from "preact/hooks";
|
||||
import Modal from "../react/Modal";
|
||||
import PdfViewer from "../type_widgets/file/PdfViewer";
|
||||
import { useCallback, useRef, useState } from "preact/hooks";
|
||||
|
||||
import { t } from "../../services/i18n";
|
||||
import toast from "../../services/toast";
|
||||
import { dynamicRequire, isElectron } from "../../services/utils";
|
||||
import Button from "../react/Button";
|
||||
import { useTriliumEvent } from "../react/hooks";
|
||||
import { t } from "../../services/i18n";
|
||||
import { dynamicRequire } from "../../services/utils";
|
||||
import Modal from "../react/Modal";
|
||||
import PdfViewer from "../type_widgets/file/PdfViewer";
|
||||
import { OptionsRowWithToggle } from "../type_widgets/options/components/OptionsRow";
|
||||
import OptionsSection from "../type_widgets/options/components/OptionsSection";
|
||||
|
||||
export interface PrintPreviewData {
|
||||
pdfBuffer: Uint8Array;
|
||||
title: string;
|
||||
notePath: string;
|
||||
pageSize: string;
|
||||
landscape: boolean;
|
||||
}
|
||||
|
||||
export default function PrintPreviewDialog() {
|
||||
const [shown, setShown] = useState(false);
|
||||
const [pdfUrl, setPdfUrl] = useState<string>();
|
||||
const [landscape, setLandscape] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const bufferRef = useRef<Uint8Array>();
|
||||
const titleRef = useRef("");
|
||||
const notePathRef = useRef("");
|
||||
const pageSizeRef = useRef("");
|
||||
|
||||
const updatePreview = useCallback((buffer: Uint8Array) => {
|
||||
bufferRef.current = buffer;
|
||||
|
||||
// Revoke old URL before creating new one.
|
||||
if (pdfUrl) {
|
||||
URL.revokeObjectURL(pdfUrl);
|
||||
}
|
||||
|
||||
const blob = new Blob([buffer as BlobPart], { type: "application/pdf" });
|
||||
setPdfUrl(URL.createObjectURL(blob));
|
||||
setLoading(false);
|
||||
}, [pdfUrl]);
|
||||
|
||||
useTriliumEvent("showPrintPreview", (data: PrintPreviewData) => {
|
||||
bufferRef.current = data.pdfBuffer;
|
||||
titleRef.current = data.title;
|
||||
|
||||
const blob = new Blob([data.pdfBuffer as BlobPart], { type: "application/pdf" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
setPdfUrl(url);
|
||||
notePathRef.current = data.notePath;
|
||||
pageSizeRef.current = data.pageSize;
|
||||
setLandscape(data.landscape);
|
||||
updatePreview(data.pdfBuffer);
|
||||
setShown(true);
|
||||
});
|
||||
|
||||
@@ -34,6 +57,7 @@ export default function PrintPreviewDialog() {
|
||||
setPdfUrl(undefined);
|
||||
}
|
||||
bufferRef.current = undefined;
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
function handleSave() {
|
||||
@@ -47,6 +71,32 @@ export default function PrintPreviewDialog() {
|
||||
handleClose();
|
||||
}
|
||||
|
||||
function handleLandscapeToggle(newValue: boolean) {
|
||||
setLandscape(newValue);
|
||||
regeneratePreview(newValue);
|
||||
}
|
||||
|
||||
function regeneratePreview(newLandscape: boolean) {
|
||||
if (!isElectron()) return;
|
||||
|
||||
setLoading(true);
|
||||
const { ipcRenderer } = dynamicRequire("electron");
|
||||
|
||||
// Listen for the result once.
|
||||
const onResult = (_e: any, { buffer }: { buffer: Uint8Array }) => {
|
||||
toast.closePersistent("printing");
|
||||
updatePreview(buffer);
|
||||
};
|
||||
ipcRenderer.once("export-as-pdf-preview-result", onResult);
|
||||
|
||||
ipcRenderer.send("export-as-pdf-preview", {
|
||||
title: titleRef.current,
|
||||
notePath: notePathRef.current,
|
||||
pageSize: pageSizeRef.current,
|
||||
landscape: newLandscape
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
className="print-preview-dialog"
|
||||
@@ -54,15 +104,34 @@ export default function PrintPreviewDialog() {
|
||||
size="xl"
|
||||
show={shown}
|
||||
onHidden={handleClose}
|
||||
bodyStyle={{ height: "80vh", padding: 0 }}
|
||||
bodyStyle={{ height: "78vh", padding: 0, display: "flex" }}
|
||||
footer={
|
||||
<>
|
||||
<Button text={t("print_preview.close")} onClick={handleClose} />
|
||||
<Button text={t("print_preview.save")} className="btn-primary" onClick={handleSave} />
|
||||
<Button text={t("print_preview.save")} className="btn-primary" onClick={handleSave} disabled={loading} />
|
||||
</>
|
||||
}
|
||||
>
|
||||
{pdfUrl && <PdfViewer pdfUrl={pdfUrl} />}
|
||||
<div style={{ padding: "16px", minWidth: "250px", overflowY: "auto" }}>
|
||||
<OptionsSection>
|
||||
<OptionsRowWithToggle
|
||||
name="printLandscape"
|
||||
label={t("print_preview.landscape")}
|
||||
currentValue={landscape}
|
||||
onChange={handleLandscapeToggle}
|
||||
disabled={loading}
|
||||
/>
|
||||
</OptionsSection>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: 1, position: "relative" }}>
|
||||
{loading && (
|
||||
<div style={{ position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", zIndex: 1, backgroundColor: "var(--modal-bg-color, rgba(255,255,255,0.8))" }}>
|
||||
<span class="bx bx-loader-circle bx-spin" style={{ fontSize: "2rem" }} />
|
||||
</div>
|
||||
)}
|
||||
{pdfUrl && <PdfViewer pdfUrl={pdfUrl} />}
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ electron.ipcMain.on("export-as-pdf-preview", async (e, { title, notePath, landsc
|
||||
`
|
||||
});
|
||||
|
||||
e.sender.send("export-as-pdf-preview-result", { buffer, title });
|
||||
e.sender.send("export-as-pdf-preview-result", { buffer, title, notePath, pageSize, landscape });
|
||||
} catch (_e) {
|
||||
electron.dialog.showErrorBox(t("pdf.unable-to-export-title"), t("pdf.unable-to-export-message"));
|
||||
} finally {
|
||||
|
||||
Reference in New Issue
Block a user