// The tray menu panels' host calls (the panel page's counterpart of src/api.ts, kept apart so the panel bundle stays // small). Only `menu-*` windows may call these (capabilities/menu.json; every command re-checks the window in Rust). import { invoke } from '@tauri-apps/api/core'; import { listen } from '@tauri-apps/api/event'; import type { MenuNode, PanelInfo } from './model'; import type { MenuBridge } from './TrayMenu'; export const inTauri = (): boolean => typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window; const call = (cmd: string, args?: Record) => { invoke(cmd, args).catch(() => {}); }; function sub(ev: string, fn: (p: T) => void): () => void { const un = listen(ev, e => fn(e.payload)); return () => { un.then(f => f()).catch(() => {}); }; } /** This panel: its path into the tree, pinned or not, and the tree now. */ export const menuState = (): Promise => invoke('menu_state').catch(() => null); /** Every change of the tree (a store read, mute, language): the panel updates in place. */ export const onModel = (fn: (nodes: MenuNode[]) => void) => sub('menu-model', fn); /** Rust about this panel: `pinned`, `unpinned`, `focus`. */ export const onPanel = (fn: (word: string) => void) => sub('menu-panel', fn); export const bridge: MenuBridge = { ready: (width, height) => call('menu_ready', { width, height }), openSub: (key, top, focus) => call('menu_open_sub', { key, top, focus }), pinSub: (key, top) => call('menu_pin_sub', { key, top }), closeSubs: () => call('menu_close_subs'), close: refocusParent => call('menu_close', { refocusParent }), dismiss: () => call('menu_dismiss'), pin: pinned => call('menu_pin', { pinned }), select: id => call('menu_select', { id }), };