feat(right_pane): store expansion state

This commit is contained in:
Elian Doran 2025-12-18 16:29:35 +02:00
parent a4024d17ba
commit ddb6b3ea8a
No known key found for this signature in database
7 changed files with 26 additions and 14 deletions

View File

@ -24,7 +24,7 @@ export default function HighlightsList() {
const { isReadOnly } = useIsNoteReadOnly(note, noteContext); const { isReadOnly } = useIsNoteReadOnly(note, noteContext);
return ( return (
<RightPanelWidget title={t("highlights_list_2.title")}> <RightPanelWidget id="highlights" title={t("highlights_list_2.title")}>
{((noteType === "text" && isReadOnly) || (noteType === "doc")) && <ReadOnlyTextHighlightsList />} {((noteType === "text" && isReadOnly) || (noteType === "doc")) && <ReadOnlyTextHighlightsList />}
{noteType === "text" && !isReadOnly && <EditableTextHighlightsList />} {noteType === "text" && !isReadOnly && <EditableTextHighlightsList />}
</RightPanelWidget> </RightPanelWidget>

View File

@ -28,16 +28,10 @@ export default function RightPanelContainer() {
return () => splitInstance.destroy(); return () => splitInstance.destroy();
}, []); }, []);
const items = [
<TableOfContents />,
<HighlightsList />
];
const sizesBeforeCollapse = useRef(new WeakMap<HTMLElement, number>());
return ( return (
<div id="right-pane"> <div id="right-pane">
{items} <TableOfContents />
<HighlightsList />
</div> </div>
); );
} }

View File

@ -2,17 +2,20 @@ import clsx from "clsx";
import { ComponentChildren } from "preact"; import { ComponentChildren } from "preact";
import { useContext, useRef, useState } from "preact/hooks"; import { useContext, useRef, useState } from "preact/hooks";
import { useTriliumOptionJson } from "../react/hooks";
import Icon from "../react/Icon"; import Icon from "../react/Icon";
import { ParentComponent } from "../react/react_utils"; import { ParentComponent } from "../react/react_utils";
interface RightPanelWidgetProps { interface RightPanelWidgetProps {
id: string;
title: string; title: string;
children: ComponentChildren; children: ComponentChildren;
buttons?: ComponentChildren; buttons?: ComponentChildren;
} }
export default function RightPanelWidget({ title, buttons, children }: RightPanelWidgetProps) { export default function RightPanelWidget({ id, title, buttons, children }: RightPanelWidgetProps) {
const [ expanded, setExpanded ] = useState(true); const [ rightPaneCollapsedItems, setRightPaneCollapsedItems ] = useTriliumOptionJson<string[]>("rightPaneCollapsedItems");
const [ expanded, setExpanded ] = useState(!rightPaneCollapsedItems.includes(id));
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const parentComponent = useContext(ParentComponent); const parentComponent = useContext(ParentComponent);
@ -27,7 +30,19 @@ export default function RightPanelWidget({ title, buttons, children }: RightPane
> >
<div <div
class="card-header" class="card-header"
onClick={() => setExpanded(!expanded)} onClick={() => {
const newExpanded = !expanded;
setExpanded(newExpanded);
const rightPaneCollapsedItemsSet = new Set(rightPaneCollapsedItems);
if (newExpanded) {
rightPaneCollapsedItemsSet.delete(id);
} else {
rightPaneCollapsedItemsSet.add(id);
}
if (rightPaneCollapsedItemsSet.size !== rightPaneCollapsedItems.length) {
setRightPaneCollapsedItems(Array.from(rightPaneCollapsedItemsSet));
}
}}
> >
<Icon <Icon
icon="bx bx-chevron-down" icon="bx bx-chevron-down"

View File

@ -26,7 +26,7 @@ export default function TableOfContents() {
const { isReadOnly } = useIsNoteReadOnly(note, noteContext); const { isReadOnly } = useIsNoteReadOnly(note, noteContext);
return ( return (
<RightPanelWidget title={t("toc.table_of_contents")}> <RightPanelWidget id="toc" title={t("toc.table_of_contents")}>
{((noteType === "text" && isReadOnly) || (noteType === "doc")) && <ReadOnlyTextTableOfContents />} {((noteType === "text" && isReadOnly) || (noteType === "doc")) && <ReadOnlyTextTableOfContents />}
{noteType === "text" && !isReadOnly && <EditableTextTableOfContents />} {noteType === "text" && !isReadOnly && <EditableTextTableOfContents />}
</RightPanelWidget> </RightPanelWidget>

View File

@ -51,8 +51,9 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
"imageMaxWidthHeight", "imageMaxWidthHeight",
"imageJpegQuality", "imageJpegQuality",
"leftPaneWidth", "leftPaneWidth",
"rightPaneWidth",
"leftPaneVisible", "leftPaneVisible",
"rightPaneWidth",
"rightPaneCollapsedItems",
"rightPaneVisible", "rightPaneVisible",
"nativeTitleBarVisible", "nativeTitleBarVisible",
"headingStyle", "headingStyle",

View File

@ -105,6 +105,7 @@ const defaultOptions: DefaultOption[] = [
{ name: "leftPaneVisible", value: "true", isSynced: false }, { name: "leftPaneVisible", value: "true", isSynced: false },
{ name: "rightPaneWidth", value: "25", isSynced: false }, { name: "rightPaneWidth", value: "25", isSynced: false },
{ name: "rightPaneVisible", value: "true", isSynced: false }, { name: "rightPaneVisible", value: "true", isSynced: false },
{ name: "rightPaneCollapsedItems", value: "[]", isSynced: false },
{ name: "nativeTitleBarVisible", value: "false", isSynced: false }, { name: "nativeTitleBarVisible", value: "false", isSynced: false },
{ name: "eraseEntitiesAfterTimeInSeconds", value: "604800", isSynced: true }, // default is 7 days { name: "eraseEntitiesAfterTimeInSeconds", value: "604800", isSynced: true }, // default is 7 days
{ name: "eraseEntitiesAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day { name: "eraseEntitiesAfterTimeScale", value: "86400", isSynced: true }, // default 86400 seconds = Day

View File

@ -77,6 +77,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
imageJpegQuality: number; imageJpegQuality: number;
leftPaneWidth: number; leftPaneWidth: number;
rightPaneWidth: number; rightPaneWidth: number;
rightPaneCollapsedItems: string;
eraseEntitiesAfterTimeInSeconds: number; eraseEntitiesAfterTimeInSeconds: number;
eraseEntitiesAfterTimeScale: number; eraseEntitiesAfterTimeScale: number;
autoReadonlySizeText: number; autoReadonlySizeText: number;