diff --git a/apps/client/src/layouts/desktop_layout.tsx b/apps/client/src/layouts/desktop_layout.tsx
index 758b2e9c9..21760b9a9 100644
--- a/apps/client/src/layouts/desktop_layout.tsx
+++ b/apps/client/src/layouts/desktop_layout.tsx
@@ -184,7 +184,7 @@ export default class DesktopLayout {
.child(new HighlightsListWidget())
.child(...this.customWidgets.get("right-pane"))
)
- .optChild(isNewLayout, )
+ .optChild(isNewLayout, )
)
.optChild(!launcherPaneIsHorizontal && isNewLayout, )
)
diff --git a/apps/client/src/services/bundle.ts b/apps/client/src/services/bundle.ts
index 649b9a9fd..5dcdfad05 100644
--- a/apps/client/src/services/bundle.ts
+++ b/apps/client/src/services/bundle.ts
@@ -5,7 +5,6 @@ import type { Entity, WidgetDefinition } from "./frontend_script_api.js";
import { t } from "./i18n.js";
import ScriptContext from "./script_context.js";
import server from "./server.js";
-import toast from "./toast.js";
import toastService from "./toast.js";
import utils, { getErrorMessage } from "./utils.js";
@@ -66,51 +65,45 @@ async function executeStartupBundles() {
}
export class WidgetsByParent {
- private byParent: Record;
+ private legacyWidgets: Record;
+ private preactWidgets: Record;
constructor() {
- this.byParent = {};
+ this.legacyWidgets = {};
+ this.preactWidgets = {};
}
add(widget: Widget) {
if ("type" in widget && widget.type === "react-widget") {
// React-based script.
const reactWidget = widget as WidgetDefinition;
- this.byParent[reactWidget.parent] = this.byParent[reactWidget.parent] || [];
- this.byParent[reactWidget.parent].push(widget);
+ this.preactWidgets[reactWidget.parent] = this.preactWidgets[reactWidget.parent] || [];
+ this.preactWidgets[reactWidget.parent].push(reactWidget);
} else if ("parentWidget" in widget && widget.parentWidget) {
- this.byParent[widget.parentWidget] = this.byParent[widget.parentWidget] || [];
- this.byParent[widget.parentWidget].push(widget);
+ this.legacyWidgets[widget.parentWidget] = this.legacyWidgets[widget.parentWidget] || [];
+ this.legacyWidgets[widget.parentWidget].push(widget);
} else {
console.log(`Custom widget does not have mandatory 'parentWidget' property defined`);
}
}
get(parentName: string) {
- if (!this.byParent[parentName]) {
+ if (!this.legacyWidgets[parentName]) {
return [];
}
return (
- this.byParent[parentName]
+ this.legacyWidgets[parentName]
// previously, custom widgets were provided as a single instance, but that has the disadvantage
// for splits where we actually need multiple instaces and thus having a class to instantiate is better
// https://github.com/zadam/trilium/issues/4274
- .map((w: any) => {
- if ("type" in w && w.type === "react-widget") {
- try {
- return w.render();
- } catch (e: unknown) {
- toast.showErrorTitleAndMessage(t("toast.widget-render-error.title"), getErrorMessage(e));
- return null;
- }
- }
-
- return (w.prototype ? new w() : w);
- })
- .filter(Boolean)
+ .map((w: any) => (w.prototype ? new w() : w))
);
}
+
+ getPreactWidgets(parentName: string) {
+ return this.preactWidgets[parentName] ?? [];
+ }
}
async function getWidgetBundlesByParent() {
diff --git a/apps/client/src/services/frontend_script_api_preact.ts b/apps/client/src/services/frontend_script_api_preact.ts
index d728c057f..99132dfb1 100644
--- a/apps/client/src/services/frontend_script_api_preact.ts
+++ b/apps/client/src/services/frontend_script_api_preact.ts
@@ -1,7 +1,10 @@
import { Fragment, h } from "preact";
+import * as hooks from "preact/hooks";
export const preactAPI = Object.freeze({
// Core
h,
- Fragment
+ Fragment,
+
+ ...hooks
});
diff --git a/apps/client/src/widgets/sidebar/RightPanelContainer.tsx b/apps/client/src/widgets/sidebar/RightPanelContainer.tsx
index f7a9a8f51..62da69571 100644
--- a/apps/client/src/widgets/sidebar/RightPanelContainer.tsx
+++ b/apps/client/src/widgets/sidebar/RightPanelContainer.tsx
@@ -6,7 +6,7 @@ import { isValidElement, VNode } from "preact";
import { useEffect, useRef } from "preact/hooks";
import appContext from "../../components/app_context";
-import { Widget } from "../../services/bundle";
+import { WidgetsByParent } from "../../services/bundle";
import { t } from "../../services/i18n";
import options from "../../services/options";
import { DEFAULT_GUTTER_SIZE } from "../../services/resizer";
@@ -27,9 +27,9 @@ interface RightPanelWidgetDefinition {
position: number;
}
-export default function RightPanelContainer({ customWidgets }: { customWidgets: BasicWidget[] }) {
+export default function RightPanelContainer({ widgetsByParent }: { widgetsByParent: WidgetsByParent }) {
const [ rightPaneVisible, setRightPaneVisible ] = useTriliumOptionBool("rightPaneVisible");
- const items = useItems(rightPaneVisible, customWidgets);
+ const items = useItems(rightPaneVisible, widgetsByParent);
useSplit(rightPaneVisible);
return (
@@ -52,7 +52,7 @@ export default function RightPanelContainer({ customWidgets }: { customWidgets:
);
}
-function useItems(rightPaneVisible: boolean, customWidgets: Widget[]) {
+function useItems(rightPaneVisible: boolean, widgetsByParent: WidgetsByParent) {
const { note } = useActiveNoteContext();
const noteType = useNoteProperty(note, "type");
const [ highlightsList ] = useTriliumOptionJson("highlightsList");
@@ -69,11 +69,18 @@ function useItems(rightPaneVisible: boolean, customWidgets: Widget[]) {
enabled: noteType === "text" && highlightsList.length > 0,
position: 20,
},
- ...customWidgets.map((w, i) => ({
- el: isValidElement(w) ? w : ,
+ ...widgetsByParent.get("right-pane").map((widget, i) => ({
+ el: ,
enabled: true,
- position: w.position ?? 30 + i * 10
- }))
+ position: widget.position ?? 30 + i * 10
+ })),
+ ...widgetsByParent.getPreactWidgets("right-pane").map((widget) => {
+ const El = widget.render;
+ return {
+ el: ,
+ enabled: true
+ };
+ })
];
return definitions