From 604488b166a135bee14d80c80dc6945506513b09 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 4 Dec 2025 17:55:38 +0200 Subject: [PATCH] chore(react/launch_bar): port custom widget --- .../src/widgets/containers/launcher.tsx | 35 ++++++++++++++++--- apps/client/src/widgets/react/hooks.tsx | 10 ++++++ packages/commons/src/lib/attribute_names.ts | 3 +- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/apps/client/src/widgets/containers/launcher.tsx b/apps/client/src/widgets/containers/launcher.tsx index f30c9ad28..c61717cf2 100644 --- a/apps/client/src/widgets/containers/launcher.tsx +++ b/apps/client/src/widgets/containers/launcher.tsx @@ -11,10 +11,10 @@ import ProtectedSessionStatusWidget from "../launch_bar/ProtectedSessionStatusWi import { VNode } from "preact"; import { CommandButton, CustomNoteLauncher, NoteLauncher } from "../launch_bar/GenericButtons.jsx"; import date_notes from "../../services/date_notes.js"; -import { useLegacyWidget } from "../react/hooks.jsx"; +import { useLegacyWidget, useNoteContext, useNoteRelation, useNoteRelationTarget } from "../react/hooks.jsx"; import QuickSearchWidget from "../quick_search.js"; import { ParentComponent } from "../react/react_utils.jsx"; -import { useContext } from "preact/hooks"; +import { useContext, useEffect, useMemo, useState } from "preact/hooks"; import { LaunchBarActionButton, useLauncherIconAndTitle } from "../launch_bar/launch_bar_widgets.jsx"; interface InnerWidget extends BasicWidget { @@ -64,7 +64,7 @@ export default class LauncherWidget extends BasicWidget { } else if (launcherType === "script") { widget = wrapReactWidgets([ ])[0]; } else if (launcherType === "customWidget") { - widget = await this.initCustomWidget(note); + widget = wrapReactWidgets([ ])[0]; } else if (launcherType === "builtinWidget") { widget = wrapReactWidgets([ this.initBuiltinWidget(note) ])[0]; } else { @@ -160,14 +160,39 @@ function TodayLauncher({ launcherNote }: { launcherNote: FNote }) { } function QuickSearchLauncherWidget({ isHorizontalLayout }: { isHorizontalLayout: boolean }) { - const [ widgetEl ] = useLegacyWidget(() => new QuickSearchWidget()); + const widget = useMemo(() => new QuickSearchWidget(), []); const parentComponent = useContext(ParentComponent) as BasicWidget | null; const isEnabled = isHorizontalLayout && !isMobile(); parentComponent?.contentSized(); return (
- {isEnabled && widgetEl} + {isEnabled && }
) } + +function CustomWidget({ launcherNote }: { launcherNote: FNote }) { + const [ widgetNote ] = useNoteRelationTarget(launcherNote, "widget"); + const [ widget, setWidget ] = useState(); + const parentComponent = useContext(ParentComponent) as BasicWidget | null; + parentComponent?.contentSized(); + + useEffect(() => { + widgetNote?.executeScript().then(setWidget); + }, [ widgetNote ]); + + return ( +
+ {widget && } +
+ ) +} + +function LegacyWidgetRenderer({ widget }: { widget: BasicWidget }) { + const { noteContext } = useNoteContext(); + const [ widgetEl ] = useLegacyWidget(() => widget, { + noteContext + }); + return widgetEl; +} diff --git a/apps/client/src/widgets/react/hooks.tsx b/apps/client/src/widgets/react/hooks.tsx index c602802d5..77119ce18 100644 --- a/apps/client/src/widgets/react/hooks.tsx +++ b/apps/client/src/widgets/react/hooks.tsx @@ -370,6 +370,16 @@ export function useNoteRelation(note: FNote | undefined | null, relationName: Re ] as const; } +export function useNoteRelationTarget(note: FNote, relationName: RelationNames) { + const [ targetNote, setTargetNote ] = useState(); + + useEffect(() => { + note.getRelationTarget(relationName).then(setTargetNote); + }, [ note ]); + + return [ targetNote ] as const; +} + /** * Allows a React component to read or write a note's label while also reacting to changes in value. * diff --git a/packages/commons/src/lib/attribute_names.ts b/packages/commons/src/lib/attribute_names.ts index 04d365f1a..16793b964 100644 --- a/packages/commons/src/lib/attribute_names.ts +++ b/packages/commons/src/lib/attribute_names.ts @@ -62,7 +62,8 @@ type Relations = [ "ancestor", // Launcher-specific - "target" + "target", + "widget" ]; export type LabelNames = keyof Labels;