fix(toc): not working on note switch

This commit is contained in:
Elian Doran 2025-12-18 10:08:10 +02:00
parent 97a3e439d2
commit 60342c0f6f
No known key found for this signature in database
2 changed files with 35 additions and 10 deletions

View File

@ -1,3 +1,4 @@
import { CKTextEditor } from "@triliumnext/ckeditor5";
import { FilterLabelsByType, KeyboardActionNames, OptionNames, RelationNames } from "@triliumnext/commons"; import { FilterLabelsByType, KeyboardActionNames, OptionNames, RelationNames } from "@triliumnext/commons";
import { Tooltip } from "bootstrap"; import { Tooltip } from "bootstrap";
import Mark from "mark.js"; import Mark from "mark.js";
@ -25,6 +26,7 @@ import utils, { escapeRegExp, randomString, reloadFrontendApp } from "../../serv
import BasicWidget, { ReactWrappedWidget } from "../basic_widget"; import BasicWidget, { ReactWrappedWidget } from "../basic_widget";
import NoteContextAwareWidget from "../note_context_aware_widget"; import NoteContextAwareWidget from "../note_context_aware_widget";
import { DragData } from "../note_tree"; import { DragData } from "../note_tree";
import CKEditor from "./CKEditor";
import { noteSavedDataStore } from "./NoteStore"; import { noteSavedDataStore } from "./NoteStore";
import { NoteContextContext, ParentComponent, refToJQuerySelector } from "./react_utils"; import { NoteContextContext, ParentComponent, refToJQuerySelector } from "./react_utils";
@ -1085,3 +1087,31 @@ export function useNoteColorClass(note: FNote | null | undefined) {
}, [ color, note ]); }, [ color, note ]);
return colorClass; return colorClass;
} }
export function useTextEditor(noteContext: NoteContext | null | undefined) {
const [ textEditor, setTextEditor ] = useState<CKTextEditor | null>(null);
const requestIdRef = useRef(0);
// React to note context change and initial state.
useEffect(() => {
if (!noteContext) {
setTextEditor(null);
return;
}
const requestId = ++requestIdRef.current;
noteContext.getTextEditor((textEditor) => {
// Prevent stale async.
if (requestId !== requestIdRef.current) return;
setTextEditor(textEditor);
});
}, [ noteContext ]);
// React to editor initializing.
useTriliumEvent("textEditorRefreshed", ({ ntxId: eventNtxId, editor }) => {
if (eventNtxId !== noteContext?.ntxId) return;
setTextEditor(editor);
});
return textEditor;
}

View File

@ -2,7 +2,7 @@ import { CKTextEditor, ModelElement } from "@triliumnext/ckeditor5";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { t } from "../../services/i18n"; import { t } from "../../services/i18n";
import { useActiveNoteContext, useIsNoteReadOnly, useNoteProperty, useTriliumEvent } from "../react/hooks"; import { useActiveNoteContext, useIsNoteReadOnly, useNoteProperty, useTextEditor, useTriliumEvent } from "../react/hooks";
import RightPanelWidget from "./RightPanelWidget"; import RightPanelWidget from "./RightPanelWidget";
interface CKHeading { interface CKHeading {
@ -24,18 +24,13 @@ export default function TableOfContents() {
} }
function EditableTextTableOfContents() { function EditableTextTableOfContents() {
const { ntxId } = useActiveNoteContext(); const { note, noteContext } = useActiveNoteContext();
const [ textEditor, setTextEditor ] = useState<CKTextEditor | null>(null); const textEditor = useTextEditor(noteContext);
const [ headings, setHeadings ] = useState<CKHeading[]>([]); const [ headings, setHeadings ] = useState<CKHeading[]>([]);
useTriliumEvent("textEditorRefreshed", ({ ntxId: eventNtxId, editor }) => {
if (eventNtxId !== ntxId) return;
setTextEditor(editor);
});
useEffect(() => { useEffect(() => {
if (!textEditor) return; if (!textEditor) return;
const headings = extractTocFromTextEditor(textEditor); const headings = extractTocFromTextEditor(textEditor);
// React to changes. // React to changes.
const changeCallback = () => { const changeCallback = () => {
@ -55,7 +50,7 @@ function EditableTextTableOfContents() {
setHeadings(headings); setHeadings(headings);
return () => textEditor.model.document.off("change:data", changeCallback); return () => textEditor.model.document.off("change:data", changeCallback);
}, [ textEditor ]); }, [ textEditor, note ]);
return <AbstractTableOfContents headings={headings} />; return <AbstractTableOfContents headings={headings} />;
} }