2026-04-11 10:39:08 +02:00
|
|
|
import type { MutableRefObject } from 'react'
|
|
|
|
|
import type { SidebarFilter } from '../types'
|
2026-04-11 12:59:11 +02:00
|
|
|
import {
|
|
|
|
|
APP_COMMAND_DEFINITIONS,
|
|
|
|
|
type AppCommandId,
|
|
|
|
|
type AppCommandDefinition,
|
|
|
|
|
} from './appCommandCatalog'
|
2026-04-11 10:39:08 +02:00
|
|
|
import type { ViewMode } from './useViewMode'
|
|
|
|
|
|
|
|
|
|
export const APP_COMMAND_EVENT_NAME = 'laputa:dispatch-command'
|
|
|
|
|
|
2026-04-11 12:59:11 +02:00
|
|
|
export {
|
|
|
|
|
APP_COMMAND_IDS,
|
|
|
|
|
findShortcutCommandId,
|
|
|
|
|
findShortcutCommandIdForEvent,
|
|
|
|
|
isAppCommandId,
|
|
|
|
|
isNativeMenuCommandId,
|
|
|
|
|
isNativeMenuShortcutCommand,
|
|
|
|
|
} from './appCommandCatalog'
|
|
|
|
|
export type { AppCommandDefinition, AppCommandId, AppCommandShortcutCombo } from './appCommandCatalog'
|
2026-04-11 10:39:08 +02:00
|
|
|
|
|
|
|
|
export interface AppCommandHandlers {
|
|
|
|
|
onSetViewMode: (mode: ViewMode) => void
|
|
|
|
|
onCreateNote: () => void
|
|
|
|
|
onCreateType?: () => void
|
|
|
|
|
onOpenDailyNote: () => void
|
|
|
|
|
onQuickOpen: () => void
|
|
|
|
|
onSave: () => void
|
|
|
|
|
onOpenSettings: () => void
|
|
|
|
|
onToggleInspector: () => void
|
|
|
|
|
onCommandPalette: () => void
|
|
|
|
|
onZoomIn: () => void
|
|
|
|
|
onZoomOut: () => void
|
|
|
|
|
onZoomReset: () => void
|
|
|
|
|
onToggleOrganized?: (path: string) => void
|
|
|
|
|
onToggleFavorite?: (path: string) => void
|
|
|
|
|
onArchiveNote: (path: string) => void
|
|
|
|
|
onDeleteNote: (path: string) => void
|
|
|
|
|
onSearch: () => void
|
|
|
|
|
onToggleRawEditor?: () => void
|
|
|
|
|
onToggleDiff?: () => void
|
|
|
|
|
onToggleAIChat?: () => void
|
|
|
|
|
onGoBack?: () => void
|
|
|
|
|
onGoForward?: () => void
|
|
|
|
|
onCheckForUpdates?: () => void
|
|
|
|
|
onSelectFilter?: (filter: SidebarFilter) => void
|
|
|
|
|
onOpenVault?: () => void
|
|
|
|
|
onRemoveActiveVault?: () => void
|
|
|
|
|
onRestoreGettingStarted?: () => void
|
|
|
|
|
onCommitPush?: () => void
|
|
|
|
|
onPull?: () => void
|
|
|
|
|
onResolveConflicts?: () => void
|
|
|
|
|
onViewChanges?: () => void
|
|
|
|
|
onInstallMcp?: () => void
|
|
|
|
|
onOpenInNewWindow?: () => void
|
|
|
|
|
onReloadVault?: () => void
|
|
|
|
|
onRepairVault?: () => void
|
|
|
|
|
onRestoreDeletedNote?: () => void
|
|
|
|
|
activeTabPathRef: MutableRefObject<string | null>
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 12:59:11 +02:00
|
|
|
type SimpleHandlerKey = keyof Pick<
|
|
|
|
|
AppCommandHandlers,
|
|
|
|
|
| 'onOpenSettings'
|
|
|
|
|
| 'onCheckForUpdates'
|
|
|
|
|
| 'onCreateNote'
|
|
|
|
|
| 'onCreateType'
|
|
|
|
|
| 'onOpenDailyNote'
|
|
|
|
|
| 'onQuickOpen'
|
|
|
|
|
| 'onSave'
|
|
|
|
|
| 'onSearch'
|
|
|
|
|
| 'onToggleRawEditor'
|
|
|
|
|
| 'onToggleDiff'
|
|
|
|
|
| 'onToggleInspector'
|
|
|
|
|
| 'onToggleAIChat'
|
|
|
|
|
| 'onCommandPalette'
|
|
|
|
|
| 'onZoomIn'
|
|
|
|
|
| 'onZoomOut'
|
|
|
|
|
| 'onZoomReset'
|
|
|
|
|
| 'onGoBack'
|
|
|
|
|
| 'onGoForward'
|
|
|
|
|
| 'onOpenVault'
|
|
|
|
|
| 'onRemoveActiveVault'
|
|
|
|
|
| 'onRestoreGettingStarted'
|
|
|
|
|
| 'onCommitPush'
|
|
|
|
|
| 'onPull'
|
|
|
|
|
| 'onResolveConflicts'
|
|
|
|
|
| 'onViewChanges'
|
|
|
|
|
| 'onInstallMcp'
|
|
|
|
|
| 'onReloadVault'
|
|
|
|
|
| 'onRepairVault'
|
|
|
|
|
| 'onOpenInNewWindow'
|
|
|
|
|
| 'onRestoreDeletedNote'
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
type ActiveTabHandlerKey = keyof Pick<
|
|
|
|
|
AppCommandHandlers,
|
|
|
|
|
'onToggleOrganized' | 'onToggleFavorite' | 'onArchiveNote' | 'onDeleteNote'
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
const SIMPLE_HANDLER_EXECUTORS: Record<SimpleHandlerKey, (handlers: AppCommandHandlers) => void> = {
|
|
|
|
|
onOpenSettings: (handlers) => handlers.onOpenSettings(),
|
|
|
|
|
onCheckForUpdates: (handlers) => handlers.onCheckForUpdates?.(),
|
|
|
|
|
onCreateNote: (handlers) => handlers.onCreateNote(),
|
|
|
|
|
onCreateType: (handlers) => handlers.onCreateType?.(),
|
|
|
|
|
onOpenDailyNote: (handlers) => handlers.onOpenDailyNote(),
|
|
|
|
|
onQuickOpen: (handlers) => handlers.onQuickOpen(),
|
|
|
|
|
onSave: (handlers) => handlers.onSave(),
|
|
|
|
|
onSearch: (handlers) => handlers.onSearch(),
|
|
|
|
|
onToggleRawEditor: (handlers) => handlers.onToggleRawEditor?.(),
|
|
|
|
|
onToggleDiff: (handlers) => handlers.onToggleDiff?.(),
|
|
|
|
|
onToggleInspector: (handlers) => handlers.onToggleInspector(),
|
|
|
|
|
onToggleAIChat: (handlers) => handlers.onToggleAIChat?.(),
|
|
|
|
|
onCommandPalette: (handlers) => handlers.onCommandPalette(),
|
|
|
|
|
onZoomIn: (handlers) => handlers.onZoomIn(),
|
|
|
|
|
onZoomOut: (handlers) => handlers.onZoomOut(),
|
|
|
|
|
onZoomReset: (handlers) => handlers.onZoomReset(),
|
|
|
|
|
onGoBack: (handlers) => handlers.onGoBack?.(),
|
|
|
|
|
onGoForward: (handlers) => handlers.onGoForward?.(),
|
|
|
|
|
onOpenVault: (handlers) => handlers.onOpenVault?.(),
|
|
|
|
|
onRemoveActiveVault: (handlers) => handlers.onRemoveActiveVault?.(),
|
|
|
|
|
onRestoreGettingStarted: (handlers) => handlers.onRestoreGettingStarted?.(),
|
|
|
|
|
onCommitPush: (handlers) => handlers.onCommitPush?.(),
|
|
|
|
|
onPull: (handlers) => handlers.onPull?.(),
|
|
|
|
|
onResolveConflicts: (handlers) => handlers.onResolveConflicts?.(),
|
|
|
|
|
onViewChanges: (handlers) => handlers.onViewChanges?.(),
|
|
|
|
|
onInstallMcp: (handlers) => handlers.onInstallMcp?.(),
|
|
|
|
|
onReloadVault: (handlers) => handlers.onReloadVault?.(),
|
|
|
|
|
onRepairVault: (handlers) => handlers.onRepairVault?.(),
|
|
|
|
|
onOpenInNewWindow: (handlers) => handlers.onOpenInNewWindow?.(),
|
|
|
|
|
onRestoreDeletedNote: (handlers) => handlers.onRestoreDeletedNote?.(),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ACTIVE_TAB_HANDLER_EXECUTORS: Record<ActiveTabHandlerKey, (handlers: AppCommandHandlers, path: string) => void> = {
|
|
|
|
|
onToggleOrganized: (handlers, path) => handlers.onToggleOrganized?.(path),
|
|
|
|
|
onToggleFavorite: (handlers, path) => handlers.onToggleFavorite?.(path),
|
|
|
|
|
onArchiveNote: (handlers, path) => handlers.onArchiveNote(path),
|
|
|
|
|
onDeleteNote: (handlers, path) => handlers.onDeleteNote(path),
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 10:39:08 +02:00
|
|
|
function dispatchActiveTabCommand(
|
|
|
|
|
pathRef: MutableRefObject<string | null>,
|
2026-04-11 12:59:11 +02:00
|
|
|
handler: (path: string) => void,
|
2026-04-11 10:39:08 +02:00
|
|
|
): boolean {
|
|
|
|
|
const path = pathRef.current
|
|
|
|
|
if (!path) return false
|
2026-04-11 12:59:11 +02:00
|
|
|
handler(path)
|
2026-04-11 10:39:08 +02:00
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 12:59:11 +02:00
|
|
|
function dispatchDefinition(
|
|
|
|
|
definition: AppCommandDefinition,
|
|
|
|
|
handlers: AppCommandHandlers,
|
|
|
|
|
): boolean {
|
|
|
|
|
switch (definition.route.kind) {
|
|
|
|
|
case 'view-mode':
|
|
|
|
|
handlers.onSetViewMode(definition.route.value)
|
2026-04-11 10:39:08 +02:00
|
|
|
return true
|
2026-04-11 12:59:11 +02:00
|
|
|
case 'filter':
|
|
|
|
|
handlers.onSelectFilter?.(definition.route.value)
|
2026-04-11 10:39:08 +02:00
|
|
|
return true
|
2026-04-11 12:59:11 +02:00
|
|
|
case 'handler':
|
|
|
|
|
SIMPLE_HANDLER_EXECUTORS[definition.route.handler as SimpleHandlerKey](handlers)
|
2026-04-11 10:39:08 +02:00
|
|
|
return true
|
2026-04-11 12:59:11 +02:00
|
|
|
case 'active-tab-handler':
|
|
|
|
|
return dispatchActiveTabCommand(
|
|
|
|
|
handlers.activeTabPathRef,
|
|
|
|
|
(path) => ACTIVE_TAB_HANDLER_EXECUTORS[definition.route.handler as ActiveTabHandlerKey](handlers, path),
|
|
|
|
|
)
|
2026-04-11 10:39:08 +02:00
|
|
|
}
|
2026-04-11 12:59:11 +02:00
|
|
|
}
|
2026-04-11 10:44:45 +02:00
|
|
|
|
2026-04-11 12:59:11 +02:00
|
|
|
export function dispatchAppCommand(id: AppCommandId, handlers: AppCommandHandlers): boolean {
|
|
|
|
|
return dispatchDefinition(APP_COMMAND_DEFINITIONS[id], handlers)
|
2026-04-11 10:39:08 +02:00
|
|
|
}
|