chore(react/ribbon): watch note map size

This commit is contained in:
Elian Doran 2025-08-23 11:00:25 +03:00
parent 86dd9aa42a
commit f7c82d6b09
No known key found for this signature in database
3 changed files with 29 additions and 60 deletions

View File

@ -12,7 +12,7 @@ import FNote from "../../entities/fnote";
import attributes from "../../services/attributes"; import attributes from "../../services/attributes";
import FBlob from "../../entities/fblob"; import FBlob from "../../entities/fblob";
import NoteContextAwareWidget from "../note_context_aware_widget"; import NoteContextAwareWidget from "../note_context_aware_widget";
import { VNode } from "preact"; import { RefObject, VNode } from "preact";
type TriliumEventHandler<T extends EventNames> = (data: EventData<T>) => void; type TriliumEventHandler<T extends EventNames> = (data: EventData<T>) => void;
const registeredHandlers: Map<Component, Map<EventNames, TriliumEventHandler<any>[]>> = new Map(); const registeredHandlers: Map<Component, Map<EventNames, TriliumEventHandler<any>[]>> = new Map();
@ -455,3 +455,19 @@ export function useLegacyWidget<T extends BasicWidget>(widgetFactory: () => T, {
return [ <div className={containerClassName} ref={ref} />, widget ] return [ <div className={containerClassName} ref={ref} />, widget ]
} }
export function useResizeObserver(ref: RefObject<HTMLElement>, callback: ResizeObserverCallback) {
useEffect(() => {
if (!ref.current) {
return;
}
const element = ref.current;
const resizeObserver = new ResizeObserver(callback);
resizeObserver.observe(element);
return () => {
resizeObserver.unobserve(element);
resizeObserver.disconnect();
}
}, [ ref, callback ]);
}

View File

@ -1,9 +1,9 @@
import { TabContext } from "./ribbon-interface"; import { TabContext } from "./ribbon-interface";
import NoteMapWidget from "../note_map"; import NoteMapWidget from "../note_map";
import { useLegacyWidget } from "../react/hooks"; import { useLegacyWidget, useResizeObserver } from "../react/hooks";
import ActionButton from "../react/ActionButton"; import ActionButton from "../react/ActionButton";
import { t } from "../../services/i18n"; import { t } from "../../services/i18n";
import { useEffect, useRef, useState } from "preact/hooks"; import { useCallback, useEffect, useRef, useState } from "preact/hooks";
const SMALL_SIZE_HEIGHT = "300px"; const SMALL_SIZE_HEIGHT = "300px";
@ -17,19 +17,20 @@ export default function NoteMapTab({ note, noteContext }: TabContext) {
containerClassName: "note-map-container" containerClassName: "note-map-container"
}); });
useEffect(() => noteMapWidget.setDimensions(), [ height ]); const resizeIfNeeded = useCallback(() => {
console.log("Resize if needed");
function toggleExpanded(newValue: boolean) { if (isExpanded && containerRef.current) {
setExpanded(newValue);
if (newValue && containerRef.current) {
const { top } = containerRef.current.getBoundingClientRect(); const { top } = containerRef.current.getBoundingClientRect();
const height = window.innerHeight - top; const height = window.innerHeight - top;
setHeight(height + "px"); setHeight(height + "px");
} else { } else {
setHeight(SMALL_SIZE_HEIGHT); setHeight(SMALL_SIZE_HEIGHT);
} }
} }, [ isExpanded, containerRef ]);
useEffect(() => noteMapWidget.setDimensions(), [ height ]);
useEffect(() => resizeIfNeeded(), [ isExpanded ]);
useResizeObserver(containerRef, resizeIfNeeded);
return ( return (
<div className="note-map-ribbon-widget" style={{ height }} ref={containerRef}> <div className="note-map-ribbon-widget" style={{ height }} ref={containerRef}>
@ -40,14 +41,14 @@ export default function NoteMapTab({ note, noteContext }: TabContext) {
icon="bx bx-arrow-to-bottom" icon="bx bx-arrow-to-bottom"
text={t("note_map.open_full")} text={t("note_map.open_full")}
className="open-full-button" className="open-full-button"
onClick={() => toggleExpanded(true)} onClick={() => setExpanded(true)}
/> />
) : ( ) : (
<ActionButton <ActionButton
icon="bx bx-arrow-to-top" icon="bx bx-arrow-to-top"
text={t("note_map.collapse")} text={t("note_map.collapse")}
className="collapse-button" className="collapse-button"
onClick={() => toggleExpanded(false)} onClick={() => setExpanded(false)}
/> />
)} )}
</div> </div>

View File

@ -1,48 +0,0 @@
import NoteContextAwareWidget from "../note_context_aware_widget.js";
import NoteMapWidget from "../note_map.js";
import { t } from "../../services/i18n.js";
export default class NoteMapRibbonWidget extends NoteContextAwareWidget {
private openState!: "small" | "full";
private $container!: JQuery<HTMLElement>;
private $openFullButton!: JQuery<HTMLElement>;
private $collapseButton!: JQuery<HTMLElement>;
doRender() {
this.$widget = $(TPL);
this.contentSized();
this.$container = this.$widget.find(".note-map-container");
this.$container.append(this.noteMapWidget.render());
this.openState = "small";
this.$openFullButton = this.$widget.find(".open-full-button");
this.$openFullButton.on("click", () => {
this.setFullHeight();
this.$openFullButton.hide();
this.$collapseButton.show();
this.openState = "full";
this.noteMapWidget.setDimensions();
});
this.$collapseButton = this.$widget.find(".collapse-button");
this.$collapseButton.on("click", () => {
this.setSmallSize();
this.$openFullButton.show();
this.$collapseButton.hide();
this.openState = "small";
this.noteMapWidget.setDimensions();
});
new ResizeObserver(handleResize).observe(this.$widget[0]);
}
}