diff --git a/apps/client/src/widgets/buttons/command_button.ts b/apps/client/src/widgets/buttons/command_button.ts deleted file mode 100644 index 49b147d35..000000000 --- a/apps/client/src/widgets/buttons/command_button.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { ActionKeyboardShortcut } from "@triliumnext/commons"; -import type { CommandNames } from "../../components/app_context.js"; -import keyboardActionsService from "../../services/keyboard_actions.js"; -import AbstractButtonWidget, { type AbstractButtonWidgetSettings } from "./abstract_button.js"; -import type { ButtonNoteIdProvider } from "./button_from_note.js"; - -let actions: ActionKeyboardShortcut[]; - -keyboardActionsService.getActions().then((as) => (actions = as)); - -// TODO: Is this actually used? -export type ClickHandler = (widget: CommandButtonWidget, e: JQuery.ClickEvent) => void; -type CommandOrCallback = CommandNames | (() => CommandNames); - -interface CommandButtonWidgetSettings extends AbstractButtonWidgetSettings { - command?: CommandOrCallback; - onClick?: ClickHandler; - buttonNoteIdProvider?: ButtonNoteIdProvider | null; -} - -export default class CommandButtonWidget extends AbstractButtonWidget { - constructor() { - super(); - this.settings = { - titlePlacement: "right", - title: null, - icon: null, - onContextMenu: null - }; - } - - doRender() { - super.doRender(); - - if (this.settings.command) { - this.$widget.on("click", () => { - this.tooltip.hide(); - - if (this._command) { - this.triggerCommand(this._command); - } - }); - } else { - console.warn(`Button widget '${this.componentId}' has no defined command`, this.settings); - } - } - - getTitle() { - const title = super.getTitle(); - - const action = actions.find((act) => act.actionName === this._command); - - if (action?.effectiveShortcuts && action.effectiveShortcuts.length > 0) { - return `${title} (${action.effectiveShortcuts.join(", ")})`; - } else { - return title; - } - } - - onClick(handler: ClickHandler) { - this.settings.onClick = handler; - return this; - } - - command(command: CommandOrCallback) { - this.settings.command = command; - return this; - } - - get _command() { - return typeof this.settings.command === "function" ? this.settings.command() : this.settings.command; - } -} diff --git a/apps/client/src/widgets/containers/launcher.tsx b/apps/client/src/widgets/containers/launcher.tsx index 17707a171..eeb497901 100644 --- a/apps/client/src/widgets/containers/launcher.tsx +++ b/apps/client/src/widgets/containers/launcher.tsx @@ -3,17 +3,17 @@ import SyncStatusWidget from "../sync_status.js"; import BasicWidget, { wrapReactWidgets } from "../basic_widget.js"; import NoteLauncher from "../buttons/launcher/note_launcher.js"; import ScriptLauncher from "../buttons/launcher/script_launcher.js"; -import CommandButtonWidget from "../buttons/command_button.js"; import utils from "../../services/utils.js"; import TodayLauncher from "../buttons/launcher/today_launcher.js"; import QuickSearchLauncherWidget from "../quick_search_launcher.js"; import type FNote from "../../entities/fnote.js"; -import type { CommandNames } from "../../components/app_context.js"; import BookmarkButtons from "../launch_bar/BookmarkButtons.jsx"; import SpacerWidget from "../launch_bar/SpacerWidget.jsx"; import HistoryNavigationButton from "../launch_bar/HistoryNavigation.jsx"; import AiChatButton from "../launch_bar/AiChatButton.jsx"; import ProtectedSessionStatusWidget from "../launch_bar/ProtectedSessionStatusWidget.jsx"; +import { VNode } from "preact"; +import CommandButton from "../launch_bar/CommandButton.jsx"; interface InnerWidget extends BasicWidget { settings?: { @@ -54,9 +54,9 @@ export default class LauncherWidget extends BasicWidget { return false; } - let widget: BasicWidget; + let widget: BasicWidget | VNode; if (launcherType === "command") { - widget = this.initCommandLauncherWidget(note).class("launcher-button"); + widget = wrapReactWidgets([ ])[0]; } else if (launcherType === "note") { widget = new NoteLauncher(note).class("launcher-button"); } else if (launcherType === "script") { @@ -82,13 +82,6 @@ export default class LauncherWidget extends BasicWidget { return true; } - initCommandLauncherWidget(note: FNote) { - return new CommandButtonWidget() - .title(() => note.title) - .icon(() => note.getIcon()) - .command(() => note.getLabelValue("command") as CommandNames); - } - async initCustomWidget(note: FNote) { const widget = await note.getRelationTarget("widget"); diff --git a/apps/client/src/widgets/launch_bar/CommandButton.tsx b/apps/client/src/widgets/launch_bar/CommandButton.tsx new file mode 100644 index 000000000..22ac0fea2 --- /dev/null +++ b/apps/client/src/widgets/launch_bar/CommandButton.tsx @@ -0,0 +1,19 @@ +import { CommandNames } from "../../components/app_context"; +import FNote from "../../entities/fnote"; +import { escapeHtml } from "../../services/utils"; +import { useNoteLabel, useNoteProperty } from "../react/hooks"; +import { LaunchBarActionButton } from "./launch_bar_widgets"; + +export default function CommandButton({ launcherNote }: { launcherNote: FNote }) { + const [ iconClass ] = useNoteLabel(launcherNote, "iconClass"); + const [ command ] = useNoteLabel(launcherNote, "command"); + const title = useNoteProperty(launcherNote, "title"); + + return iconClass && title && command && ( + + ) +} diff --git a/packages/commons/src/lib/attribute_names.ts b/packages/commons/src/lib/attribute_names.ts index 8b3ec3f37..963fba0eb 100644 --- a/packages/commons/src/lib/attribute_names.ts +++ b/packages/commons/src/lib/attribute_names.ts @@ -26,6 +26,7 @@ type Labels = { // Launch bar bookmarkFolder: boolean; + command: string; // Collection-specific viewType: string;