chore(react/type_widget): save SVG attachment

This commit is contained in:
Elian Doran 2025-09-20 14:00:58 +03:00
parent 02017ebd9d
commit bde7b753a0
No known key found for this signature in database
4 changed files with 26 additions and 13 deletions

View File

@ -27,6 +27,7 @@ export default function Mermaid(props: TypeWidgetProps) {
return (
<SvgSplitEditor
attachmentName="mermaid-export"
renderSvg={renderSvg}
{...props}
/>

View File

@ -17,7 +17,10 @@ export interface EditableCodeProps extends TypeWidgetProps {
debounceUpdate?: boolean;
lineWrapping?: boolean;
updateInterval?: number;
/** Invoked when the content of the note is changed, such as a different revision or a note switch. */
onContentChanged?: (content: string) => void;
/** Invoked after the content of the note has been uploaded to the server, using a spaced update. */
dataSaved?: () => void;
}
export function ReadOnlyCode({ note, viewScope, ntxId, parentComponent }: TypeWidgetProps) {
@ -43,7 +46,7 @@ export function ReadOnlyCode({ note, viewScope, ntxId, parentComponent }: TypeWi
)
}
export function EditableCode({ note, ntxId, debounceUpdate, parentComponent, updateInterval, onContentChanged, ...editorProps }: EditableCodeProps) {
export function EditableCode({ note, ntxId, debounceUpdate, parentComponent, updateInterval, onContentChanged, dataSaved, ...editorProps }: EditableCodeProps) {
const editorRef = useRef<VanillaCodeMirror>(null);
const containerRef = useRef<HTMLPreElement>(null);
const [ vimKeymapEnabled ] = useTriliumOptionBool("vimKeymapEnabled");
@ -57,6 +60,7 @@ export function EditableCode({ note, ntxId, debounceUpdate, parentComponent, upd
codeEditor.setMimeType(note.mime);
codeEditor.clearHistory();
},
dataSaved,
updateInterval
});

View File

@ -2,8 +2,13 @@ import { useState } from "preact/hooks";
import { t } from "../../../services/i18n";
import SplitEditor, { PreviewButton, SplitEditorProps } from "./SplitEditor";
import { RawHtmlBlock } from "../../react/RawHtml";
import server from "../../../services/server";
interface SvgSplitEditorProps extends Omit<SplitEditorProps, "previewContent"> {
/**
* The name of the note attachment (without .svg extension) that will be used for storing the preview.
*/
attachmentName: string;
/**
* Called upon when the SVG preview needs refreshing, such as when the editor has switched to a new note or the content has switched.
*
@ -14,7 +19,7 @@ interface SvgSplitEditorProps extends Omit<SplitEditorProps, "previewContent"> {
renderSvg(content: string): string | Promise<string>;
}
export default function SvgSplitEditor({ renderSvg, ...props }: SvgSplitEditorProps) {
export default function SvgSplitEditor({ note, attachmentName, renderSvg, ...props }: SvgSplitEditorProps) {
const [ svg, setSvg ] = useState<string>();
const [ error, setError ] = useState<string | null | undefined>();
@ -31,10 +36,24 @@ export default function SvgSplitEditor({ renderSvg, ...props }: SvgSplitEditorPr
}
}
function onSave() {
const payload = {
role: "image",
title: `${attachmentName}.svg`,
mime: "image/svg+xml",
content: svg,
position: 0
};
server.post(`notes/${note.noteId}/attachments?matchBy=title`, payload);
}
return (
<SplitEditor
note={note}
error={error}
onContentChanged={onContentChanged}
dataSaved={onSave}
previewContent={(
<RawHtmlBlock className="render-container" html={svg} />
)}

View File

@ -95,15 +95,7 @@ export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTy
}
#saveSvg() {
const payload = {
role: "image",
title: `${this.attachmentName}.svg`,
mime: "image/svg+xml",
content: this.svg,
position: 0
};
server.post(`notes/${this.noteId}/attachments?matchBy=title`, payload);
}
cleanup(): void {
@ -112,9 +104,6 @@ export default abstract class AbstractSvgSplitTypeWidget extends AbstractSplitTy
super.cleanup();
}
/**
* Called to obtain the name of the note attachment (without .svg extension) that will be used for storing the preview.
*/
abstract get attachmentName(): string;
/**