mirror of
https://github.com/zadam/trilium.git
synced 2026-01-06 06:34:25 +01:00
feat(layout/right_pane): basic store to read content without blob
This commit is contained in:
parent
98ed442d27
commit
2e484a11e6
33
apps/client/src/widgets/react/NoteStore.ts
Normal file
33
apps/client/src/widgets/react/NoteStore.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
type Listener = () => void;
|
||||||
|
|
||||||
|
class NoteSavedDataStore {
|
||||||
|
private data = new Map<string, string>();
|
||||||
|
private listeners = new Map<string, Set<Listener>>();
|
||||||
|
|
||||||
|
get(noteId: string) {
|
||||||
|
return this.data.get(noteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
set(noteId: string, value: string) {
|
||||||
|
this.data.set(noteId, value);
|
||||||
|
this.listeners.get(noteId)?.forEach(l => l());
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribe(noteId: string, listener: Listener) {
|
||||||
|
let set = this.listeners.get(noteId);
|
||||||
|
if (!set) {
|
||||||
|
set = new Set();
|
||||||
|
this.listeners.set(noteId, set);
|
||||||
|
}
|
||||||
|
set.add(listener);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
set!.delete(listener);
|
||||||
|
if (set!.size === 0) {
|
||||||
|
this.listeners.delete(noteId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const noteSavedDataStore = new NoteSavedDataStore();
|
||||||
@ -2,7 +2,7 @@ import { FilterLabelsByType, KeyboardActionNames, OptionNames, RelationNames } f
|
|||||||
import { Tooltip } from "bootstrap";
|
import { Tooltip } from "bootstrap";
|
||||||
import Mark from "mark.js";
|
import Mark from "mark.js";
|
||||||
import { RefObject, VNode } from "preact";
|
import { RefObject, VNode } from "preact";
|
||||||
import { CSSProperties } from "preact/compat";
|
import { CSSProperties, useSyncExternalStore } from "preact/compat";
|
||||||
import { MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
|
import { MutableRef, useCallback, useContext, useDebugValue, useEffect, useLayoutEffect, useMemo, useRef, useState } from "preact/hooks";
|
||||||
|
|
||||||
import appContext, { EventData, EventNames } from "../../components/app_context";
|
import appContext, { EventData, EventNames } from "../../components/app_context";
|
||||||
@ -25,6 +25,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 { noteSavedDataStore } from "./NoteStore";
|
||||||
import { NoteContextContext, ParentComponent, refToJQuerySelector } from "./react_utils";
|
import { NoteContextContext, ParentComponent, refToJQuerySelector } from "./react_utils";
|
||||||
|
|
||||||
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
|
export function useTriliumEvent<T extends EventNames>(eventName: T, handler: (data: EventData<T>) => void) {
|
||||||
@ -112,6 +113,7 @@ export function useEditorSpacedUpdate({ note, noteContext, getData, onContentCha
|
|||||||
protected_session_holder.touchProtectedSessionIfNecessary(note);
|
protected_session_holder.touchProtectedSessionIfNecessary(note);
|
||||||
await server.put(`notes/${note.noteId}/data`, data, parentComponent?.componentId);
|
await server.put(`notes/${note.noteId}/data`, data, parentComponent?.componentId);
|
||||||
|
|
||||||
|
noteSavedDataStore.set(note.noteId, data.content);
|
||||||
dataSaved?.(data);
|
dataSaved?.(data);
|
||||||
};
|
};
|
||||||
}, [ note, getData, dataSaved ]);
|
}, [ note, getData, dataSaved ]);
|
||||||
@ -120,6 +122,7 @@ export function useEditorSpacedUpdate({ note, noteContext, getData, onContentCha
|
|||||||
// React to note/blob changes.
|
// React to note/blob changes.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!blob) return;
|
if (!blob) return;
|
||||||
|
noteSavedDataStore.set(note.noteId, blob.content);
|
||||||
spacedUpdate.allowUpdateWithoutChange(() => onContentChange(blob.content));
|
spacedUpdate.allowUpdateWithoutChange(() => onContentChange(blob.content));
|
||||||
}, [ blob ]);
|
}, [ blob ]);
|
||||||
|
|
||||||
@ -151,6 +154,14 @@ export function useEditorSpacedUpdate({ note, noteContext, getData, onContentCha
|
|||||||
return spacedUpdate;
|
return spacedUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useNoteSavedData(noteId: string | undefined) {
|
||||||
|
return useSyncExternalStore(
|
||||||
|
(cb) => noteId ? noteSavedDataStore.subscribe(noteId, cb) : () => {},
|
||||||
|
() => noteId ? noteSavedDataStore.get(noteId) : undefined
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows a React component to read and write a Trilium option, while also watching for external changes.
|
* Allows a React component to read and write a Trilium option, while also watching for external changes.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -6,11 +6,13 @@ import { useEffect } from "preact/hooks";
|
|||||||
|
|
||||||
import options from "../../services/options";
|
import options from "../../services/options";
|
||||||
import { DEFAULT_GUTTER_SIZE } from "../../services/resizer";
|
import { DEFAULT_GUTTER_SIZE } from "../../services/resizer";
|
||||||
|
import { useActiveNoteContext } from "../react/hooks";
|
||||||
import TableOfContents from "./TableOfContents";
|
import TableOfContents from "./TableOfContents";
|
||||||
|
|
||||||
const MIN_WIDTH_PERCENT = 5;
|
const MIN_WIDTH_PERCENT = 5;
|
||||||
|
|
||||||
export default function RightPanelContainer() {
|
export default function RightPanelContainer() {
|
||||||
|
const { note } = useActiveNoteContext();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// We are intentionally omitting useTriliumOption to avoid re-render due to size change.
|
// We are intentionally omitting useTriliumOption to avoid re-render due to size change.
|
||||||
const rightPaneWidth = Math.max(MIN_WIDTH_PERCENT, options.getInt("rightPaneWidth") ?? MIN_WIDTH_PERCENT);
|
const rightPaneWidth = Math.max(MIN_WIDTH_PERCENT, options.getInt("rightPaneWidth") ?? MIN_WIDTH_PERCENT);
|
||||||
@ -26,7 +28,9 @@ export default function RightPanelContainer() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="right-pane">
|
<div id="right-pane">
|
||||||
<TableOfContents />
|
{note && <>
|
||||||
|
<TableOfContents note={note} />
|
||||||
|
</>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
|
import FNote from "../../entities/fnote";
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
|
import { useNoteSavedData } from "../react/hooks";
|
||||||
import RightPanelWidget from "./RightPanelWidget";
|
import RightPanelWidget from "./RightPanelWidget";
|
||||||
|
|
||||||
export default function TableOfContents() {
|
export default function TableOfContents({ note }: { note: FNote }) {
|
||||||
|
const content = useNoteSavedData(note.noteId);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RightPanelWidget title={t("toc.table_of_contents")}>
|
<RightPanelWidget title={t("toc.table_of_contents")}>
|
||||||
Toc is here.
|
{content?.length}
|
||||||
</RightPanelWidget>
|
</RightPanelWidget>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user