chore(react/launch_bar): address requested changes

This commit is contained in:
Elian Doran 2025-12-05 22:57:07 +02:00
parent 31561879b3
commit a205108681
No known key found for this signature in database
11 changed files with 50 additions and 35 deletions

View File

@ -20,7 +20,7 @@ export default function BookmarkButtons() {
return (
<div style={style}>
{childNotes?.map(childNote => <SingleBookmark note={childNote} />)}
{childNotes?.map(childNote => <SingleBookmark key={childNote.noteId} note={childNote} />)}
</div>
)
}
@ -48,8 +48,8 @@ function BookmarkFolder({ note }: { note: FNote }) {
<ul className="children-notes">
{childNotes.map(childNote => (
<li>
<NoteLink key={childNote.noteId} notePath={childNote.noteId} noPreview showNoteIcon containerClassName="note-link" noTnLink />
<li key={childNote.noteId}>
<NoteLink notePath={childNote.noteId} noPreview showNoteIcon containerClassName="note-link" noTnLink />
</li>
))}
</ul>

View File

@ -35,11 +35,10 @@ export interface CalendarArgs {
}
export default function Calendar(args: CalendarArgs) {
const [ rawFirstDayOfWeek ] = useTriliumOptionInt("firstDayOfWeek") ?? 0;
const [ rawFirstDayOfWeek ] = useTriliumOptionInt("firstDayOfWeek");
const firstDayOfWeekISO = (rawFirstDayOfWeek === 0 ? 7 : rawFirstDayOfWeek);
const date = args.date;
const month = date.format('YYYY-MM');
const firstDay = date.startOf('month');
const firstDayISO = firstDay.isoWeekday();
const monthInfo = getMonthInformation(date, firstDayISO, firstDayOfWeekISO);

View File

@ -1,4 +1,4 @@
import { Dispatch, StateUpdater, useEffect, useMemo, useRef, useState } from "preact/hooks";
import { Dispatch, StateUpdater, useMemo, useRef, useState } from "preact/hooks";
import FNote from "../../entities/fnote";
import { LaunchBarDropdownButton, LauncherNoteProps, useLauncherIconAndTitle } from "./launch_bar_widgets";
import { Dayjs, dayjs } from "@triliumnext/commons";
@ -59,7 +59,7 @@ export default function CalendarWidget({ launcherNote }: LauncherNoteProps) {
return (
<LaunchBarDropdownButton
icon={icon} title={title}
onShown={() => {
onShown={async () => {
const dateNote = appContext.tabManager.getActiveContextNote()?.getOwnedLabelValue("dateNote");
const activeDate = dateNote ? dayjs(`${dateNote}T12:00:00`) : null
const todaysDate = dayjs();
@ -68,7 +68,11 @@ export default function CalendarWidget({ launcherNote }: LauncherNoteProps) {
todaysDate,
});
setDate(dayjs(activeDate || todaysDate).startOf('month'));
checkEnableWeekNotes();
try {
await checkEnableWeekNotes();
} catch (e: unknown) {
// Non-critical.
}
}}
dropdownRef={dropdownRef}
dropdownOptions={{

View File

@ -12,6 +12,8 @@ interface HistoryNavigationProps {
command: "backInNoteHistory" | "forwardInNoteHistory";
}
const HISTORY_LIMIT = 20;
export default function HistoryNavigationButton({ launcherNote, command }: HistoryNavigationProps) {
const { icon, title } = useLauncherIconAndTitle(launcherNote);
const webContentsRef = useRef<WebContents>(null);
@ -63,8 +65,8 @@ export default function HistoryNavigationButton({ launcherNote, command }: Histo
items.reverse();
if (items.length > 20) {
items = items.slice(0, 50);
if (items.length > HISTORY_LIMIT) {
items = items.slice(0, HISTORY_LIMIT);
}
contextMenu.show({

View File

@ -1,4 +1,4 @@
import { useLayoutEffect, useState } from "preact/hooks";
import { useCallback, useLayoutEffect, useState } from "preact/hooks";
import FNote from "../../entities/fnote";
import froca from "../../services/froca";
import { isDesktop, isMobile } from "../../services/utils";
@ -8,7 +8,7 @@ import BookmarkButtons from "./BookmarkButtons";
import ProtectedSessionStatusWidget from "./ProtectedSessionStatusWidget";
import SyncStatus from "./SyncStatus";
import HistoryNavigationButton from "./HistoryNavigation";
import AiChatButton, { CommandButton, CustomWidget, NoteLauncher, QuickSearchLauncherWidget, ScriptLauncher, TodayLauncher } from "./LauncherDefinitions";
import { AiChatButton, CommandButton, CustomWidget, NoteLauncher, QuickSearchLauncherWidget, ScriptLauncher, TodayLauncher } from "./LauncherDefinitions";
import { useTriliumEvent } from "../react/hooks";
import { onWheelHorizontalScroll } from "../widget_utils";
import { LaunchBarContext } from "./launch_bar_widgets";
@ -111,10 +111,10 @@ function useLauncherChildNotes() {
}, []);
// Load the children.
function refresh() {
const refresh = useCallback(() => {
if (!visibleLaunchersRoot) return;
visibleLaunchersRoot.getChildNotes().then(setChildNotes);
}
}, [ visibleLaunchersRoot, setChildNotes ]);
useLayoutEffect(refresh, [ visibleLaunchersRoot ]);
// React to position changes.

View File

@ -1,16 +1,17 @@
import { useCallback, useContext, useEffect, useMemo, useState } from "preact/hooks";
import { useGlobalShortcut, useLegacyWidget, useNoteContext, useNoteLabel, useNoteRelationTarget, useTriliumOptionBool } from "../react/hooks";
import { useGlobalShortcut, useLegacyWidget, useNoteLabel, useNoteRelationTarget, useTriliumOptionBool } from "../react/hooks";
import { ParentComponent } from "../react/react_utils";
import BasicWidget from "../basic_widget";
import FNote from "../../entities/fnote";
import QuickSearchWidget from "../quick_search";
import { isMobile } from "../../services/utils";
import { getErrorMessage, isMobile } from "../../services/utils";
import date_notes from "../../services/date_notes";
import { CustomNoteLauncher } from "./GenericButtons";
import { LaunchBarActionButton, LaunchBarContext, LauncherNoteProps, useLauncherIconAndTitle } from "./launch_bar_widgets";
import dialog from "../../services/dialog";
import { t } from "../../services/i18n";
import appContext, { CommandNames } from "../../components/app_context";
import toast from "../../services/toast";
export function CommandButton({ launcherNote }: LauncherNoteProps) {
const { icon, title } = useLauncherIconAndTitle(launcherNote);
@ -77,7 +78,7 @@ export function ScriptLauncher({ launcherNote }: LauncherNoteProps) {
)
}
export default function AiChatButton({ launcherNote }: LauncherNoteProps) {
export function AiChatButton({ launcherNote }: LauncherNoteProps) {
const [ aiEnabled ] = useTriliumOptionBool("aiEnabled");
const { icon, title } = useLauncherIconAndTitle(launcherNote);
@ -123,12 +124,24 @@ export function CustomWidget({ launcherNote }: LauncherNoteProps) {
parentComponent?.contentSized();
useEffect(() => {
widgetNote?.executeScript().then(widget => {
if (widget instanceof BasicWidget) {
(async function() {
let widget: BasicWidget;
try {
widget = await widgetNote?.executeScript();
} catch (e) {
toast.showError(t("toast.bundle-error.message", {
id: widgetNote?.noteId,
title: widgetNote?.title,
message: getErrorMessage(e)
}));
return;
}
if (widgetNote && widget instanceof BasicWidget) {
widget._noteId = widgetNote.noteId;
}
setWidget(widget);
});
})();
}, [ widgetNote ]);
return (

View File

@ -1,3 +0,0 @@
export default function RightDropdownButton() {
return <p>Button goes here.</p>;
}

View File

@ -88,7 +88,7 @@ function useSyncStatus() {
// First, read last synced push.
if ("lastSyncedPush" in message) {
lastSyncedPush = message.lastSyncedPush;
} else if ("data" in message && message.data && "lastSyncedPush" in message.data && lastSyncedPush) {
} else if ("data" in message && message.data && "lastSyncedPush" in message.data && lastSyncedPush !== undefined) {
lastSyncedPush = message.data.lastSyncedPush;
}

View File

@ -67,7 +67,7 @@ export default function Dropdown({ id, className, buttonClassName, isStatic, chi
resizeObserver.disconnect();
dropdown.dispose();
}
}, [ triggerRef, dropdownContainerRef ]);
}, []);
const onShown = useCallback(() => {
setShown(true);
@ -101,7 +101,7 @@ export default function Dropdown({ id, className, buttonClassName, isStatic, chi
$dropdown.off("show.bs.dropdown", onShown);
$dropdown.off("hide.bs.dropdown", onHidden);
};
}, []); // Add dependency array
}, [ onShown, onHidden ]);
const ariaId = useUniqueName("button");

View File

@ -72,6 +72,5 @@ export default function NoteLink({ className, containerClassName, notePath, show
$linkEl?.addClass(className);
}
return <span className={containerClassName} ref={ref} />
return <span className={containerClassName} ref={ref} />;
}

View File

@ -813,7 +813,7 @@ export function useKeyboardShortcuts(scope: "code-detail" | "text-detail", conta
}
/**
* Register a global shortcut. Internally it uses the shortcut service and assignes a random namespace to make it unique.
* Register a global shortcut. Internally it uses the shortcut service and assigns a random namespace to make it unique.
*
* @param keyboardShortcut the keyboard shortcut combination to register.
* @param handler the corresponding handler to be called when the keyboard shortcut is invoked by the user.
@ -877,12 +877,13 @@ async function isNoteReadOnly(note: FNote, noteContext: NoteContext) {
export function useChildNotes(parentNoteId: string) {
const [ childNotes, setChildNotes ] = useState<FNote[]>([]);
async function refreshChildNotes() {
useEffect(() => {
(async function() {
const parentNote = await froca.getNote(parentNoteId);
const childNotes = await parentNote?.getChildNotes();
setChildNotes(childNotes ?? []);
}
useEffect(() => { refreshChildNotes() }, [ parentNoteId ]);
})();
}, [ parentNoteId ]);
return childNotes;
}