mirror of
https://github.com/zadam/trilium.git
synced 2025-11-05 04:45:47 +01:00
chore(react/type_widget): export as SVG/PNG
This commit is contained in:
@@ -5,7 +5,9 @@ import { RawHtmlBlock } from "../../react/RawHtml";
|
|||||||
import server from "../../../services/server";
|
import server from "../../../services/server";
|
||||||
import svgPanZoom, { zoomIn } from "svg-pan-zoom";
|
import svgPanZoom, { zoomIn } from "svg-pan-zoom";
|
||||||
import { RefObject } from "preact";
|
import { RefObject } from "preact";
|
||||||
import { useElementSize } from "../../react/hooks";
|
import { useElementSize, useTriliumEvent } from "../../react/hooks";
|
||||||
|
import utils from "../../../services/utils";
|
||||||
|
import toast from "../../../services/toast";
|
||||||
|
|
||||||
interface SvgSplitEditorProps extends Omit<SplitEditorProps, "previewContent"> {
|
interface SvgSplitEditorProps extends Omit<SplitEditorProps, "previewContent"> {
|
||||||
/**
|
/**
|
||||||
@@ -22,7 +24,18 @@ interface SvgSplitEditorProps extends Omit<SplitEditorProps, "previewContent"> {
|
|||||||
renderSvg(content: string): string | Promise<string>;
|
renderSvg(content: string): string | Promise<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function SvgSplitEditor({ note, attachmentName, renderSvg, ...props }: SvgSplitEditorProps) {
|
/**
|
||||||
|
* A specialization of `SplitTypeWidget` meant for note types that have a SVG preview.
|
||||||
|
*
|
||||||
|
* This adds the following functionality:
|
||||||
|
*
|
||||||
|
* - Automatic handling of the preview when content or the note changes via {@link renderSvg}.
|
||||||
|
* - Built-in pan and zoom functionality with automatic re-centering.
|
||||||
|
* - Automatically displays errors to the user if {@link renderSvg} failed.
|
||||||
|
* - Automatically saves the SVG attachment.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export default function SvgSplitEditor({ ntxId, note, attachmentName, renderSvg, ...props }: SvgSplitEditorProps) {
|
||||||
const [ svg, setSvg ] = useState<string>();
|
const [ svg, setSvg ] = useState<string>();
|
||||||
const [ error, setError ] = useState<string | null | undefined>();
|
const [ error, setError ] = useState<string | null | undefined>();
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@@ -54,13 +67,28 @@ export default function SvgSplitEditor({ note, attachmentName, renderSvg, ...pro
|
|||||||
server.post(`notes/${note.noteId}/attachments?matchBy=title`, payload);
|
server.post(`notes/${note.noteId}/attachments?matchBy=title`, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Import/export
|
||||||
|
useTriliumEvent("exportSvg", ({ ntxId: eventNtxId }) => {
|
||||||
|
if (eventNtxId !== ntxId || !svg) return;
|
||||||
|
utils.downloadSvg(note.title, svg);
|
||||||
|
});
|
||||||
|
useTriliumEvent("exportPng", async ({ ntxId: eventNtxId }) => {
|
||||||
|
if (eventNtxId !== ntxId || !svg) return;
|
||||||
|
try {
|
||||||
|
await utils.downloadSvgAsPng(note.title, svg);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(e);
|
||||||
|
toast.showError(t("svg.export_to_png"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Pan & zoom.
|
// Pan & zoom.
|
||||||
const zoomRef = useResizer(containerRef, note.noteId, svg);
|
const zoomRef = useResizer(containerRef, note.noteId, svg);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SplitEditor
|
<SplitEditor
|
||||||
className="svg-editor"
|
className="svg-editor"
|
||||||
note={note}
|
note={note} ntxId={ntxId}
|
||||||
error={error}
|
error={error}
|
||||||
onContentChanged={onContentChanged}
|
onContentChanged={onContentChanged}
|
||||||
dataSaved={onSave}
|
dataSaved={onSave}
|
||||||
|
|||||||
@@ -7,17 +7,6 @@ import utils from "../../services/utils.js";
|
|||||||
import OnClickButtonWidget from "../buttons/onclick_button.js";
|
import OnClickButtonWidget from "../buttons/onclick_button.js";
|
||||||
import AbstractSplitTypeWidget from "./abstract_split_type_widget.js";
|
import AbstractSplitTypeWidget from "./abstract_split_type_widget.js";
|
||||||
|
|
||||||
/**
|
|
||||||
* A specialization of `SplitTypeWidget` meant for note types that have a SVG preview.
|
|
||||||
*
|
|
||||||
* This adds the following functionality:
|
|
||||||
*
|
|
||||||
* - Automatic handling of the preview when content or the note changes via {@link renderSvg}.
|
|
||||||
* - Built-in pan and zoom functionality with automatic re-centering.
|
|
||||||
* - Automatically displays errors to the user if {@link renderSvg} failed.
|
|
||||||
* - Automatically saves the SVG attachment.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTypeWidget {
|
export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTypeWidget {
|
||||||
|
|
||||||
private $renderContainer!: JQuery<HTMLElement>;
|
private $renderContainer!: JQuery<HTMLElement>;
|
||||||
@@ -47,27 +36,5 @@ export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTy
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
async exportSvgEvent({ ntxId }: EventData<"exportSvg">) {
|
|
||||||
if (!this.isNoteContext(ntxId) || this.note?.type !== "mermaid" || !this.svg) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.downloadSvg(this.note.title, this.svg);
|
|
||||||
}
|
|
||||||
|
|
||||||
async exportPngEvent({ ntxId }: EventData<"exportPng">) {
|
|
||||||
console.log("Export to PNG", this.noteContext?.noteId, ntxId, this.svg);
|
|
||||||
if (!this.isNoteContext(ntxId) || this.note?.type !== "mermaid" || !this.svg) {
|
|
||||||
console.log("Return");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await utils.downloadSvgAsPng(this.note.title, this.svg);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(e);
|
|
||||||
toast.showError(t("svg.export_to_png"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user