mirror of
https://github.com/zadam/trilium.git
synced 2025-11-09 07:58:59 +01:00
client: make the info bar part of the scrollable content, prevent overlapping with the floating buttons
This commit is contained in:
parent
d8d80ed936
commit
285a7253e3
@ -499,6 +499,10 @@ type EventMappings = {
|
||||
noteIds: string[];
|
||||
};
|
||||
refreshData: { ntxId: string | null | undefined };
|
||||
contentSafeMarginChanged: {
|
||||
top: number;
|
||||
noteContext: NoteContext;
|
||||
}
|
||||
};
|
||||
|
||||
export type EventListener<T extends EventNames> = {
|
||||
|
||||
@ -3,6 +3,7 @@ import { DESKTOP_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.
|
||||
import ApiLog from "../widgets/api_log.jsx";
|
||||
import ClosePaneButton from "../widgets/buttons/close_pane_button.js";
|
||||
import CloseZenModeButton from "../widgets/close_zen_button.jsx";
|
||||
import ContentHeader from "../widgets/content-header.js";
|
||||
import CreatePaneButton from "../widgets/buttons/create_pane_button.js";
|
||||
import FindWidget from "../widgets/find.js";
|
||||
import FlexContainer from "../widgets/containers/flex_container.js";
|
||||
@ -131,13 +132,14 @@ export default class DesktopLayout {
|
||||
)
|
||||
.child(<Ribbon />)
|
||||
.child(<SharedInfo />)
|
||||
.child(<ReadOnlyNoteInfoBar />)
|
||||
.child(new WatchedFileUpdateStatusWidget())
|
||||
.child(<FloatingButtons items={DESKTOP_FLOATING_BUTTONS} />)
|
||||
.child(
|
||||
new ScrollingContainer()
|
||||
.filling()
|
||||
.child(<ReadOnlyNoteInfoBar zenModeOnly />)
|
||||
.child(new ContentHeader()
|
||||
.child(<ReadOnlyNoteInfoBar />)
|
||||
)
|
||||
.child(new PromotedAttributesWidget())
|
||||
.child(<SqlTableSchemas />)
|
||||
.child(new NoteDetailWidget())
|
||||
|
||||
@ -28,6 +28,7 @@ import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibb
|
||||
import TabRowWidget from "../widgets/tab_row.js";
|
||||
import ToggleSidebarButton from "../widgets/mobile_widgets/toggle_sidebar_button.jsx";
|
||||
import type AppContext from "../components/app_context.js";
|
||||
import ContentHeader from "../widgets/content-header.js";
|
||||
|
||||
const MOBILE_CSS = `
|
||||
<style>
|
||||
@ -151,14 +152,15 @@ export default class MobileLayout {
|
||||
.child(<MobileDetailMenu />)
|
||||
)
|
||||
.child(<SharedInfoWidget />)
|
||||
.child(<ReadOnlyNoteInfoBar />)
|
||||
.child(<FloatingButtons items={MOBILE_FLOATING_BUTTONS} />)
|
||||
.child(<ReadOnlyNoteInfoBar zenModeOnly />)
|
||||
.child(new PromotedAttributesWidget())
|
||||
.child(
|
||||
new ScrollingContainer()
|
||||
.filling()
|
||||
.contentSized()
|
||||
.child(new ContentHeader()
|
||||
.child(<ReadOnlyNoteInfoBar />)
|
||||
)
|
||||
.child(new NoteDetailWidget())
|
||||
.child(<NoteList media="screen" />)
|
||||
.child(<StandaloneRibbonAdapter component={SearchDefinitionTab} />)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { t } from "i18next";
|
||||
import "./FloatingButtons.css";
|
||||
import { useNoteContext, useNoteLabel, useNoteLabelBoolean } from "./react/hooks";
|
||||
import { useNoteContext, useNoteLabel, useNoteLabelBoolean, useTriliumEvent } from "./react/hooks";
|
||||
import { useContext, useEffect, useMemo, useState } from "preact/hooks";
|
||||
import { ParentComponent } from "./react/react_utils";
|
||||
import { EventData, EventNames } from "../components/app_context";
|
||||
@ -20,6 +20,7 @@ interface FloatingButtonsProps {
|
||||
* properly handle rounded corners, as defined by the --border-radius CSS variable.
|
||||
*/
|
||||
export default function FloatingButtons({ items }: FloatingButtonsProps) {
|
||||
const [ top, setTop ] = useState(0);
|
||||
const { note, noteContext } = useNoteContext();
|
||||
const parentComponent = useContext(ParentComponent);
|
||||
const [ viewType ] = useNoteLabel(note, "viewType");
|
||||
@ -47,8 +48,14 @@ export default function FloatingButtons({ items }: FloatingButtonsProps) {
|
||||
const [ visible, setVisible ] = useState(true);
|
||||
useEffect(() => setVisible(true), [ note ]);
|
||||
|
||||
useTriliumEvent("contentSafeMarginChanged", (e) => {
|
||||
if (e.noteContext === noteContext) {
|
||||
setTop(e.top);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="floating-buttons no-print">
|
||||
<div className="floating-buttons no-print" style={{top}}>
|
||||
<div className={`floating-buttons-children ${!visible ? "temporarily-hidden" : ""}`}>
|
||||
{context && items.map((Component) => (
|
||||
<Component {...context} />
|
||||
|
||||
63
apps/client/src/widgets/content-header.ts
Normal file
63
apps/client/src/widgets/content-header.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import { EventData } from "../components/app_context";
|
||||
import BasicWidget from "./basic_widget";
|
||||
import Container from "./containers/container";
|
||||
import NoteContext from "../components/note_context";
|
||||
|
||||
export default class ContentHeader extends Container<BasicWidget> {
|
||||
|
||||
noteContext?: NoteContext;
|
||||
thisElement?: HTMLElement;
|
||||
parentElement?: HTMLElement;
|
||||
resizeObserver: ResizeObserver;
|
||||
currentHeight: number = 0;
|
||||
currentSafeMargin: number = NaN;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.css("contain", "unset");
|
||||
this.resizeObserver = new ResizeObserver(this.onResize.bind(this));
|
||||
}
|
||||
|
||||
setNoteContextEvent({ noteContext }: EventData<"setNoteContext">) {
|
||||
this.noteContext = noteContext;
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
this.parentElement = this.parent!.$widget.get(0);
|
||||
|
||||
if (!this.parentElement) {
|
||||
console.warn("No parent set for <ContentHeader>.");
|
||||
return;
|
||||
}
|
||||
|
||||
this.thisElement = this.$widget.get(0)!;
|
||||
|
||||
this.resizeObserver.observe(this.thisElement);
|
||||
this.parentElement.addEventListener("scroll", this.updateSafeMargin.bind(this));
|
||||
}
|
||||
|
||||
updateSafeMargin() {
|
||||
const newSafeMargin = Math.max(this.currentHeight - this.parentElement!.scrollTop, 0);
|
||||
|
||||
if (newSafeMargin !== this.currentSafeMargin) {
|
||||
this.currentSafeMargin = newSafeMargin;
|
||||
|
||||
this.triggerEvent("contentSafeMarginChanged", {
|
||||
top: newSafeMargin,
|
||||
noteContext: this.noteContext!
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onResize(entries: ResizeObserverEntry[]) {
|
||||
for (const entry of entries) {
|
||||
if (entry.target === this.thisElement) {
|
||||
this.currentHeight = entry.contentRect.height;
|
||||
this.updateSafeMargin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user