From aa1a2728b0112bc006584f5d5fd03c56ac3532b1 Mon Sep 17 00:00:00 2001 From: Vanessa Date: Thu, 21 Dec 2023 11:24:53 +0800 Subject: [PATCH] :art: fix https://github.com/siyuan-note/siyuan/issues/9926 --- app/src/assets/template/mobile/index.tpl | 2 + app/src/layout/dock/Custom.ts | 6 +-- app/src/menus/Menu.ts | 3 ++ app/src/mobile/dock/MobileCustom.ts | 25 +++++++++++ app/src/mobile/util/initFramework.ts | 53 ++++++++++++++++++++++-- app/src/plugin/index.ts | 26 +++++++++--- 6 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 app/src/mobile/dock/MobileCustom.ts diff --git a/app/src/assets/template/mobile/index.tpl b/app/src/assets/template/mobile/index.tpl index b526a3103..6f017a63a 100644 --- a/app/src/assets/template/mobile/index.tpl +++ b/app/src/assets/template/mobile/index.tpl @@ -32,6 +32,7 @@ + @@ -42,6 +43,7 @@
+
diff --git a/app/src/layout/dock/Custom.ts b/app/src/layout/dock/Custom.ts index f2e89feab..6d86d2d31 100644 --- a/app/src/layout/dock/Custom.ts +++ b/app/src/layout/dock/Custom.ts @@ -7,7 +7,7 @@ export class Custom extends Model { public tab: Tab; public data: any; public type: string; - public init: () => void; + public init: (custom: Custom) => void; public destroy: () => void; public beforeDestroy: () => void; public resize: () => void; @@ -22,7 +22,7 @@ export class Custom extends Model { beforeDestroy?: () => void, resize?: () => void, update?: () => void, - init: () => void + init: (custom: Custom) => void }) { super({app: options.app, id: options.tab.id}); if (window.siyuan.config.fileTree.openFilesUseCurrentTab) { @@ -38,6 +38,6 @@ export class Custom extends Model { this.beforeDestroy = options.beforeDestroy; this.resize = options.resize; this.update = options.update; - this.init(); + this.init(this); } } diff --git a/app/src/menus/Menu.ts b/app/src/menus/Menu.ts index c2a0386de..901e6b4f7 100644 --- a/app/src/menus/Menu.ts +++ b/app/src/menus/Menu.ts @@ -137,6 +137,9 @@ export class Menu { } public fullscreen(position: "bottom" | "all" = "all") { + if (this.element.lastElementChild.innerHTML === "") { + return; + } this.element.classList.add("b3-menu--fullscreen"); this.element.style.zIndex = (++window.siyuan.zIndex).toString(); this.element.firstElementChild.classList.remove("fn__none"); diff --git a/app/src/mobile/dock/MobileCustom.ts b/app/src/mobile/dock/MobileCustom.ts new file mode 100644 index 000000000..1b0147568 --- /dev/null +++ b/app/src/mobile/dock/MobileCustom.ts @@ -0,0 +1,25 @@ +export class MobileCustom { + public element: Element; + public data: any; + public type: string; + public init: (custom: MobileCustom) => void; + public destroy: () => void; + public update: () => void; + + constructor(options: { + element: Element, + type: string, + data: any, + destroy?: () => void, + update?: () => void, + init: (custom: MobileCustom) => void + }) { + this.element = options.element; + this.data = options.data; + this.type = options.type; + this.init = options.init; + this.destroy = options.destroy; + this.update = options.update; + this.init(this); + } +} diff --git a/app/src/mobile/util/initFramework.ts b/app/src/mobile/util/initFramework.ts index 34d7e4ef4..db6a63032 100644 --- a/app/src/mobile/util/initFramework.ts +++ b/app/src/mobile/util/initFramework.ts @@ -21,6 +21,39 @@ import {Inbox} from "../../layout/dock/Inbox"; import {App} from "../../index"; import {setTitle} from "../../dialog/processSystem"; import {checkFold} from "../../util/noRelyPCFunction"; +import {MobileCustom} from "../dock/MobileCustom"; +import {Menu} from "../../plugin/Menu"; +import {showMessage} from "../../dialog/message"; + +let custom: MobileCustom; +const openDockMenu = (app: App) => { + const menu = new Menu("dockMobileMenu"); + if (menu.isOpen) { + return; + } + app.plugins.forEach((plugin) => { + Object.keys(plugin.docks).forEach((dockId) => { + menu.addItem({ + label: plugin.docks[dockId].config.title, + icon: plugin.docks[dockId].config.icon, + click() { + if (custom?.type === dockId) { + return; + } else { + if (custom) { + custom.destroy(); + } + custom = plugin.docks[dockId].mobileModel(document.querySelector('#sidebar [data-type="sidebar-plugin"]')); + } + } + }) + }); + }); + menu.fullscreen("bottom"); + if (menu.element.lastElementChild.innerHTML === "") { + showMessage(window.siyuan.languages.emptyContent); + } +} export const initFramework = (app: App, isStart: boolean) => { setInlineStyle(); @@ -38,10 +71,16 @@ export const initFramework = (app: App, isStart: boolean) => { target: Element }) => { const svgElement = hasTopClosestByTag(event.target, "svg"); - if (!svgElement || svgElement.classList.contains("toolbar__icon--active")) { + if (!svgElement) { return; } const type = svgElement.getAttribute("data-type"); + if (svgElement.classList.contains("toolbar__icon--active")) { + if (type === "sidebar-plugin-tab") { + openDockMenu(app); + } + return; + } if (!type) { closePanel(); return; @@ -51,6 +90,7 @@ export const initFramework = (app: App, isStart: boolean) => { if (!itemType) { return; } + const tabPanelElement = sidebarElement.lastElementChild.querySelector(`[data-type="${itemType.replace("-tab", "")}"]`); if (itemType === type) { if (type === "sidebar-outline-tab") { if (!outline) { @@ -78,12 +118,19 @@ export const initFramework = (app: App, isStart: boolean) => { } } else if (type === "sidebar-inbox-tab" && !inbox) { inbox = new Inbox(app, document.querySelector('#sidebar [data-type="sidebar-inbox"]')); + } else if (type === "sidebar-plugin-tab") { + if (!custom) { + tabPanelElement.innerHTML = `
${window.siyuan.languages.emptyContent}
`; + openDockMenu(app); + } else if (custom.update) { + custom.update(); + } } svgElement.classList.add("toolbar__icon--active"); - sidebarElement.lastElementChild.querySelector(`[data-type="${itemType.replace("-tab", "")}"]`).classList.remove("fn__none"); + tabPanelElement.classList.remove("fn__none"); } else { item.classList.remove("toolbar__icon--active"); - sidebarElement.lastElementChild.querySelector(`[data-type="${itemType.replace("-tab", "")}"]`).classList.add("fn__none"); + tabPanelElement.classList.add("fn__none"); } }); }); diff --git a/app/src/plugin/index.ts b/app/src/plugin/index.ts index 3a61a20ae..98026755d 100644 --- a/app/src/plugin/index.ts +++ b/app/src/plugin/index.ts @@ -5,10 +5,12 @@ import {isMobile, isWindow} from "../util/functions"; /// #if !MOBILE import {Custom} from "../layout/dock/Custom"; import {getAllModels} from "../layout/getAll"; -/// #endif import {Tab} from "../layout/Tab"; import {setPanelFocus} from "../layout/util"; import {getDockByType} from "../layout/tabUtil"; +///#else +import {MobileCustom} from "../mobile/dock/MobileCustom"; +/// #endif import {hasClosestByAttribute} from "../protyle/util/hasClosest"; import {BlockPanel} from "../block/Panel"; import {Setting} from "./Setting"; @@ -45,12 +47,14 @@ export class Plugin { /// #endif } = {}; public docks: { - /// #if !MOBILE [key: string]: { config: IPluginDockTab, + /// #if !MOBILE model: (options: { tab: Tab }) => Custom + /// #else + mobileModel: (element: Element) => MobileCustom + /// #endif } - /// #endif } = {}; constructor(options: { @@ -238,13 +242,25 @@ export class Plugin { update?: () => void, init: () => void }) { - /// #if !MOBILE const type2 = this.name + options.type; if (typeof options.config.index === "undefined") { options.config.index = 1000; } this.docks[type2] = { config: options.config, + /// #if MOBILE + mobileModel: (element) => { + const customObj = new MobileCustom({ + element, + type: type2, + data: options.data, + init: options.init, + update: options.update, + destroy: options.destroy, + }); + return customObj; + }, + /// #else model: (arg: { tab: Tab }) => { const customObj = new Custom({ app: this.app, @@ -265,9 +281,9 @@ export class Plugin { customObj.element.classList.add("sy__" + type2); return customObj; } + /// #endif }; return this.docks[type2]; - /// #endif } public addFloatLayer = (options: {