From 094f77b1afc1062f79f927a52638aa8857f1797a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 18 Dec 2025 00:38:40 +0200 Subject: [PATCH] chore(toc): react to changes --- .../src/widgets/sidebar/TableOfContents.tsx | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/apps/client/src/widgets/sidebar/TableOfContents.tsx b/apps/client/src/widgets/sidebar/TableOfContents.tsx index 2fc3db61e..16c4102bf 100644 --- a/apps/client/src/widgets/sidebar/TableOfContents.tsx +++ b/apps/client/src/widgets/sidebar/TableOfContents.tsx @@ -1,9 +1,8 @@ import { CKTextEditor, ModelElement } from "@triliumnext/ckeditor5"; import { useEffect, useState } from "preact/hooks"; -import FNote from "../../entities/fnote"; import { t } from "../../services/i18n"; -import { useActiveNoteContext, useNoteSavedData, useTriliumEvent } from "../react/hooks"; +import { useActiveNoteContext, useTriliumEvent } from "../react/hooks"; import RightPanelWidget from "./RightPanelWidget"; interface CKHeading { @@ -26,10 +25,26 @@ export default function TableOfContents() { useEffect(() => { if (!textEditor) return; const headings = extractTocFromTextEditor(textEditor); - setHeadings(headings); - }, [ textEditor ]); - console.log("Render with ", headings); + // React to changes. + const changeCallback = () => { + const changes = textEditor.model.document.differ.getChanges(); + + const affectsHeadings = changes.some( change => { + return ( + change.type === 'insert' || change.type === 'remove' || (change.type === 'attribute' && change.attributeKey === 'headingLevel') + ); + }); + if (affectsHeadings) { + setHeadings(extractTocFromTextEditor(textEditor)); + } + }; + + textEditor.model.document.on("change:data", changeCallback); + setHeadings(headings); + + return () => textEditor.model.document.off("change:data", changeCallback); + }, [ textEditor ]); return (