import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@components/UI/Command.js"; import { useAppStore } from "@core/stores/appStore.js"; import { useDevice, useDeviceStore } from "@core/stores/deviceStore.js"; import { Hashicon } from "@emeraldpay/hashicon-react"; import { useCommandState } from "cmdk"; import { ArrowLeftRightIcon, BoxSelectIcon, BugIcon, EraserIcon, FactoryIcon, LayersIcon, LayoutIcon, LinkIcon, LucideIcon, MapIcon, MessageSquareIcon, MoonIcon, PaletteIcon, PlusIcon, PowerIcon, QrCodeIcon, RefreshCwIcon, SettingsIcon, SmartphoneIcon, TrashIcon, UsersIcon, XCircleIcon, } from "lucide-react"; import { useEffect } from "react"; export interface Group { label: string; icon: LucideIcon; commands: Command[]; } export interface Command { label: string; icon: LucideIcon; action?: () => void; subItems?: SubItem[]; tags?: string[]; } export interface SubItem { label: string; icon: JSX.Element; action: () => void; } export const CommandPalette = (): JSX.Element => { const { commandPaletteOpen, setCommandPaletteOpen, setSelectedDevice, removeDevice, selectedDevice, darkMode, setDarkMode, setAccent, } = useAppStore(); const { getDevices } = useDeviceStore(); const { setDialogOpen, setActivePage, connection } = useDevice(); const groups: Group[] = [ { label: "Goto", icon: LinkIcon, commands: [ { label: "Messages", icon: MessageSquareIcon, action() { setActivePage("messages"); }, }, { label: "Map", icon: MapIcon, action() { setActivePage("map"); }, }, { label: "Config", icon: SettingsIcon, action() { setActivePage("config"); }, tags: ["settings"], }, { label: "Channels", icon: LayersIcon, action() { setActivePage("channels"); }, }, { label: "Nodes", icon: UsersIcon, action() { setActivePage("nodes"); }, }, ], }, { label: "Manage", icon: SmartphoneIcon, commands: [ { label: "Switch Node", icon: ArrowLeftRightIcon, subItems: getDevices().map((device) => { return { label: device.nodes.get(device.hardware.myNodeNum)?.user?.longName ?? device.hardware.myNodeNum.toString(), icon: ( ), action() { setSelectedDevice(device.id); }, }; }), }, { label: "Connect New Node", icon: PlusIcon, action() { setSelectedDevice(0); }, }, ], }, { label: "Contextual", icon: BoxSelectIcon, commands: [ { label: "QR Code", icon: QrCodeIcon, subItems: [ { label: "Generator", icon: , action() { setDialogOpen("QR", true); }, }, { label: "Import", icon: , action() { setDialogOpen("import", true); }, }, ], }, { label: "Disconnect", icon: XCircleIcon, action() { void connection?.disconnect(); setSelectedDevice(0); removeDevice(selectedDevice ?? 0); }, }, { label: "Schedule Shutdown", icon: PowerIcon, action() { setDialogOpen("shutdown", true); }, }, { label: "Schedule Reboot", icon: RefreshCwIcon, action() { setDialogOpen("reboot", true); }, }, { label: "Reset Nodes", icon: TrashIcon, action() { connection?.resetNodes(); }, }, { label: "Factory Reset", icon: FactoryIcon, action() { connection?.factoryReset(); }, }, ], }, { label: "Debug", icon: BugIcon, commands: [ { label: "Reconfigure", icon: RefreshCwIcon, action() { void connection?.configure(); }, }, { label: "[WIP] Clear Messages", icon: EraserIcon, action() { alert("This feature is not implemented"); }, }, ], }, { label: "Application", icon: LayoutIcon, commands: [ { label: "Toggle Dark Mode", icon: MoonIcon, action() { setDarkMode(!darkMode); }, }, { label: "Accent Color", icon: PaletteIcon, subItems: [ { label: "Red", icon: ( ), action() { setAccent("red"); }, }, { label: "Orange", icon: ( ), action() { setAccent("orange"); }, }, { label: "Yellow", icon: ( ), action() { setAccent("yellow"); }, }, { label: "Green", icon: ( ), action() { setAccent("green"); }, }, { label: "Blue", icon: ( ), action() { setAccent("blue"); }, }, { label: "Purple", icon: ( ), action() { setAccent("purple"); }, }, { label: "Pink", icon: ( ), action() { setAccent("pink"); }, }, ], }, ], }, ]; useEffect(() => { const handleKeydown = (e: KeyboardEvent) => { if (e.key === "k" && (e.metaKey || e.ctrlKey)) { e.preventDefault(); setCommandPaletteOpen(true); } }; window.addEventListener("keydown", handleKeydown); return () => window.removeEventListener("keydown", handleKeydown); }, []); return ( No results found. {groups.map((group) => ( {group.commands.map((command) => ( { command.action?.(); setCommandPaletteOpen(false); }} > {command.label} {command.subItems?.map((subItem) => ( ))} ))} ))} ); }; const SubItem = ({ label, icon, action, }: { label: string; icon: React.ReactNode; action: () => void; }) => { const search = useCommandState((state) => state.search); if (!search) return null; return ( {icon} {label} ); };