chore(react/launch_bar): port today launcher

This commit is contained in:
Elian Doran 2025-12-04 16:52:38 +02:00
parent 0d6bcba023
commit 54f70c8158
No known key found for this signature in database
3 changed files with 41 additions and 28 deletions

View File

@ -1,15 +0,0 @@
import NoteLauncher from "./note_launcher.js";
import dateNotesService from "../../../services/date_notes.js";
import appContext from "../../../components/app_context.js";
export default class TodayLauncher extends NoteLauncher {
async getTargetNoteId() {
const todayNote = await dateNotesService.getTodayNote();
return todayNote?.noteId;
}
getHoistedNoteId() {
return appContext.tabManager.getActiveContext()?.hoistedNoteId;
}
}

View File

@ -3,7 +3,6 @@ import SyncStatusWidget from "../sync_status.js";
import BasicWidget, { wrapReactWidgets } from "../basic_widget.js";
import ScriptLauncher from "../buttons/launcher/script_launcher.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 BookmarkButtons from "../launch_bar/BookmarkButtons.jsx";
@ -12,7 +11,8 @@ 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, NoteLauncher } from "../launch_bar/GenericButtons.jsx";
import { CommandButton, CustomNoteLauncher, NoteLauncher } from "../launch_bar/GenericButtons.jsx";
import date_notes from "../../services/date_notes.js";
interface InnerWidget extends BasicWidget {
settings?: {
@ -113,7 +113,7 @@ export default class LauncherWidget extends BasicWidget {
case "forwardInHistoryButton":
return <HistoryNavigationButton launcherNote={note} command="forwardInNoteHistory" />
case "todayInJournal":
return new TodayLauncher(note);
return <TodayLauncher launcherNote={note} />
case "quickSearch":
return new QuickSearchLauncherWidget(this.isHorizontalLayout);
case "aiChatLauncher":
@ -123,3 +123,15 @@ export default class LauncherWidget extends BasicWidget {
}
}
}
function TodayLauncher({ launcherNote }: { launcherNote: FNote }) {
return (
<CustomNoteLauncher
launcherNote={launcherNote}
getTargetNoteId={async () => {
const todayNote = await date_notes.getTodayNote();
return todayNote?.noteId ?? null;
}}
/>
);
}

View File

@ -2,7 +2,7 @@ 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, useNoteRelation } from "../react/hooks";
import { useNoteLabel } from "../react/hooks";
import { LaunchBarActionButton, useLauncherIconAndTitle } from "./launch_bar_widgets";
import dialog from "../../services/dialog";
import { t } from "../../services/i18n";
@ -20,7 +20,11 @@ export function CommandButton({ launcherNote }: { launcherNote: FNote }) {
)
}
export function CustomNoteLauncher({ launcherNote, targetNoteId, hoistedNoteId }: { launcherNote: FNote, targetNoteId: string | null, hoistedNoteId?: string }) {
export function CustomNoteLauncher({ launcherNote, getTargetNoteId, getHoistedNoteId }: {
launcherNote: FNote,
getTargetNoteId: (launcherNote: FNote) => string | null | Promise<string | null>,
getHoistedNoteId?: (launcherNote: FNote) => string | null
}) {
const { icon, title } = useLauncherIconAndTitle(launcherNote);
async function launch(evt: MouseEvent) {
@ -28,12 +32,10 @@ export function CustomNoteLauncher({ launcherNote, targetNoteId, hoistedNoteId }
return;
}
if (!targetNoteId) {
dialog.info(t("note_launcher.this_launcher_doesnt_define_target_note"));
return;
}
const targetNoteId = await getTargetNoteId(launcherNote);
if (!targetNoteId) return;
const hoistedNoteIdWithDefault = hoistedNoteId || launcherNote.getRelationValue("hoistedNote") || appContext.tabManager.getActiveContext()?.hoistedNoteId;
const hoistedNoteIdWithDefault = getHoistedNoteId?.(launcherNote) || appContext.tabManager.getActiveContext()?.hoistedNoteId;
const ctrlKey = isCtrlKey(evt);
if ((evt.which === 1 && ctrlKey) || evt.which === 2) {
@ -50,8 +52,9 @@ export function CustomNoteLauncher({ launcherNote, targetNoteId, hoistedNoteId }
text={escapeHtml(title)}
onClick={launch}
onAuxClick={launch}
onContextMenu={evt => {
onContextMenu={async evt => {
evt.preventDefault();
const targetNoteId = await getTargetNoteId(launcherNote);
if (targetNoteId) {
link_context_menu.openContextMenu(targetNoteId, evt);
}
@ -68,6 +71,19 @@ export function CustomNoteLauncher({ launcherNote, targetNoteId, hoistedNoteId }
// The only downside is more work in setting up the typical case
// where you actually want to have both title and icon in sync, but for those cases there are bookmarks
export function NoteLauncher({ launcherNote, ...restProps }: { launcherNote: FNote, hoistedNoteId?: string }) {
const [ targetNote ] = useNoteRelation(launcherNote, "target");
return <CustomNoteLauncher launcherNote={launcherNote} targetNoteId={targetNote ?? null} {...restProps} />
return (
<CustomNoteLauncher
launcherNote={launcherNote}
getTargetNoteId={(launcherNote) => {
const targetNoteId = launcherNote.getRelationValue("target");
if (!targetNoteId) {
dialog.info(t("note_launcher.this_launcher_doesnt_define_target_note"));
return null;
}
return targetNoteId;
}}
getHoistedNoteId={launcherNote => launcherNote.getRelationValue("hoistedNote")}
{...restProps}
/>
);
}