Files
Will Miao 91f955a277 fix(context-menu): keep only one context menu open at a time
The sidebar menus (folder tree, view options) and the page menus (card,
bulk selection, page-global) are independent components that only knew
how to close themselves, so right-clicking a folder left an open card
menu next to the folder menu, and right-clicking a card left the folder
menu behind.

Add a coordinator where every menu registers a closer; opening a menu
first closes all the others. BaseContextMenu takes part automatically,
the sidebar registers its two menus, and the global contextmenu handler
now uses the coordinator instead of hiding three specific menus by hand
(which also covers right-clicks outside the content area).
2026-10-31 11:27:48 +08:00

43 lines
1.4 KiB
JavaScript

/**
* Cross-menu coordination for the app's popup context menus.
*
* The page menus (model card, bulk selection, page-global) and the sidebar
* menus (folder tree, view options) are separate components, and each one only
* knew how to close itself. Right-clicking a folder while a card menu was open
* therefore left both on screen, and right-clicking a card while the folder
* menu was open left the sidebar menu behind.
*
* Every menu registers a closer here. Opening a menu first closes all the
* others, which keeps at most one context menu visible no matter which region
* of the window it was opened from.
*/
const closers = new Map();
/**
* Register (or replace) the closer of a menu element.
*
* @param {string} id Unique id of the menu element.
* @param {() => void} close Hides the menu; must be safe to call while hidden.
*/
export function registerContextMenuCloser(id, close) {
if (!id || typeof close !== 'function') return;
closers.set(id, close);
}
/**
* Hide every registered menu except `exceptId`.
*
* @param {string|null} [exceptId] The menu that is about to open, if any.
*/
export function closeContextMenus(exceptId = null) {
for (const [id, close] of closers) {
if (id === exceptId) continue;
try {
close();
} catch (error) {
console.error(`Failed to close context menu "${id}":`, error);
}
}
}