diff --git a/app/src/menus/navigation.ts b/app/src/menus/navigation.ts index 25fc4dd27..01fcce446 100644 --- a/app/src/menus/navigation.ts +++ b/app/src/menus/navigation.ts @@ -11,7 +11,6 @@ import {fetchPost, fetchSyncPost} from "../util/fetch"; import {onGetnotebookconf} from "./onGetnotebookconf"; /// #if !MOBILE import {openSearch} from "../search/spread"; -import {openFileById} from "../editor/util"; /// #else import {closePanel} from "../mobile/util/closePanel"; import {popSearch} from "../mobile/menu/search"; @@ -22,11 +21,11 @@ import {hasClosestByTag} from "../protyle/util/hasClosest"; import {deleteFiles} from "../editor/deleteFile"; import {getDockByType} from "../layout/util"; import {Files} from "../layout/dock/Files"; -import {openNewWindowById} from "../window/openNewWindow"; import {openCardByData} from "../card/openCard"; import {viewCards} from "../card/viewCards"; import {App} from "../index"; import {openDocHistory} from "../history/doc"; +import {openEditorTab} from "./util"; const initMultiMenu = (selectItemElements: NodeListOf) => { const fileItemElement = Array.from(selectItemElements).find(item => { @@ -473,68 +472,7 @@ export const initFileMenu = (app: App, notebookId: string, pathString: string, l }).element); window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element); } - /// #if !MOBILE - const openSubmenus: IMenu[] = [{ - icon: "iconLayoutRight", - label: window.siyuan.languages.insertRight, - accelerator: "⌥Click", - click: () => { - openFileById({app, id, position: "right", action: [Constants.CB_GET_FOCUS]}); - } - }, { - icon: "iconLayoutBottom", - label: window.siyuan.languages.insertBottom, - accelerator: "⇧Click", - click: () => { - openFileById({app, id, position: "bottom", action: [Constants.CB_GET_FOCUS]}); - } - }]; - if (window.siyuan.config.fileTree.openFilesUseCurrentTab) { - openSubmenus.push({ - label: window.siyuan.languages.openInNewTab, - accelerator: "⌥⌘Click", - click: () => { - openFileById({ - app, - id, action: [Constants.CB_GET_FOCUS], - removeCurrentTab: false - }); - } - }); - } - /// #if !BROWSER - openSubmenus.push({ - label: window.siyuan.languages.openByNewWindow, - icon: "iconOpenWindow", - click() { - openNewWindowById(id); - } - }); - /// #endif - openSubmenus.push({type: "separator"}); - openSubmenus.push({ - icon: "iconPreview", - label: window.siyuan.languages.preview, - click: () => { - openFileById({app, id, mode: "preview"}); - } - }); - /// #if !BROWSER - openSubmenus.push({type: "separator"}); - if (!window.siyuan.config.readonly) { - openSubmenus.push({ - label: window.siyuan.languages.showInFolder, - click: () => { - shell.showItemInFolder(path.join(window.siyuan.config.system.dataDir, notebookId, pathString)); - } - }); - } - /// #endif - window.siyuan.menus.menu.append(new MenuItem({ - label: window.siyuan.languages.openBy, - submenu: openSubmenus, - }).element); - /// #endif + openEditorTab(app, id, notebookId, pathString) if (!window.siyuan.config.readonly) { window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.fileHistory, diff --git a/app/src/menus/util.ts b/app/src/menus/util.ts index 5eb7e0dee..df4aab300 100644 --- a/app/src/menus/util.ts +++ b/app/src/menus/util.ts @@ -1,9 +1,16 @@ /// #if !BROWSER import {dialog} from "@electron/remote"; import {SaveDialogReturnValue} from "electron"; +import {shell} from "electron"; +import * as path from "path"; /// #endif import {fetchPost} from "../util/fetch"; import {getAssetName, pathPosix} from "../util/pathName"; +import {openFileById} from "../editor/util"; +import {Constants} from "../constants"; +import {openNewWindowById} from "../window/openNewWindow"; +import {MenuItem} from "./Menu"; +import {App} from "../index"; export const exportAsset = (src: string) => { /// #if !BROWSER @@ -23,3 +30,75 @@ export const exportAsset = (src: string) => { }; /// #endif }; + + +export const openEditorTab = (app: App, id: string, notebookId?: string, pathString?: string) => { + /// #if !MOBILE + const openSubmenus: IMenu[] = [{ + icon: "iconLayoutRight", + label: window.siyuan.languages.insertRight, + accelerator: "⌥Click", + click: () => { + openFileById({app, id, position: "right", action: [Constants.CB_GET_FOCUS]}); + } + }, { + icon: "iconLayoutBottom", + label: window.siyuan.languages.insertBottom, + accelerator: "⇧Click", + click: () => { + openFileById({app, id, position: "bottom", action: [Constants.CB_GET_FOCUS]}); + } + }]; + if (window.siyuan.config.fileTree.openFilesUseCurrentTab) { + openSubmenus.push({ + label: window.siyuan.languages.openInNewTab, + accelerator: "⌥⌘Click", + click: () => { + openFileById({ + app, + id, action: [Constants.CB_GET_FOCUS], + removeCurrentTab: false + }); + } + }); + } + /// #if !BROWSER + openSubmenus.push({ + label: window.siyuan.languages.openByNewWindow, + icon: "iconOpenWindow", + click() { + openNewWindowById(id); + } + }); + /// #endif + openSubmenus.push({type: "separator"}); + openSubmenus.push({ + icon: "iconPreview", + label: window.siyuan.languages.preview, + click: () => { + openFileById({app, id, mode: "preview"}); + } + }); + /// #if !BROWSER + openSubmenus.push({type: "separator"}); + if (!window.siyuan.config.readonly) { + openSubmenus.push({ + label: window.siyuan.languages.showInFolder, + click: () => { + if (notebookId) { + shell.showItemInFolder(path.join(window.siyuan.config.system.dataDir, notebookId, pathString)); + } else { + fetchPost("/api/block/getBlockInfo", {id}, (response) => { + shell.showItemInFolder(path.join(window.siyuan.config.system.dataDir, response.data.box, response.data.path)); + }); + } + } + }); + } + /// #endif + window.siyuan.menus.menu.append(new MenuItem({ + label: window.siyuan.languages.openBy, + submenu: openSubmenus, + }).element); + /// #endif +}; diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts index 27f0a5bc1..e995c0d84 100644 --- a/app/src/protyle/render/av/action.ts +++ b/app/src/protyle/render/av/action.ts @@ -2,6 +2,8 @@ import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "../ import {transaction} from "../../wysiwyg/transaction"; import {Menu} from "../../../plugin/API"; import {getIconByType} from "./render"; +import {openEditorTab} from "../../../menus/util"; +import {copySubMenu} from "../../../menus/commonMenuItem"; export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLElement }) => { const blockElement = hasClosestBlock(event.target); @@ -136,40 +138,77 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle return false; }; - export const avContextmenu = (protyle: IProtyle, event: MouseEvent & { detail: any }, target: HTMLElement) => { const rowElement = hasClosestByClassName(target, "av__row"); - if (rowElement) { - const menu = new Menu("av-row"); - menu.addItem({ - icon: "iconCopy", - label: window.siyuan.languages.duplicate, - click() { - - } - }); - menu.addItem({ - icon: "iconTrashcan", - label: window.siyuan.languages.delete, - click() { - - } - }); - menu.addSeparator(); - menu.addItem({ - icon: "iconTrashcan", - label: window.siyuan.languages.open, - click() { - - } - }); - menu.open({ - x: event.clientX, - y: event.clientY, - }); - event.preventDefault(); - event.stopPropagation(); - return true; + if (!rowElement) { + return false; } - return false + const blockElement = hasClosestBlock(rowElement); + if (!blockElement) { + return false; + } + const rowId = rowElement.getAttribute("data-id"); + const menu = new Menu("av-row"); + menu.addItem({ + icon: "iconCopy", + label: window.siyuan.languages.duplicate, + click() { + + } + }); + menu.addItem({ + icon: "iconTrashcan", + label: window.siyuan.languages.delete, + click() { + transaction(protyle, [{ + action: "removeAttrViewBlock", + id: blockElement.getAttribute("data-node-id"), + parentID: blockElement.getAttribute("data-av-id"), + }], [{ + action: "insertAttrViewBlock", + id: blockElement.getAttribute("data-node-id"), + parentID: blockElement.getAttribute("data-av-id"), + previousID: rowElement.previousElementSibling?.getAttribute("data-id") || "", + srcIDs: [rowId], + }]); + } + }); + menu.addSeparator(); + openEditorTab(protyle.app, rowId); + menu.addItem({ + label: window.siyuan.languages.copy, + icon: "iconCopy", + type: "submenu", + submenu: copySubMenu(rowId) + }); + menu.addSeparator(); + menu.addItem({ + icon: "iconEdit", + label: window.siyuan.languages.edit, + click() { + + } + }) + const editAttrSubmenu: IMenu[] = [] + rowElement.parentElement.querySelectorAll(".av__row--header .av__cell").forEach((cellElement) => { + editAttrSubmenu.push({ + icon: getIconByType(cellElement.getAttribute("data-dtype") as TAVCol), + label: cellElement.textContent.trim(), + click() { + } + }) + }); + menu.addItem({ + icon: "iconList", + label: window.siyuan.languages.attr, + type: "submenu", + submenu: editAttrSubmenu + }) + menu.open({ + x: event.clientX, + y: event.clientY, + }); + event.preventDefault(); + event.stopPropagation(); + return true; } diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts index e59c0cc87..6168cb112 100644 --- a/app/src/protyle/util/editorCommonEvent.ts +++ b/app/src/protyle/util/editorCommonEvent.ts @@ -811,7 +811,7 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { }], [{ action: "removeAttrViewBlock", id: targetElement.getAttribute("data-node-id"), - parentID: targetElement.getAttribute("data-av-type"), + parentID: targetElement.getAttribute("data-av-id"), }]); } return;