diff --git a/apps/client/src/services/bundle.ts b/apps/client/src/services/bundle.ts index 9127705a3..bc0445493 100644 --- a/apps/client/src/services/bundle.ts +++ b/apps/client/src/services/bundle.ts @@ -1,3 +1,6 @@ +import { h, VNode } from "preact"; + +import Component from "../components/component.js"; import BasicWidget from "../widgets/basic_widget.js"; import RightPanelWidget from "../widgets/right_panel_widget.js"; import froca from "./froca.js"; @@ -77,24 +80,42 @@ export class WidgetsByParent { } add(widget: Widget) { + let hasParentWidget = false; + let isPreact = false; if ("type" in widget && widget.type === "preact-widget") { // React-based script. const reactWidget = widget as WidgetDefinitionWithType; this.preactWidgets[reactWidget.parent] = this.preactWidgets[reactWidget.parent] || []; this.preactWidgets[reactWidget.parent].push(reactWidget); + isPreact = true; + hasParentWidget = !!reactWidget.parent; } else if ("parentWidget" in widget && widget.parentWidget) { this.legacyWidgets[widget.parentWidget] = this.legacyWidgets[widget.parentWidget] || []; this.legacyWidgets[widget.parentWidget].push(widget); - } else { - showErrorForScriptNote(widget._noteId, t("toast.widget-missing-parent")); + hasParentWidget = !!widget.parentWidget; + } + + if (!hasParentWidget) { + showErrorForScriptNote(widget._noteId, t("toast.widget-missing-parent", { + property: isPreact ? "parent" : "parentWidget" + })); } } get(parentName: ParentName) { - if (!this.legacyWidgets[parentName]) { - return []; + const widgets: (Component | VNode)[] = this.getLegacyWidgets(parentName); + for (const preactWidget of this.getPreactWidgets(parentName)) { + const el = h(preactWidget.render, {}); + // TODO: set position here. + widgets.push(el); } + return widgets; + } + + getLegacyWidgets(parentName: ParentName): (BasicWidget | RightPanelWidget)[] { + if (!this.legacyWidgets[parentName]) return []; + return ( this.legacyWidgets[parentName] // previously, custom widgets were provided as a single instance, but that has the disadvantage diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index 261f4e018..22c6acda9 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -29,7 +29,7 @@ "widget-render-error": { "title": "Failed to render a custom React widget" }, - "widget-missing-parent": "Custom widget does not have mandatory 'parentWidget' property defined.", + "widget-missing-parent": "Custom widget does not have mandatory '{{property}}' property defined.", "open-script-note": "Open script note" }, "add_link": { diff --git a/apps/client/src/widgets/sidebar/RightPanelContainer.tsx b/apps/client/src/widgets/sidebar/RightPanelContainer.tsx index 62da69571..ade0c2b7d 100644 --- a/apps/client/src/widgets/sidebar/RightPanelContainer.tsx +++ b/apps/client/src/widgets/sidebar/RightPanelContainer.tsx @@ -69,7 +69,7 @@ function useItems(rightPaneVisible: boolean, widgetsByParent: WidgetsByParent) { enabled: noteType === "text" && highlightsList.length > 0, position: 20, }, - ...widgetsByParent.get("right-pane").map((widget, i) => ({ + ...widgetsByParent.getLegacyWidgets("right-pane").map((widget, i) => ({ el: , enabled: true, position: widget.position ?? 30 + i * 10