chore(react): reintroduce reactivity to mapRootIdLabel

This commit is contained in:
Elian Doran
2025-10-04 18:08:24 +03:00
parent 0da66617a8
commit 8f819a7786
4 changed files with 18 additions and 80 deletions

View File

@@ -1,54 +0,0 @@
import server from "../services/server.js";
import attributeService from "../services/attributes.js";
import hoistedNoteService from "../services/hoisted_note.js";
import appContext, { type EventData } from "../components/app_context.js";
import NoteContextAwareWidget from "./note_context_aware_widget.js";
import linkContextMenuService from "../menus/link_context_menu.js";
import utils from "../services/utils.js";
import { t } from "../services/i18n.js";
import type ForceGraph from "force-graph";
import type { GraphData, LinkObject, NodeObject } from "force-graph";
import type FNote from "../entities/fnote.js";
type WidgetMode = "type" | "ribbon";
type Data = GraphData<NodeObject, LinkObject<NodeObject>>;
export default class NoteMapWidget extends NoteContextAwareWidget {
private fixNodes: boolean;
private widgetMode: WidgetMode;
private themeStyle!: string;
private $container!: JQuery<HTMLElement>;
private $fixNodesButton!: JQuery<HTMLElement>;
graph!: ForceGraph;
private noteIdToSizeMap!: Record<string, number>;
constructor(widgetMode: WidgetMode) {
super();
this.widgetMode = widgetMode; // 'type' or 'ribbon'
}
doRender() {
this.$widget = $(TPL);
this.$container = this.$widget.find(".note-map-container");
this.$styleResolver = this.$widget.find(".style-resolver");
this.$fixNodesButton = this.$widget.find(".fixnodes-type-switcher > button");
new ResizeObserver(() => this.setDimensions()).observe(this.$container[0]);
}
cleanup() {
this.$container.html("");
}
entitiesReloadedEvent({ loadResults }: EventData<"entitiesReloaded">) {
if (loadResults.getAttributeRows(this.componentId)
.find((attr) => attr.type === "label" && ["mapType", "mapRootNoteId"].includes(attr.name || "") && attributeService.isAffecting(attr, this.note))) {
this.refresh();
}
}
}

View File

@@ -1,6 +1,6 @@
import { useEffect, useRef, useState } from "preact/hooks";
import { useEffect, useMemo, useRef, useState } from "preact/hooks";
import "./NoteMap.css";
import { getMapRootNoteId, getThemeStyle, MapType, NoteMapWidgetMode, rgb2hex } from "./utils";
import { getThemeStyle, MapType, NoteMapWidgetMode, rgb2hex } from "./utils";
import { RefObject } from "preact";
import FNote from "../../entities/fnote";
import { useElementSize, useNoteContext, useNoteLabel } from "../react/hooks";
@@ -12,6 +12,7 @@ import { t } from "../../services/i18n";
import link_context_menu from "../../menus/link_context_menu";
import appContext from "../../components/app_context";
import Slider from "../react/Slider";
import hoisted_note from "../../services/hoisted_note";
interface NoteMapProps {
note: FNote;
@@ -23,6 +24,7 @@ export default function NoteMap({ note, widgetMode, parentRef }: NoteMapProps) {
const containerRef = useRef<HTMLDivElement>(null);
const styleResolverRef = useRef<HTMLDivElement>(null);
const [ mapTypeRaw, setMapType ] = useNoteLabel(note, "mapType");
const [ mapRootIdLabel ] = useNoteLabel(note, "mapRootNoteId");
const mapType: MapType = mapTypeRaw === "tree" ? "tree" : "link";
const graphRef = useRef<ForceGraph<NodeObject, LinkObject<NodeObject>>>();
@@ -31,17 +33,26 @@ export default function NoteMap({ note, widgetMode, parentRef }: NoteMapProps) {
const [ linkDistance, setLinkDistance ] = useState(40);
const notesAndRelationsRef = useRef<NotesAndRelationsData>();
const mapRootId = useMemo(() => {
if (note.noteId && widgetMode === "ribbon") {
return note.noteId;
} else if (mapRootIdLabel === "hoisted") {
return hoisted_note.getHoistedNoteId();
} else if (mapRootIdLabel) {
return mapRootIdLabel;
} else {
return appContext.tabManager.getActiveContext()?.parentNoteId ?? null;
}
}, [ note ]);
// Build the note graph instance.
useEffect(() => {
const container = containerRef.current;
if (!container) return;
if (!container || !mapRootId) return;
const graph = new ForceGraph(container);
graphRef.current = graph;
const mapRootId = getMapRootNoteId(note.noteId, note, widgetMode);
if (!mapRootId) return;
const labelValues = (name: string) => note.getLabels(name).map(l => l.value) ?? [];
const excludeRelations = labelValues("mapExcludeRelation");
const includeRelations = labelValues("mapIncludeRelation");

View File

@@ -1,7 +1,3 @@
import appContext from "../../components/app_context";
import FNote from "../../entities/fnote";
import hoisted_note from "../../services/hoisted_note";
export type NoteMapWidgetMode = "ribbon" | "hoisted";
export type MapType = "tree" | "link";
@@ -12,22 +8,6 @@ export function rgb2hex(rgb: string) {
.join("")}`;
}
export function getMapRootNoteId(noteId: string, note: FNote, widgetMode: NoteMapWidgetMode): string | null {
if (noteId && widgetMode === "ribbon") {
return noteId;
}
let mapRootNoteId = note?.getLabelValue("mapRootNoteId");
if (mapRootNoteId === "hoisted") {
mapRootNoteId = hoisted_note.getHoistedNoteId();
} else if (!mapRootNoteId) {
mapRootNoteId = appContext.tabManager.getActiveContext()?.parentNoteId ?? null;
}
return mapRootNoteId;
}
export function generateColorFromString(str: string, themeStyle: "light" | "dark") {
if (themeStyle === "dark") {
str = `0${str}`; // magic lightning modifier

View File

@@ -43,6 +43,7 @@ type Labels = {
webViewSrc: string;
readOnly: boolean;
mapType: string;
mapRootNoteId: string;
}
/**