From ac3b289c9eff4cc94dfe53018a0e05e817301eb0 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 4 Feb 2026 16:46:22 +0200 Subject: [PATCH] feat(mobile): more stable fixed tree for launch bar config --- apps/client/src/stylesheets/style.css | 34 ------------------- .../src/stylesheets/theme-next/shell.css | 2 +- apps/client/src/widgets/NoteDetail.css | 25 +++++++++++++- apps/client/src/widgets/NoteDetail.tsx | 26 +++++++++----- 4 files changed, 42 insertions(+), 45 deletions(-) diff --git a/apps/client/src/stylesheets/style.css b/apps/client/src/stylesheets/style.css index 5a09589e28..88f5e328bb 100644 --- a/apps/client/src/stylesheets/style.css +++ b/apps/client/src/stylesheets/style.css @@ -1694,40 +1694,6 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { } } -@media (max-width: 991px) { - body.mobile.force-fixed-tree #mobile-sidebar-wrapper { - padding-top: 0; - position: static; - height: 40vh; - width: 100vw; - transform: none !important; - background-color: var(--left-pane-background-color) !important; - border-bottom: 0.5px solid var(--main-border-color); - } - - body.mobile.force-fixed-tree #mobile-sidebar-container { - display: none !important; - } - - body.mobile.force-fixed-tree #mobile-sidebar-wrapper .quick-search { - display: none; - } - - body.mobile.force-fixed-tree .component > button.bx-sidebar { - visibility: hidden; - padding: 0; - width: 6px; - } - - body.mobile.force-fixed-tree #mobile-rest-container { - flex-direction: column !important; - } - - body.mobile.force-fixed-tree #detail-container { - flex-grow: 1; - } -} - #launcher-pane { color: var(--launcher-pane-text-color); background-color: var(--launcher-pane-background-color); diff --git a/apps/client/src/stylesheets/theme-next/shell.css b/apps/client/src/stylesheets/theme-next/shell.css index f665bcc843..0df9d6686a 100644 --- a/apps/client/src/stylesheets/theme-next/shell.css +++ b/apps/client/src/stylesheets/theme-next/shell.css @@ -744,7 +744,7 @@ body[dir=rtl] #left-pane span.fancytree-node.protected > span.fancytree-custom-i background-color: rgba(0, 0, 0, 0.5); } - body.mobile:not(.force-fixed-tree) #mobile-sidebar-wrapper { + body.mobile #mobile-sidebar-wrapper { border-top-right-radius: 12px; border-bottom-right-radius: 12px; border-inline-end: 1px solid var(--subtle-border-color); diff --git a/apps/client/src/widgets/NoteDetail.css b/apps/client/src/widgets/NoteDetail.css index 4382277805..0f6cdbfb03 100644 --- a/apps/client/src/widgets/NoteDetail.css +++ b/apps/client/src/widgets/NoteDetail.css @@ -3,6 +3,29 @@ font-family: var(--detail-font-family); font-size: var(--detail-font-size); contain: none; + + &.fixed-tree { + display: flex; + flex-direction: column; + height: 100%; + + .fixed-note-tree-container { + height: 60%; + border-bottom: 1px solid var(--main-border-color); + + .tree-wrapper { + padding: 0; + } + + .tree { + padding: 0; + } + + ul { + margin: 0; + } + } + } } body.prefers-centered-content .note-detail { @@ -12,4 +35,4 @@ body.prefers-centered-content .note-detail { .note-detail > * { contain: none; -} \ No newline at end of file +} diff --git a/apps/client/src/widgets/NoteDetail.tsx b/apps/client/src/widgets/NoteDetail.tsx index 64a485188e..14b7fc3b53 100644 --- a/apps/client/src/widgets/NoteDetail.tsx +++ b/apps/client/src/widgets/NoteDetail.tsx @@ -1,5 +1,7 @@ import "./NoteDetail.css"; +import clsx from "clsx"; +import { use } from "i18next"; import { isValidElement, VNode } from "preact"; import { useEffect, useRef, useState } from "preact/hooks"; @@ -12,8 +14,9 @@ import { t } from "../services/i18n"; import protected_session_holder from "../services/protected_session_holder"; import toast from "../services/toast.js"; import { dynamicRequire, isElectron, isMobile } from "../services/utils"; +import NoteTreeWidget from "./note_tree"; import { ExtendedNoteType, TYPE_MAPPINGS, TypeWidget } from "./note_types"; -import { useNoteContext, useTriliumEvent } from "./react/hooks"; +import { useLegacyWidget, useNote, useNoteContext, useTriliumEvent } from "./react/hooks"; import { NoteListWithLinks } from "./react/NoteList"; import { TypeWidgetProps } from "./type_widgets/type_widget"; @@ -36,6 +39,7 @@ export default function NoteDetail() { const [ noteTypesToRender, setNoteTypesToRender ] = useState<{ [ key in ExtendedNoteType ]?: (props: TypeWidgetProps) => VNode }>({}); const [ activeNoteType, setActiveNoteType ] = useState(); const widgetRequestId = useRef(0); + const hasFixedTree = noteContext?.hoistedNoteId === "_lbMobileRoot" && isMobile(); const props: TypeWidgetProps = { note: note!, @@ -119,13 +123,6 @@ export default function NoteDetail() { } }); - // Fixed tree for launch bar config on mobile. - useEffect(() => { - if (!isMobile) return; - const hasFixedTree = noteContext?.hoistedNoteId === "_lbMobileRoot"; - document.body.classList.toggle("force-fixed-tree", hasFixedTree); - }, [ note ]); - // Handle toast notifications. useEffect(() => { if (!isElectron()) return; @@ -215,8 +212,13 @@ export default function NoteDetail() { return (
+ {hasFixedTree && } + {Object.entries(noteTypesToRender).map(([ itemType, Element ]) => { return new NoteTreeWidget(), { noteContext }); + return
{treeEl}
; +} + /** * Wraps a single note type widget, in order to keep it in the DOM even after the user has switched away to another note type. This allows faster loading of the same note type again. The properties are cached, so that they are updated only * while the widget is visible, to avoid rendering in the background. When not visible, the DOM element is simply hidden.