diff --git a/apps/client/src/widgets/layout/Breadcrumb.tsx b/apps/client/src/widgets/layout/Breadcrumb.tsx index cc02657e0..fe6d59b26 100644 --- a/apps/client/src/widgets/layout/Breadcrumb.tsx +++ b/apps/client/src/widgets/layout/Breadcrumb.tsx @@ -14,13 +14,13 @@ import NoteLink from "../react/NoteLink"; import link_context_menu from "../../menus/link_context_menu"; import { TitleEditor } from "../collections/board"; import server from "../../services/server"; +import FNote from "../../entities/fnote"; const COLLAPSE_THRESHOLD = 5; const INITIAL_ITEMS = 2; const FINAL_ITEMS = 2; -export default function Breadcrumb() { - const { note, noteContext } = useNoteContext(); +export default function Breadcrumb({ note, noteContext }: { note: FNote, noteContext: NoteContext }) { const notePath = buildNotePaths(noteContext?.notePathArray); return ( diff --git a/apps/client/src/widgets/layout/StatusBar.tsx b/apps/client/src/widgets/layout/StatusBar.tsx index 8dc261864..459761b7b 100644 --- a/apps/client/src/widgets/layout/StatusBar.tsx +++ b/apps/client/src/widgets/layout/StatusBar.tsx @@ -2,6 +2,7 @@ import "./StatusBar.css"; import { Locale } from "@triliumnext/commons"; import clsx from "clsx"; +import { type ComponentChildren } from "preact"; import { createPortal } from "preact/compat"; import { useState } from "preact/hooks"; @@ -11,27 +12,28 @@ import { openInAppHelpFromUrl } from "../../services/utils"; import { formatDateTime } from "../../utils/formatters"; import Dropdown, { DropdownProps } from "../react/Dropdown"; import { FormDropdownDivider, FormListItem } from "../react/FormList"; -import { useNoteContext } from "../react/hooks"; +import { useActiveNoteContext } from "../react/hooks"; import Icon from "../react/Icon"; import { ContentLanguagesModal, useLanguageSwitcher } from "../ribbon/BasicPropertiesTab"; import { NoteSizeWidget, useNoteMetadata } from "../ribbon/NoteInfoTab"; import { useProcessedLocales } from "../type_widgets/options/components/LocaleSelector"; import Breadcrumb from "./Breadcrumb"; - +import NoteContext from "../../components/note_context"; interface StatusBarContext { note: FNote; + noteContext: NoteContext; } export default function StatusBar() { - const { note } = useNoteContext(); - const context = note && { note } satisfies StatusBarContext; + const { note, noteContext } = useActiveNoteContext(); + const context = note && noteContext && { note, noteContext } satisfies StatusBarContext; return (
{context && <>
- +
diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx index 65448eb92..f6f5123f9 100644 --- a/apps/client/src/widgets/react/hooks.tsx +++ b/apps/client/src/widgets/react/hooks.tsx @@ -316,7 +316,7 @@ export function useNoteContext() { useDebugValue(() => `notePath=${notePath}, ntxId=${noteContext?.ntxId}`); return { - note: note, + note, noteId: noteContext?.note?.noteId, notePath: noteContext?.notePath, hoistedNoteId: noteContext?.hoistedNoteId, @@ -327,7 +327,65 @@ export function useNoteContext() { parentComponent, isReadOnlyTemporarilyDisabled }; +} +/** + * Similar to {@link useNoteContext}, but instead of using the note context from the split container that the component is part of, it uses the active note context instead + * (the note currently focused by the user). + */ +export function useActiveNoteContext() { + const [ noteContext, setNoteContext ] = useState(appContext.tabManager.getActiveContext() ?? undefined); + const [ notePath, setNotePath ] = useState(); + const [ note, setNote ] = useState(); + const [ , setViewScope ] = useState(); + const [ isReadOnlyTemporarilyDisabled, setIsReadOnlyTemporarilyDisabled ] = useState(noteContext?.viewScope?.isReadOnly); + const [ refreshCounter, setRefreshCounter ] = useState(0); + + useEffect(() => { + if (!noteContext) { + setNoteContext(appContext.tabManager.getActiveContext() ?? undefined); + } + }, [ noteContext ]); + + useEffect(() => { + setNote(noteContext?.note); + }, [ notePath ]); + + useTriliumEvents([ "setNoteContext", "activeContextChanged", "noteSwitchedAndActivated", "noteSwitched" ], ({}) => { + const noteContext = appContext.tabManager.getActiveContext() ?? undefined; + setNoteContext(noteContext); + setNotePath(noteContext?.notePath); + setViewScope(noteContext?.viewScope); + }); + useTriliumEvent("frocaReloaded", () => { + setNote(noteContext?.note); + }); + useTriliumEvent("noteTypeMimeChanged", ({ noteId }) => { + if (noteId === note?.noteId) { + setRefreshCounter(refreshCounter + 1); + } + }); + useTriliumEvent("readOnlyTemporarilyDisabled", ({ noteContext: eventNoteContext }) => { + if (eventNoteContext.ntxId === noteContext?.ntxId) { + setIsReadOnlyTemporarilyDisabled(eventNoteContext?.viewScope?.readOnlyTemporarilyDisabled); + } + }); + + const parentComponent = useContext(ParentComponent) as ReactWrappedWidget; + useDebugValue(() => `notePath=${notePath}, ntxId=${noteContext?.ntxId}`); + + return { + note, + noteId: noteContext?.note?.noteId, + notePath: noteContext?.notePath, + hoistedNoteId: noteContext?.hoistedNoteId, + ntxId: noteContext?.ntxId, + viewScope: noteContext?.viewScope, + componentId: parentComponent.componentId, + noteContext, + parentComponent, + isReadOnlyTemporarilyDisabled + }; } /**