diff --git a/src/public/app/menus/context_menu.js b/src/public/app/menus/context_menu.js index 093803d5c..073d9639f 100644 --- a/src/public/app/menus/context_menu.js +++ b/src/public/app/menus/context_menu.js @@ -3,6 +3,7 @@ import keyboardActionService from '../services/keyboard_actions.js'; class ContextMenu { constructor() { this.$widget = $("#context-menu-container"); + this.$widget.addClass("dropend"); this.dateContextMenuOpenedMs = 0; $(document).on('click', () => this.hide()); @@ -11,6 +12,12 @@ class ContextMenu { async show(options) { this.options = options; + if (this.$widget.hasClass("show")) { + // The menu is already visible. Hide the menu then open it again + // at the new location to re-trigger the opening animation. + await this.hide(); + } + this.$widget.empty(); this.addItems(this.$widget, options.items); @@ -142,18 +149,26 @@ class ContextMenu { } } - hide() { + 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 - setTimeout(() => this.$widget.hide(), 100); + await timeout(100); + this.$widget.removeClass("show"); + this.$widget.hide() } } } +function timeout(ms) { + return new Promise((accept, reject) => { + setTimeout(accept, ms); + }); +} + const contextMenu = new ContextMenu(); export default contextMenu; diff --git a/src/public/app/menus/image_context_menu.js b/src/public/app/menus/image_context_menu.js index d45e35f62..6da436324 100644 --- a/src/public/app/menus/image_context_menu.js +++ b/src/public/app/menus/image_context_menu.js @@ -20,9 +20,13 @@ function setupContextMenu($image) { { title: "Copy reference to clipboard", command: "copyImageReferenceToClipboard", - uiIcon: "bx bx-empty" + uiIcon: "bx bx-directions" + }, + { + title: "Copy image to clipboard", + command: "copyImageToClipboard", + uiIcon: "bx bx-copy" }, - { title: "Copy image to clipboard", command: "copyImageToClipboard", uiIcon: "bx bx-empty" }, ], selectMenuItemHandler: async ({ command }) => { if (command === 'copyImageReferenceToClipboard') { diff --git a/src/public/app/menus/launcher_context_menu.js b/src/public/app/menus/launcher_context_menu.js index b7c722dae..b2fa40df8 100644 --- a/src/public/app/menus/launcher_context_menu.js +++ b/src/public/app/menus/launcher_context_menu.js @@ -37,18 +37,22 @@ export default class LauncherContextMenu { const canBeReset = !canBeDeleted && note.isLaunchBarConfig(); return [ - (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-note-launcher"), command: 'addNoteLauncher', uiIcon: "bx bx-plus" } : null, - (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-script-launcher"), command: 'addScriptLauncher', uiIcon: "bx bx-plus" } : null, - (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-custom-widget"), command: 'addWidgetLauncher', uiIcon: "bx bx-plus" } : null, - (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-spacer"), command: 'addSpacerLauncher', uiIcon: "bx bx-plus" } : null, + (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-note-launcher"), command: 'addNoteLauncher', uiIcon: "bx bx-note" } : null, + (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-script-launcher"), command: 'addScriptLauncher', uiIcon: "bx bx-code-curly" } : null, + (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-custom-widget"), command: 'addWidgetLauncher', uiIcon: "bx bx-customize" } : null, + (isVisibleRoot || isAvailableRoot) ? { title: t("launcher_context_menu.add-spacer"), command: 'addSpacerLauncher', uiIcon: "bx bx-dots-horizontal" } : null, (isVisibleRoot || isAvailableRoot) ? { title: "----" } : null, - { title: `${t("launcher_context_menu.delete")} `, command: "deleteNotes", uiIcon: "bx bx-trash", enabled: canBeDeleted }, - { title: t("launcher_context_menu.reset"), command: "resetLauncher", uiIcon: "bx bx-empty", enabled: canBeReset}, - { title: "----" }, + isAvailableItem ? { title: t("launcher_context_menu.move-to-visible-launchers"), command: "moveLauncherToVisible", uiIcon: "bx bx-show", enabled: true } : null, isVisibleItem ? { title: t("launcher_context_menu.move-to-available-launchers"), command: "moveLauncherToAvailable", uiIcon: "bx bx-hide", enabled: true } : null, - { title: `${t("launcher_context_menu.duplicate-launcher")} `, command: "duplicateSubtree", uiIcon: "bx bx-empty", - enabled: isItem } + (isVisibleItem || isAvailableItem) ? { title: "----" } : null, + + { title: `${t("launcher_context_menu.duplicate-launcher")} `, command: "duplicateSubtree", uiIcon: "bx bx-outline", enabled: isItem }, + { title: `${t("launcher_context_menu.delete")} `, command: "deleteNotes", uiIcon: "bx bx-trash destructive-action-icon", enabled: canBeDeleted }, + + { title: "----" }, + + { title: t("launcher_context_menu.reset"), command: "resetLauncher", uiIcon: "bx bx-reset destructive-action-icon", enabled: canBeReset} ].filter(row => row !== null); } diff --git a/src/public/app/menus/link_context_menu.js b/src/public/app/menus/link_context_menu.js index cd9c47043..8070e4020 100644 --- a/src/public/app/menus/link_context_menu.js +++ b/src/public/app/menus/link_context_menu.js @@ -6,7 +6,7 @@ function openContextMenu(notePath, e, viewScope = {}, hoistedNoteId = null) { x: e.pageX, y: e.pageY, items: [ - {title: "Open note in a new tab", command: "openNoteInNewTab", uiIcon: "bx bx-empty"}, + {title: "Open note in a new tab", command: "openNoteInNewTab", uiIcon: "bx bx-link-external"}, {title: "Open note in a new split", command: "openNoteInNewSplit", uiIcon: "bx bx-dock-right"}, {title: "Open note in a new window", command: "openNoteInNewWindow", uiIcon: "bx bx-window-open"} ], diff --git a/src/public/app/menus/tree_context_menu.js b/src/public/app/menus/tree_context_menu.js index 7609c99f5..33d1314a8 100644 --- a/src/public/app/menus/tree_context_menu.js +++ b/src/public/app/menus/tree_context_menu.js @@ -49,56 +49,98 @@ export default class TreeContextMenu { const insertNoteAfterEnabled = isNotRoot && !isHoisted && parentNotSearch; return [ - { title: `${t("tree-context-menu.open-in-a-new-tab")} Ctrl+Click`, command: "openInTab", uiIcon: "bx bx-empty", enabled: noSelectedNotes }, + { title: `${t("tree-context-menu.open-in-a-new-tab")} Ctrl+Click`, command: "openInTab", uiIcon: "bx bx-link-external", enabled: noSelectedNotes }, + { title: t("tree-context-menu.open-in-a-new-split"), command: "openNoteInSplit", uiIcon: "bx bx-dock-right", enabled: noSelectedNotes }, - { title: `${t("tree-context-menu.insert-note-after")} `, command: "insertNoteAfter", uiIcon: "bx bx-plus", + + isHoisted ? null : { title: `${t("tree-context-menu.hoist-note")} `, command: "toggleNoteHoisting", uiIcon: "bx bxs-chevrons-up", enabled: noSelectedNotes && notSearch }, + !isHoisted || !isNotRoot ? null : { title: `${t("tree-context-menu.unhoist-note")} `, command: "toggleNoteHoisting", uiIcon: "bx bx-door-open" }, + + + { title: "----" }, + + + { title: `${t("tree-context-menu.insert-note-after")}`, command: "insertNoteAfter", uiIcon: "bx bx-plus", items: insertNoteAfterEnabled ? await noteTypesService.getNoteTypeItems("insertNoteAfter") : null, enabled: insertNoteAfterEnabled && noSelectedNotes && notOptions }, - { title: `${t("tree-context-menu.insert-child-note")} `, command: "insertChildNote", uiIcon: "bx bx-plus", + + { title: `${t("tree-context-menu.insert-child-note")}`, command: "insertChildNote", uiIcon: "bx bx-plus", items: notSearch ? await noteTypesService.getNoteTypeItems("insertChildNote") : null, enabled: notSearch && noSelectedNotes && notOptions }, - { title: `${t("tree-context-menu.delete")} `, command: "deleteNotes", uiIcon: "bx bx-trash", - enabled: isNotRoot && !isHoisted && parentNotSearch && notOptions }, - { title: "----" }, - { title: `${t("tree-context-menu.search-in-subtree")} `, command: "searchInSubtree", uiIcon: "bx bx-search", - enabled: notSearch && noSelectedNotes }, - isHoisted ? null : { title: `${t("tree-context-menu.hoist-note")} `, command: "toggleNoteHoisting", uiIcon: "bx bx-empty", enabled: noSelectedNotes && notSearch }, - !isHoisted || !isNotRoot ? null : { title: `${t("tree-context-menu.unhoist-note")} `, command: "toggleNoteHoisting", uiIcon: "bx bx-door-open" }, - { title: `${t("tree-context-menu.edit-branch-prefix")} `, command: "editBranchPrefix", uiIcon: "bx bx-empty", - enabled: isNotRoot && parentNotSearch && noSelectedNotes && notOptions }, - { title: t("tree-context-menu.advanced"), uiIcon: "bx bx-empty", enabled: true, items: [ - { title: `${t("tree-context-menu.expand-subtree")} `, command: "expandSubtree", uiIcon: "bx bx-expand", enabled: noSelectedNotes }, - { title: `${t("tree-context-menu.collapse-subtree")} `, command: "collapseSubtree", uiIcon: "bx bx-collapse", enabled: noSelectedNotes }, - { title: `${t("tree-context-menu.sort-by")} `, command: "sortChildNotes", uiIcon: "bx bx-empty", enabled: noSelectedNotes && notSearch }, - { title: t("tree-context-menu.recent-changes-in-subtree"), command: "recentChangesInSubtree", uiIcon: "bx bx-history", enabled: noSelectedNotes && notOptions }, - { title: t("tree-context-menu.convert-to-attachment"), command: "convertNoteToAttachment", uiIcon: "bx bx-empty", enabled: isNotRoot && !isHoisted && notOptions }, - { title: t("tree-context-menu.copy-note-path-to-clipboard"), command: "copyNotePathToClipboard", uiIcon: "bx bx-empty", enabled: true } - ] }, + + { title: "----" }, + + { title: t("tree-context-menu.protect-subtree"), command: "protectSubtree", uiIcon: "bx bx-check-shield", enabled: noSelectedNotes }, + { title: t("tree-context-menu.unprotect-subtree"), command: "unprotectSubtree", uiIcon: "bx bx-shield", enabled: noSelectedNotes }, + + { title: "----" }, - { title: `${t("tree-context-menu.copy-clone")} `, command: "copyNotesToClipboard", uiIcon: "bx bx-copy", - enabled: isNotRoot && !isHoisted }, - { title: `${t("tree-context-menu.clone-to")} `, command: "cloneNotesTo", uiIcon: "bx bx-empty", - enabled: isNotRoot && !isHoisted }, + + + { title: t("tree-context-menu.advanced"), uiIcon: "bx bxs-wrench", enabled: true, items: [ + { title: t("tree-context-menu.apply-bulk-actions"), command: "openBulkActionsDialog", uiIcon: "bx bx-list-plus", enabled: true }, + + { title: "----" }, + + { title: `${t("tree-context-menu.edit-branch-prefix")} `, command: "editBranchPrefix", uiIcon: "bx bx-rename", enabled: isNotRoot && parentNotSearch && noSelectedNotes && notOptions }, + { title: t("tree-context-menu.convert-to-attachment"), command: "convertNoteToAttachment", uiIcon: "bx bx-paperclip", enabled: isNotRoot && !isHoisted && notOptions }, + { title: `${t("tree-context-menu.duplicate-subtree")} `, command: "duplicateSubtree", uiIcon: "bx bx-outline", enabled: parentNotSearch && isNotRoot && !isHoisted && notOptions }, + + { title: "----" }, + + { title: `${t("tree-context-menu.expand-subtree")} `, command: "expandSubtree", uiIcon: "bx bx-expand", enabled: noSelectedNotes }, + { title: `${t("tree-context-menu.collapse-subtree")} `, command: "collapseSubtree", uiIcon: "bx bx-collapse", enabled: noSelectedNotes }, + { title: `${t("tree-context-menu.sort-by")} `, command: "sortChildNotes", uiIcon: "bx bx-sort-down", enabled: noSelectedNotes && notSearch }, + + { title: "----" }, + + { title: t("tree-context-menu.copy-note-path-to-clipboard"), command: "copyNotePathToClipboard", uiIcon: "bx bx-directions", enabled: true }, + { title: t("tree-context-menu.recent-changes-in-subtree"), command: "recentChangesInSubtree", uiIcon: "bx bx-history", enabled: noSelectedNotes && notOptions }, + ] }, + + + { title: "----" }, + + { title: `${t("tree-context-menu.cut")} `, command: "cutNotesToClipboard", uiIcon: "bx bx-cut", enabled: isNotRoot && !isHoisted && parentNotSearch }, - { title: `${t("tree-context-menu.move-to")} `, command: "moveNotesTo", uiIcon: "bx bx-empty", - enabled: isNotRoot && !isHoisted && parentNotSearch }, + + { title: `${t("tree-context-menu.copy-clone")} `, command: "copyNotesToClipboard", uiIcon: "bx bx-copy", + enabled: isNotRoot && !isHoisted }, + { title: `${t("tree-context-menu.paste-into")} `, command: "pasteNotesFromClipboard", uiIcon: "bx bx-paste", enabled: !clipboard.isClipboardEmpty() && notSearch && noSelectedNotes }, + { title: t("tree-context-menu.paste-after"), command: "pasteNotesAfterFromClipboard", uiIcon: "bx bx-paste", enabled: !clipboard.isClipboardEmpty() && isNotRoot && !isHoisted && parentNotSearch && noSelectedNotes }, - { title: `${t("tree-context-menu.duplicate-subtree")} `, command: "duplicateSubtree", uiIcon: "bx bx-empty", - enabled: parentNotSearch && isNotRoot && !isHoisted && notOptions }, + + { title: `${t("tree-context-menu.move-to")} `, command: "moveNotesTo", uiIcon: "bx bx-transfer", + enabled: isNotRoot && !isHoisted && parentNotSearch }, + + { title: `${t("tree-context-menu.clone-to")} `, command: "cloneNotesTo", uiIcon: "bx bx-duplicate", + enabled: isNotRoot && !isHoisted }, + + { title: `${t("tree-context-menu.delete")} `, command: "deleteNotes", uiIcon: "bx bx-trash destructive-action-icon", + enabled: isNotRoot && !isHoisted && parentNotSearch && notOptions }, + { title: "----" }, - { title: t("tree-context-menu.export"), command: "exportNote", uiIcon: "bx bx-empty", + + { title: t("tree-context-menu.import-into-note"), command: "importIntoNote", uiIcon: "bx bx-import", enabled: notSearch && noSelectedNotes && notOptions }, - { title: t("tree-context-menu.import-into-note"), command: "importIntoNote", uiIcon: "bx bx-empty", + + { title: t("tree-context-menu.export"), command: "exportNote", uiIcon: "bx bx-export", enabled: notSearch && noSelectedNotes && notOptions }, - { title: t("tree-context-menu.apply-bulk-actions"), command: "openBulkActionsDialog", uiIcon: "bx bx-list-plus", - enabled: true } + + + { title: "----" }, + + + { title: `${t("tree-context-menu.search-in-subtree")} `, command: "searchInSubtree", uiIcon: "bx bx-search", + enabled: notSearch && noSelectedNotes }, + ].filter(row => row !== null); } diff --git a/src/public/app/widgets/buttons/attachments_actions.js b/src/public/app/widgets/buttons/attachments_actions.js index 1580753c0..b4a15daba 100644 --- a/src/public/app/widgets/buttons/attachments_actions.js +++ b/src/public/app/widgets/buttons/attachments_actions.js @@ -39,22 +39,39 @@ const TPL = ` style="position: relative; top: 3px;"> @@ -96,14 +113,14 @@ export default class AttachmentActionsWidget extends BasicWidget { const $openAttachmentButton = this.$widget.find("[data-trigger-command='openAttachment']"); $openAttachmentButton .addClass("disabled") - .append($(' (?)') + .append($('') .attr("title", t('attachments_actions.open_externally_detail_page')) ); if (isElectron) { const $openAttachmentCustomButton = this.$widget.find("[data-trigger-command='openAttachmentCustom']"); $openAttachmentCustomButton .addClass("disabled") - .append($(' (?)') + .append($('') .attr("title", t('attachments_actions.open_externally_detail_page')) ); } @@ -112,7 +129,7 @@ export default class AttachmentActionsWidget extends BasicWidget { const $openAttachmentCustomButton = this.$widget.find("[data-trigger-command='openAttachmentCustom']"); $openAttachmentCustomButton .addClass("disabled") - .append($(' (?)') + .append($('') .attr("title", t('attachments_actions.open_custom_client_only')) ); } diff --git a/src/public/app/widgets/buttons/global_menu.js b/src/public/app/widgets/buttons/global_menu.js index d760ecd5c..597d82ac4 100644 --- a/src/public/app/widgets/buttons/global_menu.js +++ b/src/public/app/widgets/buttons/global_menu.js @@ -100,6 +100,8 @@ const TPL = ` position: relative; left: 0; top: 5px; + --dropdown-shadow-opacity: 0; + --submenu-opening-delay: 0; } @@ -125,27 +127,17 @@ const TPL = `