diff --git a/apps/client/src/widgets/containers/launcher.tsx b/apps/client/src/widgets/containers/launcher.tsx
index eeb497901..6fd39eac1 100644
--- a/apps/client/src/widgets/containers/launcher.tsx
+++ b/apps/client/src/widgets/containers/launcher.tsx
@@ -13,7 +13,7 @@ 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";
+import { CommandButton } from "../launch_bar/GenericButtons.jsx";
interface InnerWidget extends BasicWidget {
settings?: {
diff --git a/apps/client/src/widgets/launch_bar/BookmarkButtons.tsx b/apps/client/src/widgets/launch_bar/BookmarkButtons.tsx
index 4c0df90e6..bf8b6cead 100644
--- a/apps/client/src/widgets/launch_bar/BookmarkButtons.tsx
+++ b/apps/client/src/widgets/launch_bar/BookmarkButtons.tsx
@@ -1,13 +1,12 @@
import { useMemo } from "preact/hooks";
-import { LaunchBarActionButton, LaunchBarDropdownButton, type LaunchBarWidgetProps } from "./launch_bar_widgets";
+import { LaunchBarDropdownButton, type LaunchBarWidgetProps } from "./launch_bar_widgets";
import { CSSProperties } from "preact";
import type FNote from "../../entities/fnote";
import { useChildNotes, useNoteLabel, useNoteLabelBoolean, useNoteProperty } from "../react/hooks";
-import appContext from "../../components/app_context";
-import { escapeHtml, isCtrlKey } from "../../services/utils";
-import link_context_menu from "../../menus/link_context_menu";
+import { escapeHtml } from "../../services/utils";
import "./BookmarkButtons.css";
import NoteLink from "../react/NoteLink";
+import { NoteLauncher } from "./GenericButtons";
const PARENT_NOTE_ID = "_lbBookmarks";
@@ -30,40 +29,7 @@ function SingleBookmark({ note }: { note: FNote }) {
const [ bookmarkFolder ] = useNoteLabelBoolean(note, "bookmarkFolder");
return bookmarkFolder
?
- :
-}
-
-function OpenNoteButtonWidget({ note }: { note: FNote }) {
- const [ iconClass ] = useNoteLabel(note, "iconClass");
- const title = useNoteProperty(note, "title");
-
- async function launch(evt: MouseEvent) {
- if (evt.which === 3) {
- return;
- }
- const hoistedNoteId = getHoistedNoteId(note);
- const ctrlKey = isCtrlKey(evt);
-
- if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
- const activate = evt.shiftKey ? true : false;
- await appContext.tabManager.openInNewTab(note.noteId, hoistedNoteId, activate);
- } else {
- await appContext.tabManager.openInSameTab(note.noteId);
- }
- }
-
- return title && iconClass && (
- {
- evt.preventDefault();
- link_context_menu.openContextMenu(note.noteId, evt);
- }}
- />
- )
+ :
}
function BookmarkFolder({ note }: { note: FNote }) {
@@ -92,7 +58,3 @@ function BookmarkFolder({ note }: { note: FNote }) {
)
}
-
-function getHoistedNoteId(noteToOpen: FNote) {
- return noteToOpen.getRelationValue("hoistedNote") || appContext.tabManager.getActiveContext()?.hoistedNoteId;
-}
diff --git a/apps/client/src/widgets/launch_bar/CommandButton.tsx b/apps/client/src/widgets/launch_bar/CommandButton.tsx
deleted file mode 100644
index 22ac0fea2..000000000
--- a/apps/client/src/widgets/launch_bar/CommandButton.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-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/apps/client/src/widgets/launch_bar/GenericButtons.tsx b/apps/client/src/widgets/launch_bar/GenericButtons.tsx
new file mode 100644
index 000000000..56fe4daa7
--- /dev/null
+++ b/apps/client/src/widgets/launch_bar/GenericButtons.tsx
@@ -0,0 +1,53 @@
+import appContext, { CommandNames } from "../../components/app_context";
+import FNote from "../../entities/fnote";
+import link_context_menu from "../../menus/link_context_menu";
+import { escapeHtml, isCtrlKey } from "../../services/utils";
+import { useNoteLabel, useNoteProperty } from "../react/hooks";
+import { LaunchBarActionButton } from "./launch_bar_widgets";
+
+export function CommandButton({ launcherNote }: { launcherNote: FNote }) {
+ const [ iconClass ] = useNoteLabel(launcherNote, "iconClass");
+ const [ command ] = useNoteLabel(launcherNote, "command");
+ const title = useNoteProperty(launcherNote, "title");
+
+ return iconClass && title && command && (
+
+ )
+}
+
+export function NoteLauncher({ launcherNote, targetNoteId, hoistedNoteId }: { launcherNote: FNote, targetNoteId: string, hoistedNoteId?: string }) {
+ const [ iconClass ] = useNoteLabel(launcherNote, "iconClass");
+ const title = useNoteProperty(launcherNote, "title");
+
+ async function launch(evt: MouseEvent) {
+ if (evt.which === 3) {
+ return;
+ }
+ const hoistedNoteIdWithDefault = hoistedNoteId || launcherNote.getRelationValue("hoistedNote") || appContext.tabManager.getActiveContext()?.hoistedNoteId;
+ const ctrlKey = isCtrlKey(evt);
+
+ if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
+ const activate = evt.shiftKey ? true : false;
+ await appContext.tabManager.openInNewTab(targetNoteId, hoistedNoteIdWithDefault, activate);
+ } else {
+ await appContext.tabManager.openInSameTab(targetNoteId);
+ }
+ }
+
+ return title && iconClass && (
+ {
+ evt.preventDefault();
+ link_context_menu.openContextMenu(targetNoteId, evt);
+ }}
+ />
+ )
+}