From 647a5c948c673c3b3e9f338510b9680186bab794 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Tue, 6 May 2025 14:55:17 +0800 Subject: [PATCH 1/3] Make it show which node triggered the event when right-clicking on the tree. --- apps/client/src/menus/context_menu.ts | 25 ++++++++-------------- apps/client/src/menus/tree_context_menu.ts | 13 +++++++++-- apps/client/src/stylesheets/tree.css | 4 ++++ 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/apps/client/src/menus/context_menu.ts b/apps/client/src/menus/context_menu.ts index 004c6bc0e..06a7d487c 100644 --- a/apps/client/src/menus/context_menu.ts +++ b/apps/client/src/menus/context_menu.ts @@ -10,6 +10,7 @@ interface ContextMenuOptions { items: MenuItem[]; /** On mobile, if set to `true` then the context menu is shown near the element. If `false` (default), then the context menu is shown at the bottom of the screen. */ forcePositionOnMobile?: boolean; + onHide?: () => void; } interface MenuSeparatorItem { @@ -36,7 +37,6 @@ export type ContextMenuEvent = PointerEvent | MouseEvent | JQuery.ContextMenuEve class ContextMenu { private $widget: JQuery; private $cover: JQuery; - private dateContextMenuOpenedMs: number; private options?: ContextMenuOptions; private isMobile: boolean; @@ -44,7 +44,6 @@ class ContextMenu { this.$widget = $("#context-menu-container"); this.$cover = $("#context-menu-cover"); this.$widget.addClass("dropend"); - this.dateContextMenuOpenedMs = 0; this.isMobile = utils.isMobile(); if (this.isMobile) { @@ -76,8 +75,6 @@ class ContextMenu { keyboardActionService.updateDisplayedShortcuts(this.$widget); this.positionMenu(); - - this.dateContextMenuOpenedMs = Date.now(); } positionMenu() { @@ -220,18 +217,14 @@ class ContextMenu { } async hide() { - // this date checking comes from change in FF66 - https://github.com/zadam/trilium/issues/468 - // "contextmenu" event also triggers "click" event which depending on the timing can close the just opened context menu - // we might filter out right clicks, but then it's better if even right clicks close the context menu - if (Date.now() - this.dateContextMenuOpenedMs > 300) { - // seems like if we hide the menu immediately, some clicks can get propagated to the underlying component - // see https://github.com/zadam/trilium/pull/3805 for details - await timeout(100); - this.$widget.removeClass("show"); - this.$cover.removeClass("show"); - $("body").removeClass("context-menu-shown"); - this.$widget.hide(); - } + this.options?.onHide?.(); + // seems like if we hide the menu immediately, some clicks can get propagated to the underlying component + // see https://github.com/zadam/trilium/pull/3805 for details + await timeout(100); + this.$widget.removeClass("show"); + this.$cover.removeClass("show"); + $("body").removeClass("context-menu-shown"); + this.$widget.hide(); } } diff --git a/apps/client/src/menus/tree_context_menu.ts b/apps/client/src/menus/tree_context_menu.ts index 309b53322..887781d74 100644 --- a/apps/client/src/menus/tree_context_menu.ts +++ b/apps/client/src/menus/tree_context_menu.ts @@ -19,6 +19,8 @@ interface ConvertToAttachmentResponse { attachment?: FAttachment; } +let lastTargetNode: HTMLElement | null = null; + // This will include all commands that implement ContextMenuCommandData, but it will not work if it additional options are added via the `|` operator, // so they need to be added manually. export type TreeCommandNames = FilteredCommandNames | "openBulkActionsDialog"; @@ -33,12 +35,19 @@ export default class TreeContextMenu implements SelectMenuItemEventListener this.selectMenuItemHandler(item) + selectMenuItemHandler: (item, e) => this.selectMenuItemHandler(item), + onHide: () => { + lastTargetNode?.classList.remove('fancytree-menu-target'); + } }); + // It's placed after show to ensure the old target is cleared before showing the context menu again on repeated right-clicks. + lastTargetNode?.classList.remove('fancytree-menu-target'); + lastTargetNode = this.node.span; + lastTargetNode.classList.add('fancytree-menu-target'); } async getMenuItems(): Promise[]> { diff --git a/apps/client/src/stylesheets/tree.css b/apps/client/src/stylesheets/tree.css index b6bcff2ee..385e596dd 100644 --- a/apps/client/src/stylesheets/tree.css +++ b/apps/client/src/stylesheets/tree.css @@ -208,6 +208,10 @@ span.fancytree-node:hover { border: 1px solid var(--main-border-color); } +span.fancytree-node.fancytree-menu-target { + box-shadow: inset 0 0 0 1px var(--main-border-color); +} + .fancytree-title:hover, span.fancytree-node:hover .fancytree-title { border: 0; From 4f42be36476535c213a01e7cf832e83c512d8ac2 Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Tue, 6 May 2025 19:41:54 +0800 Subject: [PATCH 2/3] Remove delays to close the right-click menu --- apps/client/src/menus/context_menu.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/apps/client/src/menus/context_menu.ts b/apps/client/src/menus/context_menu.ts index 06a7d487c..ebcdaae91 100644 --- a/apps/client/src/menus/context_menu.ts +++ b/apps/client/src/menus/context_menu.ts @@ -183,8 +183,6 @@ class ContextMenu { return false; } - this.hide(); - if ("handler" in item && item.handler) { item.handler(item, e); } @@ -218,9 +216,6 @@ class ContextMenu { async hide() { this.options?.onHide?.(); - // seems like if we hide the menu immediately, some clicks can get propagated to the underlying component - // see https://github.com/zadam/trilium/pull/3805 for details - await timeout(100); this.$widget.removeClass("show"); this.$cover.removeClass("show"); $("body").removeClass("context-menu-shown"); @@ -228,12 +223,6 @@ class ContextMenu { } } -function timeout(ms: number) { - return new Promise((accept, reject) => { - setTimeout(accept, ms); - }); -} - const contextMenu = new ContextMenu(); export default contextMenu; From 2436838aae6f09973a2bbadb7e02b39dd519e3cd Mon Sep 17 00:00:00 2001 From: SiriusXT <1160925501@qq.com> Date: Tue, 6 May 2025 20:40:13 +0800 Subject: [PATCH 3/3] Hide the content menu on mouse up --- apps/client/src/menus/context_menu.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/client/src/menus/context_menu.ts b/apps/client/src/menus/context_menu.ts index ebcdaae91..7d0bc0a2f 100644 --- a/apps/client/src/menus/context_menu.ts +++ b/apps/client/src/menus/context_menu.ts @@ -192,6 +192,12 @@ class ContextMenu { // it's important to stop the propagation especially for sub-menus, otherwise the event // might be handled again by top-level menu return false; + }) + .on("mouseup", (e) =>{ + e.stopPropagation(); + // Hide the content menu on mouse up to prevent the mouse event from propagating to the elements below. + this.hide(); + return false; }); if ("enabled" in item && item.enabled !== undefined && !item.enabled) {