import { useLayoutEffect, useState } from "preact/hooks"; import FNote from "../../entities/fnote"; import froca from "../../services/froca"; import { isDesktop, isMobile } from "../../services/utils"; import CalendarWidget from "./CalendarWidget"; import SpacerWidget from "./SpacerWidget"; 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 { useTriliumEvent } from "../react/hooks"; import { onWheelHorizontalScroll } from "../widget_utils"; import { LaunchBarContext } from "./launch_bar_widgets"; export default function LauncherContainer({ isHorizontalLayout }: { isHorizontalLayout: boolean }) { const childNotes = useLauncherChildNotes(); return (
{childNotes?.map(childNote => { if (childNote.type !== "launcher") { throw new Error(`Note '${childNote.noteId}' '${childNote.title}' is not a launcher even though it's in the launcher subtree`); } if (!isDesktop() && childNote.isLabelTruthy("desktopOnly")) { return false; } return })}
) } function Launcher({ note, isHorizontalLayout }: { note: FNote, isHorizontalLayout: boolean }) { const launcherType = note.getLabelValue("launcherType"); if (glob.TRILIUM_SAFE_MODE && launcherType === "customWidget") return; switch (launcherType) { case "command": return ; case "note": return ; case "script": return ; case "customWidget": return ; case "builtinWidget": return initBuiltinWidget(note, isHorizontalLayout); default: throw new Error(`Unrecognized launcher type '${launcherType}' for launcher '${note.noteId}' title '${note.title}'`); } } function initBuiltinWidget(note: FNote, isHorizontalLayout: boolean) { const builtinWidget = note.getLabelValue("builtinWidget"); switch (builtinWidget) { case "calendar": return case "spacer": // || has to be inside since 0 is a valid value const baseSize = parseInt(note.getLabelValue("baseSize") || "40"); const growthFactor = parseInt(note.getLabelValue("growthFactor") || "100"); return ; case "bookmarks": return ; case "protectedSession": return ; case "syncStatus": return ; case "backInHistoryButton": return case "forwardInHistoryButton": return case "todayInJournal": return case "quickSearch": return case "aiChatLauncher": return default: throw new Error(`Unrecognized builtin widget ${builtinWidget} for launcher ${note.noteId} "${note.title}"`); } } function useLauncherChildNotes() { const [ visibleLaunchersRoot, setVisibleLaunchersRoot ] = useState(); const [ childNotes, setChildNotes ] = useState(); // Load the root note. useLayoutEffect(() => { const visibleLaunchersRootId = isMobile() ? "_lbMobileVisibleLaunchers" : "_lbVisibleLaunchers"; froca.getNote(visibleLaunchersRootId, true).then(setVisibleLaunchersRoot); }, []); // Load the children. function refresh() { if (!visibleLaunchersRoot) return; visibleLaunchersRoot.getChildNotes().then(setChildNotes); } useLayoutEffect(refresh, [ visibleLaunchersRoot ]); // React to position changes. useTriliumEvent("entitiesReloaded", ({loadResults}) => { if (loadResults.getBranchRows().find((branch) => branch.parentNoteId && froca.getNoteFromCache(branch.parentNoteId)?.isLaunchBarConfig())) { refresh(); } }); return childNotes; }