diff --git a/app/appearance/langs/ja_JP.json b/app/appearance/langs/ja_JP.json index 16506fd27..c524a5823 100644 --- a/app/appearance/langs/ja_JP.json +++ b/app/appearance/langs/ja_JP.json @@ -1363,7 +1363,7 @@ "wysiwyg": "WYSIWYG", "recentViewed": "最近閲覧", "recentOpened": "最近開いた", - "recentClosed": "最近閉じる", + "recentClosed": "最近閉じた", "recentModified": "最近更新", "_label": "日本語", "_time": { diff --git a/app/src/boot/globalEvent/command/global.ts b/app/src/boot/globalEvent/command/global.ts index b9eabb563..4cfe6e59c 100644 --- a/app/src/boot/globalEvent/command/global.ts +++ b/app/src/boot/globalEvent/command/global.ts @@ -8,7 +8,7 @@ import {popSearch} from "../../../mobile/menu/search"; import {getRecentDocs} from "../../../mobile/menu/getRecentDocs"; /// #else import {openNewWindow} from "../../../window/openNewWindow"; -import {selectOpenTab, toggleDockBar} from "../../../layout/dock/util"; +import {openBacklink, openGraph, openOutline, selectOpenTab, toggleDockBar} from "../../../layout/dock/util"; import {openGlobalSearch} from "../../../search/util"; import {workspaceMenu} from "../../../menus/workspace"; import {isWindow} from "../../../util/functions"; @@ -40,7 +40,7 @@ import {openCard} from "../../../card/openCard"; import {syncGuide} from "../../../sync/syncGuide"; import {Wnd} from "../../../layout/Wnd"; import {unsplitWnd} from "../../../menus/tab"; -import {openFileById} from "../../../editor/util"; +import {openFile} from "../../../editor/util"; export const globalCommand = (command: string, app: App) => { /// #if MOBILE @@ -151,11 +151,60 @@ export const globalCommand = (command: string, app: App) => { return true; case "recentClosed": if (window.siyuan.closedTabs.length > 0) { - openFileById({ - app, - id: window.siyuan.closedTabs.pop(), - action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL] - }); + const closeData = window.siyuan.closedTabs.pop(); + const childData = closeData.children as ILayoutJSON; + if (childData.instance === "Editor") { + openFile({ + app, + fileName: closeData.title, + id: childData.blockId, + rootID: childData.rootId, + mode: childData.mode, + action: [childData.action] + }); + } else if (childData.instance === "Asset") { + openFile({ + app, + assetPath: childData.path, + page: childData.page, + }); + } else if (childData.instance === "Backlink") { + openBacklink({ + app, + blockId: childData.blockId, + rootId: childData.rootId, + title: closeData.title, + }); + } else if (childData.instance === "Graph") { + openGraph({ + app, + blockId: childData.blockId, + rootId: childData.rootId, + title: closeData.title + }); + } else if (childData.instance === "Outline") { + openOutline({ + app, + rootId: childData.blockId, + title: closeData.title, + isPreview: childData.isPreview + }); + } else if (childData.instance === "Search") { + openFile({ + app, + searchData: childData.config, + }); + } else if (childData.instance === "Custom") { + openFile({ + app, + custom: { + icon: closeData.icon, + title: closeData.title, + data: childData.customModelData, + id: childData.customModelType + }, + }); + } } return true; case "toggleDock": diff --git a/app/src/boot/globalEvent/keydown.ts b/app/src/boot/globalEvent/keydown.ts index bd3845636..f3d5df0eb 100644 --- a/app/src/boot/globalEvent/keydown.ts +++ b/app/src/boot/globalEvent/keydown.ts @@ -442,7 +442,12 @@ const editKeydown = (app: App, event: KeyboardEvent) => { if (matchHotKey(window.siyuan.config.keymap.editor.general.outline.custom, event)) { event.preventDefault(); const offset = getSelectionOffset(target); - openOutline(protyle); + openOutline({ + app, + rootId: protyle.block.rootID, + title: protyle.options.render.title ? (protyle.title.editElement.textContent || window.siyuan.languages.untitled) : "", + isPreview: !protyle.preview.element.classList.contains("fn__none") + }); // switchWnd 后,range会被清空,需要重新设置 focusByOffset(target, offset.start, offset.end); return true; @@ -1534,7 +1539,8 @@ export const windowKeyDown = (app: App, event: KeyboardEvent) => { if (matchHotKey(window.siyuan.config.keymap.general.recentClosed.custom, event)) { execByCommand({ - command: "closeTab" + command: "recentClosed", + app }); event.preventDefault(); return; diff --git a/app/src/layout/Wnd.ts b/app/src/layout/Wnd.ts index 32c75fcfc..eac33105e 100644 --- a/app/src/layout/Wnd.ts +++ b/app/src/layout/Wnd.ts @@ -4,7 +4,7 @@ import { fixWndFlex1, getInstanceById, getWndByLayout, - JSONToCenter, + JSONToCenter, layoutToJSON, newModelByInitData, pdfIsLoading, saveLayout, @@ -786,6 +786,13 @@ export class Wnd { clearCounter(); this.children.find((item, index) => { if (item.id === id) { + if (window.siyuan.closedTabs.length > Constants.SIZE_UNDO) { + window.siyuan.closedTabs.pop(); + } + const tabJSON = {}; + layoutToJSON(item, tabJSON); + window.siyuan.closedTabs.push(tabJSON); + if (item.model instanceof Custom && item.model.beforeDestroy) { item.model.beforeDestroy(); } @@ -793,7 +800,6 @@ export class Wnd { saveScroll(item.model.editor.protyle); // 更新文档关闭时间 fetchPost("/api/storage/updateRecentDocCloseTime", {rootID: item.model.editor.protyle.block.rootID}); - window.siyuan.closedTabs.push(item.model.editor.protyle.block.rootID); } if (this.children.length === 1) { this.destroyModel(this.children[0].model); diff --git a/app/src/layout/dock/util.ts b/app/src/layout/dock/util.ts index 5414838df..3e0369971 100644 --- a/app/src/layout/dock/util.ts +++ b/app/src/layout/dock/util.ts @@ -122,9 +122,14 @@ export const openGraph = async (options: { })); }; -export const openOutline = async (protyle: IProtyle) => { +export const openOutline = async (options: { + app: App, + rootId: string, + isPreview: boolean, + title: string +}) => { const outlinePanel = getAllModels().outline.find(item => { - if (item.blockId === protyle.block.rootID && item.type === "local") { + if (item.blockId === options.rootId && item.type === "local") { item.parent.parent.removeTab(item.parent.id); return true; } @@ -141,23 +146,20 @@ export const openOutline = async (protyle: IProtyle) => { wnd = getWndByLayout(window.siyuan.layout.centerLayout); } const newWnd = wnd.split("lr"); - let title = ""; - if (!protyle.title) { - const response = await fetchSyncPost("api/block/getDocInfo", {id: protyle.block.rootID}); - title = response.data.name || window.siyuan.languages.untitled; - } else { - title = protyle.title.editElement.textContent || window.siyuan.languages.untitled; + if (options.title) { + const response = await fetchSyncPost("api/block/getDocInfo", {id: options.rootId}); + options.title = response.data.name || window.siyuan.languages.untitled; } newWnd.addTab(new Tab({ icon: "iconAlignCenter", - title, + title: options.title, callback(tab: Tab) { tab.addModel(new Outline({ - app: protyle.app, + app: options.app, type: "local", tab, - blockId: protyle.block.rootID, - isPreview: !protyle.preview.element.classList.contains("fn__none") + blockId: options.rootId, + isPreview: options.isPreview, })); } }), false, false); diff --git a/app/src/protyle/header/openTitleMenu.ts b/app/src/protyle/header/openTitleMenu.ts index fd20af0db..aac3caa81 100644 --- a/app/src/protyle/header/openTitleMenu.ts +++ b/app/src/protyle/header/openTitleMenu.ts @@ -76,7 +76,12 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition, from: stri label: window.siyuan.languages.outline, accelerator: window.siyuan.config.keymap.editor.general.outline.custom, click: () => { - openOutline(protyle); + openOutline({ + app: protyle.app, + rootId: protyle.block.rootID, + title: protyle.options.render.title ? (protyle.title.editElement.textContent || window.siyuan.languages.untitled) : "", + isPreview: !protyle.preview.element.classList.contains("fn__none") + }); } }).element); window.siyuan.menus.menu.append(new MenuItem({ diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 68de08f8a..4b05128a1 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -460,7 +460,7 @@ interface ISiyuan { storage?: { [key: string]: any }, - closedTabs: string[] + closedTabs?: ILayoutJSON[] transactions?: { protyle: IProtyle, doOperations: IOperation[], @@ -595,6 +595,8 @@ interface ILayoutJSON extends ILayoutOptions { page?: string path?: string blockId?: string + mode?: TEditorMode + action?: TProtyleAction icon?: string rootId?: string active?: boolean