Pārlūkot izejas kodu

:art: https://github.com/siyuan-note/siyuan/issues/13128

Vanessa 7 mēneši atpakaļ
vecāks
revīzija
c0b68b1e5e

+ 59 - 15
app/src/boot/globalEvent/keydown.ts

@@ -72,6 +72,7 @@ import {setReadOnly} from "../../config/util/setReadOnly";
 import {copyPNGByLink} from "../../menus/util";
 import {globalCommand} from "./command/global";
 import {duplicateCompletely} from "../../protyle/render/av/action";
+import {copyTextByType} from "../../protyle/toolbar/util";
 
 const switchDialogEvent = (app: App, event: MouseEvent) => {
     event.preventDefault();
@@ -487,7 +488,7 @@ const editKeydown = (app: App, event: KeyboardEvent) => {
         event.preventDefault();
         return true;
     }
-    if (matchHotKey(window.siyuan.config.keymap.editor.general.copyBlockRef.custom, event)) {
+    if (!isFileFocus && matchHotKey(window.siyuan.config.keymap.editor.general.copyBlockRef.custom, event)) {
         event.preventDefault();
         event.stopPropagation();
         if (hasClosestByClassName(range.startContainer, "protyle-title")) {
@@ -592,6 +593,12 @@ const fileTreeKeydown = (app: App, event: KeyboardEvent) => {
     const notebookId = topULElement.getAttribute("data-url");
     const pathString = liElements[0].getAttribute("data-path");
     const isFile = liElements[0].getAttribute("data-type") === "navigation-file";
+    const ids: string[] = [];
+    liElements.forEach(item => {
+        if (item.getAttribute("data-type") === "navigation-file") {
+            ids.push(item.getAttribute("data-node-id"));
+        }
+    })
 
     if (matchHotKey(window.siyuan.config.keymap.editor.general.spaceRepetition.custom, event) && !window.siyuan.config.readonly) {
         if (isFile) {
@@ -604,25 +611,20 @@ const fileTreeKeydown = (app: App, event: KeyboardEvent) => {
                 openCardByData(app, response.data, "notebook", notebookId, getNotebookName(notebookId));
             });
         }
+        event.preventDefault();
+        return true;
     }
 
     if (matchHotKey(window.siyuan.config.keymap.editor.general.quickMakeCard.custom, event)) {
-        const blockIDs: string[] = [];
-        liElements.forEach(item => {
-            const id = item.getAttribute("data-node-id");
-            if (id) {
-                blockIDs.push(id);
-            }
-        });
-        if (blockIDs.length > 0) {
+        if (ids.length > 0) {
             transaction(undefined, [{
                 action: "addFlashcards",
                 deckID: Constants.QUICK_DECK_ID,
-                blockIDs,
+                blockIDs: ids,
             }], [{
                 action: "removeFlashcards",
                 deckID: Constants.QUICK_DECK_ID,
-                blockIDs,
+                blockIDs: ids,
             }]);
         }
         event.preventDefault();
@@ -664,12 +666,54 @@ const fileTreeKeydown = (app: App, event: KeyboardEvent) => {
         return true;
     }
 
-    if (isFile && !event.repeat && matchHotKey(window.siyuan.config.keymap.editor.general.duplicate.custom, event)) {
+    if (!event.repeat && matchHotKey(window.siyuan.config.keymap.editor.general.duplicate.custom, event)) {
         event.preventDefault();
         event.stopPropagation();
-        fetchPost("/api/filetree/duplicateDoc", {
-            id: liElements[0].getAttribute("data-node-id"),
-        });
+        ids.forEach(item => {
+            fetchPost("/api/filetree/duplicateDoc", {
+                id: item,
+            });
+        })
+        return true;
+    }
+
+    if (!event.repeat && matchHotKey(window.siyuan.config.keymap.editor.general.copyBlockRef.custom, event)) {
+        event.preventDefault();
+        event.stopPropagation();
+        copyTextByType(ids, "ref");
+        return true;
+    }
+
+    if (!event.repeat && matchHotKey(window.siyuan.config.keymap.editor.general.copyBlockEmbed.custom, event)) {
+        event.preventDefault();
+        event.stopPropagation();
+        copyTextByType(ids, "blockEmbed");
+        return true;
+    }
+
+    if (!event.repeat && matchHotKey(window.siyuan.config.keymap.editor.general.copyProtocol.custom, event)) {
+        event.preventDefault();
+        event.stopPropagation();
+        copyTextByType(ids, "protocol");
+        return true;
+    }
+
+    if (!event.repeat && matchHotKey(window.siyuan.config.keymap.editor.general.copyProtocolInMd.custom, event)) {
+        event.preventDefault();
+        event.stopPropagation();
+        copyTextByType(ids, "protocolMd");
+        return true;
+    }
+    if (!event.repeat && matchHotKey(window.siyuan.config.keymap.editor.general.copyHPath.custom, event)) {
+        event.preventDefault();
+        event.stopPropagation();
+        copyTextByType(ids, "hPath");
+        return true;
+    }
+    if (!event.repeat && matchHotKey(window.siyuan.config.keymap.editor.general.copyID.custom, event)) {
+        event.preventDefault();
+        event.stopPropagation();
+        copyTextByType(ids, "id");
         return true;
     }
 

+ 12 - 77
app/src/menus/commonMenuItem.ts

@@ -22,6 +22,7 @@ import {App} from "../index";
 import {renderAVAttribute} from "../protyle/render/av/blockAttr";
 import {openAssetNewWindow} from "../window/openNewWindow";
 import {escapeHtml} from "../util/escape";
+import {copyTextByType} from "../protyle/toolbar/util";
 
 const bindAttrInput = (inputElement: HTMLInputElement, id: string) => {
     inputElement.addEventListener("change", () => {
@@ -377,21 +378,8 @@ export const copySubMenu = (ids: string[], accelerator = true, focusElement?: El
         iconHTML: "",
         accelerator: accelerator ? window.siyuan.config.keymap.editor.general.copyBlockRef.custom : undefined,
         label: window.siyuan.languages.copyBlockRef,
-        click: async () => {
-            let text = "";
-            for (let i = 0; i < ids.length; i++) {
-                const id = ids[i];
-                const response = await fetchSyncPost("/api/block/getRefText", {id});
-                const content = `((${id} '${response.data}'))`;
-                if (ids.length > 1) {
-                    text += "* ";
-                }
-                text += content;
-                if (ids.length > 1 && i !== ids.length - 1) {
-                    text += "\n";
-                }
-            }
-            writeText(text);
+        click: () => {
+            copyTextByType(ids, "ref");
             if (focusElement) {
                 focusBlock(focusElement);
             }
@@ -402,17 +390,7 @@ export const copySubMenu = (ids: string[], accelerator = true, focusElement?: El
         label: window.siyuan.languages.copyBlockEmbed,
         accelerator: accelerator ? window.siyuan.config.keymap.editor.general.copyBlockEmbed.custom : undefined,
         click: () => {
-            let text = "";
-            ids.forEach((id, index) => {
-                if (ids.length > 1) {
-                    text += "* ";
-                }
-                text += `{{select * from blocks where id='${id}'}}`;
-                if (ids.length > 1 && index !== ids.length - 1) {
-                    text += "\n";
-                }
-            });
-            writeText(text);
+            copyTextByType(ids, "blockEmbed");
             if (focusElement) {
                 focusBlock(focusElement);
             }
@@ -423,17 +401,7 @@ export const copySubMenu = (ids: string[], accelerator = true, focusElement?: El
         label: window.siyuan.languages.copyProtocol,
         accelerator: accelerator ? window.siyuan.config.keymap.editor.general.copyProtocol.custom : undefined,
         click: () => {
-            let text = "";
-            ids.forEach((id, index) => {
-                if (ids.length > 1) {
-                    text += "* ";
-                }
-                text += `siyuan://blocks/${id}`;
-                if (ids.length > 1 && index !== ids.length - 1) {
-                    text += "\n";
-                }
-            });
-            writeText(text);
+            copyTextByType(ids, "protocol");
             if (focusElement) {
                 focusBlock(focusElement);
             }
@@ -443,21 +411,8 @@ export const copySubMenu = (ids: string[], accelerator = true, focusElement?: El
         iconHTML: "",
         label: window.siyuan.languages.copyProtocolInMd,
         accelerator: accelerator ? window.siyuan.config.keymap.editor.general.copyProtocolInMd.custom : undefined,
-        click: async () => {
-            let text = "";
-            for (let i = 0; i < ids.length; i++) {
-                const id = ids[i];
-                const response = await fetchSyncPost("/api/block/getRefText", {id});
-                const content = `[${response.data}](siyuan://blocks/${id})`;
-                if (ids.length > 1) {
-                    text += "* ";
-                }
-                text += content;
-                if (ids.length > 1 && i !== ids.length - 1) {
-                    text += "\n";
-                }
-            }
-            writeText(text);
+        click: () => {
+            copyTextByType(ids, "protocolMd");
             if (focusElement) {
                 focusBlock(focusElement);
             }
@@ -467,21 +422,11 @@ export const copySubMenu = (ids: string[], accelerator = true, focusElement?: El
         iconHTML: "",
         label: window.siyuan.languages.copyHPath,
         accelerator: accelerator ? window.siyuan.config.keymap.editor.general.copyHPath.custom : undefined,
-        click: async () => {
-            let text = "";
-            for (let i = 0; i < ids.length; i++) {
-                const id = ids[i];
-                const response = await fetchSyncPost("/api/filetree/getHPathByID", {id});
-                const content = response.data;
-                if (ids.length > 1) {
-                    text += "* ";
-                }
-                text += content;
-                if (ids.length > 1 && i !== ids.length - 1) {
-                    text += "\n";
-                }
+        click:  () => {
+            copyTextByType(ids, "hPath");
+            if (focusElement) {
+                focusBlock(focusElement);
             }
-            writeText(text);
         }
     }, {
         id: "copyID",
@@ -489,17 +434,7 @@ export const copySubMenu = (ids: string[], accelerator = true, focusElement?: El
         label: window.siyuan.languages.copyID,
         accelerator: accelerator ? window.siyuan.config.keymap.editor.general.copyID.custom : undefined,
         click: () => {
-            let text = "";
-            ids.forEach((id, index) => {
-                if (ids.length > 1) {
-                    text += "* ";
-                }
-                text += id;
-                if (ids.length > 1 && index !== ids.length - 1) {
-                    text += "\n";
-                }
-            });
-            writeText(text);
+            copyTextByType(ids, "id");
             if (focusElement) {
                 focusBlock(focusElement);
             }

+ 3 - 1
app/src/menus/index.ts

@@ -1,5 +1,5 @@
 /// #if !MOBILE
-import {getInstanceById} from "../layout/util";
+import {getInstanceById, setPanelFocus} from "../layout/util";
 import {Tab} from "../layout/Tab";
 import {initSearchMenu} from "./search";
 import {initDockMenu} from "./dock";
@@ -68,6 +68,7 @@ export class Menus {
                     this.unselect();
                     // navigation 根上:新建文档/文件夹/取消挂在/打开文件位置
                     initNavigationMenu(app, target).popup({x: event.clientX, y: event.clientY});
+                    setPanelFocus(hasClosestByClassName(target, "sy__file") as HTMLElement);
                     event.stopPropagation();
                     break;
                 } else if (dataType === "navigation-file") {
@@ -77,6 +78,7 @@ export class Menus {
                         x: event.clientX,
                         y: event.clientY
                     });
+                    setPanelFocus(hasClosestByClassName(target, "sy__file") as HTMLElement);
                     event.stopPropagation();
                     break;
                 } else if (dataType === "search-item") {

+ 14 - 2
app/src/menus/navigation.ts

@@ -54,7 +54,19 @@ const initMultiMenu = (selectItemElements: NodeListOf<Element>, app: App) => {
             label: window.siyuan.languages.copy,
             type: "submenu",
             icon: "iconCopy",
-            submenu: copySubMenu(blockIDs, false)
+            submenu: copySubMenu(blockIDs).concat([{
+                id: "duplicate",
+                iconHTML: "",
+                label: window.siyuan.languages.duplicate,
+                accelerator: window.siyuan.config.keymap.editor.general.duplicate.custom,
+                click() {
+                    blockIDs.forEach((id) => {
+                        fetchPost("/api/filetree/duplicateDoc", {
+                            id
+                        });
+                    });
+                }
+            }])
         }).element);
     }
 
@@ -481,7 +493,7 @@ export const initFileMenu = (app: App, notebookId: string, pathString: string, l
             label: window.siyuan.languages.copy,
             type: "submenu",
             icon: "iconCopy",
-            submenu: (copySubMenu([id], false) as IMenu[]).concat([{
+            submenu: (copySubMenu([id]) as IMenu[]).concat([{
                 id: "duplicate",
                 iconHTML: "",
                 label: window.siyuan.languages.duplicate,

+ 33 - 1
app/src/protyle/toolbar/util.ts

@@ -1,6 +1,7 @@
-import {fetchPost} from "../../util/fetch";
+import {fetchPost, fetchSyncPost} from "../../util/fetch";
 import {Constants} from "../../constants";
 import {focusByRange, focusByWbr} from "../util/selection";
+import {writeText} from "../util/compatibility";
 
 export const previewTemplate = (pathString: string, element: Element, parentId: string) => {
     if (!pathString) {
@@ -213,3 +214,34 @@ export const toolbarKeyToMenu = (toolbar: Array<string | IMenuItem>) => {
     });
     return toolbarResult;
 };
+
+export const copyTextByType = async (ids: string[],
+                                     type: "ref" | "blockEmbed" | "protocol" | "protocolMd" | "hPath" | "id") => {
+    let text = "";
+    for (let i = 0; i < ids.length; i++) {
+        const id = ids[i];
+        if (ids.length > 1) {
+            text += "* ";
+        }
+        if (type === "ref") {
+            const response = await fetchSyncPost("/api/block/getRefText", {id});
+            text += `((${id} '${response.data}'))`;
+        } else if (type === "blockEmbed") {
+            text += `{{select * from blocks where id='${id}'}}`;
+        } else if (type === "protocol") {
+            text += `siyuan://blocks/${id}`;
+        } else if (type === "protocolMd") {
+            const response = await fetchSyncPost("/api/block/getRefText", {id});
+            text += `[${response.data}](siyuan://blocks/${id})`;
+        } else if (type === "hPath") {
+            const response = await fetchSyncPost("/api/filetree/getHPathByID", {id});
+            text += response.data;
+        } else if (type === "id") {
+            text += id;
+        }
+        if (ids.length > 1 && i !== ids.length - 1) {
+            text += "\n";
+        }
+    }
+    writeText(text);
+}