diff --git a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx index f1cb2569b..be87a28be 100644 --- a/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx +++ b/apps/client/src/widgets/type_widgets/text/CKEditorWithWatchdog.tsx @@ -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, "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; + 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(null); const watchdogRef = useRef(null); const [ editor, setEditor ] = useState(); @@ -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 ]); diff --git a/apps/client/src/widgets/type_widgets/text/EditableText.tsx b/apps/client/src/widgets/type_widgets/text/EditableText.tsx index 055285ac3..0a138c963 100644 --- a/apps/client/src/widgets/type_widgets/text/EditableText.tsx +++ b/apps/client/src/widgets/type_widgets/text/EditableText.tsx @@ -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 (
- {note && spacedUpdate.scheduleUpdate()} @@ -160,6 +163,25 @@ export default function EditableText({ note, parentComponent, ntxId, noteContext ) } +function useTemplates() { + const [ templates, setTemplates ] = useState(); + + 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}`); diff --git a/apps/client/src/widgets/type_widgets/text/config.ts b/apps/client/src/widgets/type_widgets/text/config.ts index a923ad92f..05608f459 100644 --- a/apps/client/src/widgets/type_widgets/text/config.ts +++ b/apps/client/src/widgets/type_widgets/text/config.ts @@ -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 { @@ -157,7 +157,7 @@ export async function buildConfig(opts: BuildEditorOptions): Promise { 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; } diff --git a/apps/client/src/widgets/type_widgets_old/editable_text.ts b/apps/client/src/widgets/type_widgets_old/editable_text.ts index 083750132..84760aedb 100644 --- a/apps/client/src/widgets/type_widgets_old/editable_text.ts +++ b/apps/client/src/widgets/type_widgets_old/editable_text.ts @@ -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;