mirror of
https://github.com/zadam/trilium.git
synced 2025-11-11 08:58:58 +01:00
chore(react/type_widgets): react to snippet changes
This commit is contained in:
parent
3673162a48
commit
a975576214
@ -1,5 +1,5 @@
|
||||
import { HTMLProps, RefObject, useEffect, useImperativeHandle, useRef, useState } from "preact/compat";
|
||||
import { PopupEditor, ClassicEditor, EditorWatchdog, type WatchdogConfig, CKTextEditor } from "@triliumnext/ckeditor5";
|
||||
import { PopupEditor, ClassicEditor, EditorWatchdog, type WatchdogConfig, CKTextEditor, TemplateDefinition } from "@triliumnext/ckeditor5";
|
||||
import { buildConfig, BuildEditorOptions } from "./config";
|
||||
import { useLegacyImperativeHandlers } from "../../react/hooks";
|
||||
import link from "../../../services/link";
|
||||
@ -29,9 +29,10 @@ interface CKEditorWithWatchdogProps extends Pick<HTMLProps<HTMLDivElement>, "cla
|
||||
/** Called upon whenever a new CKEditor instance is initialized, whether it's the first initialization, after a crash or after a config change that requires it (e.g. content language). */
|
||||
onEditorInitialized?: (editor: CKTextEditor) => void;
|
||||
editorApi: RefObject<CKEditorApi>;
|
||||
templates: TemplateDefinition[];
|
||||
}
|
||||
|
||||
export default function CKEditorWithWatchdog({ content, contentLanguage, className, tabIndex, isClassicEditor, watchdogRef: externalWatchdogRef, watchdogConfig, onNotificationWarning, onWatchdogStateChange, onChange, onEditorInitialized, editorApi }: CKEditorWithWatchdogProps) {
|
||||
export default function CKEditorWithWatchdog({ content, contentLanguage, className, tabIndex, isClassicEditor, watchdogRef: externalWatchdogRef, watchdogConfig, onNotificationWarning, onWatchdogStateChange, onChange, onEditorInitialized, editorApi, templates }: CKEditorWithWatchdogProps) {
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const watchdogRef = useRef<EditorWatchdog>(null);
|
||||
const [ editor, setEditor ] = useState<CKTextEditor>();
|
||||
@ -130,7 +131,8 @@ export default function CKEditorWithWatchdog({ content, contentLanguage, classNa
|
||||
const editor = await buildEditor(container, !!isClassicEditor, {
|
||||
forceGplLicense: false,
|
||||
isClassicEditor: !!isClassicEditor,
|
||||
contentLanguage: contentLanguage ?? null
|
||||
contentLanguage: contentLanguage ?? null,
|
||||
templates
|
||||
});
|
||||
|
||||
setEditor(editor);
|
||||
@ -153,7 +155,7 @@ export default function CKEditorWithWatchdog({ content, contentLanguage, classNa
|
||||
watchdog.create(container);
|
||||
|
||||
return () => watchdog.destroy();
|
||||
}, [ contentLanguage ]);
|
||||
}, [ contentLanguage, templates ]);
|
||||
|
||||
// React to content changes.
|
||||
useEffect(() => editor?.setData(content ?? ""), [ editor, content ]);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useRef, useState } from "preact/hooks";
|
||||
import { useEffect, useRef, useState } from "preact/hooks";
|
||||
import dialog from "../../../services/dialog";
|
||||
import toast from "../../../services/toast";
|
||||
import utils, { deferred, isMobile } from "../../../services/utils";
|
||||
@ -6,10 +6,11 @@ import { useEditorSpacedUpdate, useKeyboardShortcuts, useLegacyImperativeHandler
|
||||
import { TypeWidgetProps } from "../type_widget";
|
||||
import CKEditorWithWatchdog, { CKEditorApi } from "./CKEditorWithWatchdog";
|
||||
import "./EditableText.css";
|
||||
import { CKTextEditor, ClassicEditor, EditorWatchdog } from "@triliumnext/ckeditor5";
|
||||
import { CKTextEditor, ClassicEditor, EditorWatchdog, TemplateDefinition } from "@triliumnext/ckeditor5";
|
||||
import Component from "../../../components/component";
|
||||
import options from "../../../services/options";
|
||||
import { loadIncludedNote, refreshIncludedNote } from "./utils";
|
||||
import getTemplates, { updateTemplateCache } from "./snippets.js";
|
||||
|
||||
/**
|
||||
* The editor can operate into two distinct modes:
|
||||
@ -47,7 +48,8 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
onContentChange(newContent) {
|
||||
setContent(newContent);
|
||||
}
|
||||
})
|
||||
});
|
||||
const templates = useTemplates();
|
||||
|
||||
useTriliumEvent("scrollToEnd", () => {
|
||||
const editor = watchdogRef.current?.editor;
|
||||
@ -127,7 +129,7 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
|
||||
return (
|
||||
<div ref={containerRef} class={`note-detail-editable-text note-detail-printable ${codeBlockWordWrap ? "word-wrap" : ""}`}>
|
||||
{note && <CKEditorWithWatchdog
|
||||
{note && !!templates && <CKEditorWithWatchdog
|
||||
className="note-detail-editable-text-editor use-tn-links"
|
||||
tabIndex={300}
|
||||
content={content}
|
||||
@ -143,6 +145,7 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
// A minimum number of milliseconds between saving the editor data internally (defaults to 5000). Note that for large documents, this might impact the editor performance.
|
||||
saveInterval: 5000
|
||||
}}
|
||||
templates={templates}
|
||||
onNotificationWarning={onNotificationWarning}
|
||||
onWatchdogStateChange={onWatchdogStateChange}
|
||||
onChange={() => spacedUpdate.scheduleUpdate()}
|
||||
@ -160,6 +163,25 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext
|
||||
)
|
||||
}
|
||||
|
||||
function useTemplates() {
|
||||
const [ templates, setTemplates ] = useState<TemplateDefinition[]>();
|
||||
|
||||
useEffect(() => {
|
||||
getTemplates().then(setTemplates);
|
||||
}, []);
|
||||
|
||||
useTriliumEvent("entitiesReloaded", async ({ loadResults }) => {
|
||||
console.log("Reloaded ", loadResults);
|
||||
const newTemplates = await updateTemplateCache(loadResults);
|
||||
if (newTemplates) {
|
||||
console.log("Got new templates!", newTemplates);
|
||||
setTemplates(newTemplates);
|
||||
}
|
||||
});
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
function onWatchdogStateChange(watchdog: EditorWatchdog) {
|
||||
const currentState = watchdog.state;
|
||||
logInfo(`CKEditor state changed to ${currentState}`);
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import { ALLOWED_PROTOCOLS } from "../../../services/link.js";
|
||||
import { MIME_TYPE_AUTO } from "@triliumnext/commons";
|
||||
import { buildExtraCommands, type EditorConfig, PREMIUM_PLUGINS } from "@triliumnext/ckeditor5";
|
||||
import { buildExtraCommands, type EditorConfig, PREMIUM_PLUGINS, TemplateDefinition } from "@triliumnext/ckeditor5";
|
||||
import { getHighlightJsNameForMime } from "../../../services/mime_types.js";
|
||||
import options from "../../../services/options.js";
|
||||
import { ensureMimeTypesForHighlighting, isSyntaxHighlightEnabled } from "../../../services/syntax_highlight.js";
|
||||
import emojiDefinitionsUrl from "@triliumnext/ckeditor5/src/emoji_definitions/en.json?url";
|
||||
import { copyTextWithToast } from "../../../services/clipboard_ext.js";
|
||||
import getTemplates from "./snippets.js";
|
||||
import { t } from "../../../services/i18n.js";
|
||||
import { getMermaidConfig } from "../../../services/mermaid.js";
|
||||
import noteAutocompleteService, { type Suggestion } from "../../../services/note_autocomplete.js";
|
||||
@ -20,6 +19,7 @@ export interface BuildEditorOptions {
|
||||
forceGplLicense: boolean;
|
||||
isClassicEditor: boolean;
|
||||
contentLanguage: string | null;
|
||||
templates: TemplateDefinition[];
|
||||
}
|
||||
|
||||
export async function buildConfig(opts: BuildEditorOptions): Promise<EditorConfig> {
|
||||
@ -157,7 +157,7 @@ export async function buildConfig(opts: BuildEditorOptions): Promise<EditorConfi
|
||||
extraCommands: buildExtraCommands()
|
||||
},
|
||||
template: {
|
||||
definitions: await getTemplates()
|
||||
definitions: opts.templates
|
||||
},
|
||||
htmlSupport: {
|
||||
allow: JSON.parse(options.get("allowedHtmlTags"))
|
||||
|
||||
@ -96,18 +96,22 @@ async function handleContentUpdate(affectedNoteIds: string[]) {
|
||||
}
|
||||
}
|
||||
|
||||
export function updateTemplateCache(loadResults: LoadResults): boolean {
|
||||
export async function updateTemplateCache(loadResults: LoadResults): Promise<TemplateDefinition[] | null> {
|
||||
const affectedNoteIds = loadResults.getNoteIds();
|
||||
|
||||
// React to creation or deletion of text snippets.
|
||||
if (loadResults.getAttributeRows().find((attr) =>
|
||||
attr.type === "label" &&
|
||||
(attr.name === "textSnippet" || attr.name === "textSnippetDescription"))) {
|
||||
handleFullReload();
|
||||
if (loadResults.getAttributeRows().find((attr) => {
|
||||
if (attr.type === "label") {
|
||||
return (attr.name === "textSnippet" || attr.name === "textSnippetDescription");
|
||||
} else if (attr.type === "relation") {
|
||||
return (attr.value === "_template_text_snippet");
|
||||
}
|
||||
})) {
|
||||
return await getTemplates();
|
||||
} else if (affectedNoteIds.length > 0) {
|
||||
// Update content and titles if one of the template notes were updated.
|
||||
debouncedHandleContentUpdate(affectedNoteIds);
|
||||
}
|
||||
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -12,7 +12,6 @@ import { buildSelectedBackgroundColor } from "../../components/touch_bar.js";
|
||||
import { buildConfig, BuildEditorOptions, OPEN_SOURCE_LICENSE_KEY } from "./ckeditor/config.js";
|
||||
import type FNote from "../../entities/fnote.js";
|
||||
import { PopupEditor, ClassicEditor, EditorWatchdog, type CKTextEditor, type MentionFeed, type WatchdogConfig, EditorConfig } from "@triliumnext/ckeditor5";
|
||||
import { updateTemplateCache } from "./ckeditor/snippets.js";
|
||||
|
||||
|
||||
export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
@ -54,8 +53,6 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
return this.watchdog?.editor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async executeWithTextEditorEvent({ callback, resolve, ntxId }: EventData<"executeWithTextEditor">) {
|
||||
if (!this.isNoteContext(ntxId)) {
|
||||
return;
|
||||
@ -130,14 +127,6 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
|
||||
await this.reinitialize();
|
||||
}
|
||||
|
||||
async entitiesReloadedEvent(e: EventData<"entitiesReloaded">) {
|
||||
await super.entitiesReloadedEvent(e);
|
||||
|
||||
if (updateTemplateCache(e.loadResults)) {
|
||||
await this.reinitialize();
|
||||
}
|
||||
}
|
||||
|
||||
buildTouchBarCommand(data: CommandListenerData<"buildTouchBar">) {
|
||||
const { TouchBar, buildIcon } = data;
|
||||
const { TouchBarSegmentedControl, TouchBarGroup, TouchBarButton } = TouchBar;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user