import { ApplicationMenu, type ApplicationMenuItemConfig } from "electrobun/bun"; import type { SavedConnection } from "../shared/types"; import type { ConnectionStore } from "./store/connections"; /** * macOS application menu (electrobun menus are macOS-only). Standard roles plus * app actions; custom actions are forwarded to the webview as menuAction * messages. Rebuilt whenever saved connections change so the Connect submenu * stays current. */ export async function applyApplicationMenu(store: ConnectionStore): Promise { if (process.platform !== "darwin") return; const { stacks, connections } = await store.load(); const item = (c: SavedConnection): ApplicationMenuItemConfig => ({ label: c.name, action: `connect:${c.id}`, }); const looseItems = connections.filter((c) => !c.stackId).map(item); const stackMenus: ApplicationMenuItemConfig[] = stacks.map((stack) => ({ label: stack.name, submenu: connections.filter((c) => c.stackId === stack.id).map(item), })); const connectSubmenu: ApplicationMenuItemConfig[] = [ ...looseItems, ...stackMenus, ...(looseItems.length || stackMenus.length ? [{ type: "separator" } as const] : []), { label: "Connection Manager…", action: "manage-connections" }, ]; ApplicationMenu.setApplicationMenu([ { submenu: [ { role: "hide" }, { role: "hideOthers" }, { role: "showAll" }, { type: "separator" }, { label: "Quit", role: "quit" }, ], }, { label: "File", submenu: [ { label: "New Tab", action: "new-tab", accelerator: "t" }, { label: "Close Tab", action: "close-tab", accelerator: "w" }, { type: "separator" }, { label: "New Folder", action: "new-folder" }, { label: "New File", action: "new-file" }, { type: "separator" }, { label: "Edit File", action: "edit-file", accelerator: "e" }, { type: "separator" }, { label: "Connect", submenu: connectSubmenu }, ], }, { label: "Edit", submenu: [ { role: "undo" }, { role: "redo" }, { type: "separator" }, { role: "cut" }, { role: "copy" }, { role: "paste" }, { role: "pasteAndMatchStyle" }, { role: "delete" }, { role: "selectAll" }, ], }, { label: "View", submenu: [ { label: "Refresh", action: "refresh-active", accelerator: "r" }, { type: "separator" }, { role: "toggleFullScreen" }, ], }, { label: "Window", submenu: [ { role: "minimize" }, { role: "zoom" }, { type: "separator" }, { role: "cycleThroughWindows" }, { role: "bringAllToFront" }, ], }, ]); console.log(`[menu] applied (${connections.length} connections)`); }