mirror of
https://github.com/zadam/trilium.git
synced 2025-12-22 15:24:24 +01:00
feat(script/jsx): add support for React hooks
This commit is contained in:
parent
4d7e5bc8f6
commit
44ca9f457c
@ -184,7 +184,7 @@ export default class DesktopLayout {
|
|||||||
.child(new HighlightsListWidget())
|
.child(new HighlightsListWidget())
|
||||||
.child(...this.customWidgets.get("right-pane"))
|
.child(...this.customWidgets.get("right-pane"))
|
||||||
)
|
)
|
||||||
.optChild(isNewLayout, <RightPanelContainer customWidgets={this.customWidgets.get("right-pane")} />)
|
.optChild(isNewLayout, <RightPanelContainer widgetsByParent={this.customWidgets} />)
|
||||||
)
|
)
|
||||||
.optChild(!launcherPaneIsHorizontal && isNewLayout, <StatusBar />)
|
.optChild(!launcherPaneIsHorizontal && isNewLayout, <StatusBar />)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import type { Entity, WidgetDefinition } from "./frontend_script_api.js";
|
|||||||
import { t } from "./i18n.js";
|
import { t } from "./i18n.js";
|
||||||
import ScriptContext from "./script_context.js";
|
import ScriptContext from "./script_context.js";
|
||||||
import server from "./server.js";
|
import server from "./server.js";
|
||||||
import toast from "./toast.js";
|
|
||||||
import toastService from "./toast.js";
|
import toastService from "./toast.js";
|
||||||
import utils, { getErrorMessage } from "./utils.js";
|
import utils, { getErrorMessage } from "./utils.js";
|
||||||
|
|
||||||
@ -66,51 +65,45 @@ async function executeStartupBundles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class WidgetsByParent {
|
export class WidgetsByParent {
|
||||||
private byParent: Record<string, Widget[]>;
|
private legacyWidgets: Record<string, LegacyWidget[]>;
|
||||||
|
private preactWidgets: Record<string, WidgetDefinition[]>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.byParent = {};
|
this.legacyWidgets = {};
|
||||||
|
this.preactWidgets = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
add(widget: Widget) {
|
add(widget: Widget) {
|
||||||
if ("type" in widget && widget.type === "react-widget") {
|
if ("type" in widget && widget.type === "react-widget") {
|
||||||
// React-based script.
|
// React-based script.
|
||||||
const reactWidget = widget as WidgetDefinition;
|
const reactWidget = widget as WidgetDefinition;
|
||||||
this.byParent[reactWidget.parent] = this.byParent[reactWidget.parent] || [];
|
this.preactWidgets[reactWidget.parent] = this.preactWidgets[reactWidget.parent] || [];
|
||||||
this.byParent[reactWidget.parent].push(widget);
|
this.preactWidgets[reactWidget.parent].push(reactWidget);
|
||||||
} else if ("parentWidget" in widget && widget.parentWidget) {
|
} else if ("parentWidget" in widget && widget.parentWidget) {
|
||||||
this.byParent[widget.parentWidget] = this.byParent[widget.parentWidget] || [];
|
this.legacyWidgets[widget.parentWidget] = this.legacyWidgets[widget.parentWidget] || [];
|
||||||
this.byParent[widget.parentWidget].push(widget);
|
this.legacyWidgets[widget.parentWidget].push(widget);
|
||||||
} else {
|
} else {
|
||||||
console.log(`Custom widget does not have mandatory 'parentWidget' property defined`);
|
console.log(`Custom widget does not have mandatory 'parentWidget' property defined`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get(parentName: string) {
|
get(parentName: string) {
|
||||||
if (!this.byParent[parentName]) {
|
if (!this.legacyWidgets[parentName]) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
this.byParent[parentName]
|
this.legacyWidgets[parentName]
|
||||||
// previously, custom widgets were provided as a single instance, but that has the disadvantage
|
// 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
|
// for splits where we actually need multiple instaces and thus having a class to instantiate is better
|
||||||
// https://github.com/zadam/trilium/issues/4274
|
// https://github.com/zadam/trilium/issues/4274
|
||||||
.map((w: any) => {
|
.map((w: any) => (w.prototype ? new w() : w))
|
||||||
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)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPreactWidgets(parentName: string) {
|
||||||
|
return this.preactWidgets[parentName] ?? [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getWidgetBundlesByParent() {
|
async function getWidgetBundlesByParent() {
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { Fragment, h } from "preact";
|
import { Fragment, h } from "preact";
|
||||||
|
import * as hooks from "preact/hooks";
|
||||||
|
|
||||||
export const preactAPI = Object.freeze({
|
export const preactAPI = Object.freeze({
|
||||||
// Core
|
// Core
|
||||||
h,
|
h,
|
||||||
Fragment
|
Fragment,
|
||||||
|
|
||||||
|
...hooks
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { isValidElement, VNode } from "preact";
|
|||||||
import { useEffect, useRef } from "preact/hooks";
|
import { useEffect, useRef } from "preact/hooks";
|
||||||
|
|
||||||
import appContext from "../../components/app_context";
|
import appContext from "../../components/app_context";
|
||||||
import { Widget } from "../../services/bundle";
|
import { WidgetsByParent } from "../../services/bundle";
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
import options from "../../services/options";
|
import options from "../../services/options";
|
||||||
import { DEFAULT_GUTTER_SIZE } from "../../services/resizer";
|
import { DEFAULT_GUTTER_SIZE } from "../../services/resizer";
|
||||||
@ -27,9 +27,9 @@ interface RightPanelWidgetDefinition {
|
|||||||
position: number;
|
position: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function RightPanelContainer({ customWidgets }: { customWidgets: BasicWidget[] }) {
|
export default function RightPanelContainer({ widgetsByParent }: { widgetsByParent: WidgetsByParent }) {
|
||||||
const [ rightPaneVisible, setRightPaneVisible ] = useTriliumOptionBool("rightPaneVisible");
|
const [ rightPaneVisible, setRightPaneVisible ] = useTriliumOptionBool("rightPaneVisible");
|
||||||
const items = useItems(rightPaneVisible, customWidgets);
|
const items = useItems(rightPaneVisible, widgetsByParent);
|
||||||
useSplit(rightPaneVisible);
|
useSplit(rightPaneVisible);
|
||||||
|
|
||||||
return (
|
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 { note } = useActiveNoteContext();
|
||||||
const noteType = useNoteProperty(note, "type");
|
const noteType = useNoteProperty(note, "type");
|
||||||
const [ highlightsList ] = useTriliumOptionJson<string[]>("highlightsList");
|
const [ highlightsList ] = useTriliumOptionJson<string[]>("highlightsList");
|
||||||
@ -69,11 +69,18 @@ function useItems(rightPaneVisible: boolean, customWidgets: Widget[]) {
|
|||||||
enabled: noteType === "text" && highlightsList.length > 0,
|
enabled: noteType === "text" && highlightsList.length > 0,
|
||||||
position: 20,
|
position: 20,
|
||||||
},
|
},
|
||||||
...customWidgets.map((w, i) => ({
|
...widgetsByParent.get("right-pane").map((widget, i) => ({
|
||||||
el: isValidElement(w) ? w : <CustomLegacyWidget key={w._noteId} originalWidget={w as LegacyRightPanelWidget} />,
|
el: <CustomLegacyWidget key={widget._noteId} originalWidget={widget as LegacyRightPanelWidget} />,
|
||||||
enabled: true,
|
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: <El />,
|
||||||
|
enabled: true
|
||||||
|
};
|
||||||
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
return definitions
|
return definitions
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user