diff --git a/app/src/ai/actions.ts b/app/src/ai/actions.ts index d9bb472eb..69d45816e 100644 --- a/app/src/ai/actions.ts +++ b/app/src/ai/actions.ts @@ -174,7 +174,7 @@ export const AIActions = (elements: Element[], protyle: IProtyle) => { if (customHTML) { customHTML = `
${customHTML}`; } - const clearContext = "Clear context" + const clearContext = "Clear context"; menu.addItem({ iconHTML: "", type: "empty", @@ -237,7 +237,7 @@ export const AIActions = (elements: Element[], protyle: IProtyle) => { fillContent(protyle, response.data, elements); }); if (currentElement.dataset.action === clearContext) { - showMessage(window.siyuan.languages.clearContextSucc) + showMessage(window.siyuan.languages.clearContextSucc); } else { menu.close(); } @@ -272,7 +272,7 @@ export const AIActions = (elements: Element[], protyle: IProtyle) => { fillContent(protyle, response.data, elements); }); if (target.dataset.action === clearContext) { - showMessage(window.siyuan.languages.clearContextSucc) + showMessage(window.siyuan.languages.clearContextSucc); } else { menu.close(); } diff --git a/app/src/layout/topBar.ts b/app/src/layout/topBar.ts index a77c53e74..3c1d9faac 100644 --- a/app/src/layout/topBar.ts +++ b/app/src/layout/topBar.ts @@ -1,5 +1,5 @@ import {getWorkspaceName} from "../util/noRelyPCFunction"; -import {isHuawei, isInAndroid, isInIOS, setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility"; +import {isInAndroid, isInIOS, setStorageVal, updateHotkeyTip} from "../protyle/util/compatibility"; import {exitSiYuan, processSync} from "../dialog/processSystem"; import {goBack, goForward} from "../util/backForward"; import {syncGuide} from "../sync/syncGuide"; @@ -14,12 +14,12 @@ import {webFrame} from "electron"; /// #endif import {Constants} from "../constants"; import {isBrowser, isWindow} from "../util/functions"; -import {Menu} from "../plugin/Menu"; import {fetchPost} from "../util/fetch"; import {needSubscribe} from "../util/needSubscribe"; import * as dayjs from "dayjs"; import {exportLayout} from "./util"; import {commandPanel} from "../boot/globalEvent/command/panel"; +import {openTopBarMenu} from "../plugin/openTopBarMenu"; export const initBar = (app: App) => { const toolbarElement = document.getElementById("toolbar"); @@ -179,7 +179,7 @@ export const initBar = (app: App) => { event.stopPropagation(); break; } else if (targetId === "barPlugins") { - openPlugin(app, target); + openTopBarMenu(app, target); event.stopPropagation(); break; } else if (targetId === "barCommand") { @@ -298,86 +298,3 @@ export const setZoom = (type: "zoomIn" | "zoomOut" | "restore") => { } /// #endif }; - -const openPlugin = (app: App, target: Element) => { - const menu = new Menu("topBarPlugin"); - menu.addItem({ - icon: "iconSettings", - label: window.siyuan.languages.manage, - ignore: isHuawei() || window.siyuan.config.readonly, - click() { - openSetting(app).element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click")); - } - }); - menu.addSeparator(undefined, isHuawei() || window.siyuan.config.readonly); - let hasPlugin = false; - app.plugins.forEach((plugin) => { - // @ts-ignore - const hasSetting = plugin.setting || plugin.__proto__.hasOwnProperty("openSetting"); - let hasTopBar = false; - plugin.topBarIcons.forEach(item => { - const hasUnpin = window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].includes(item.id); - const submenu = [{ - icon: hasUnpin ? "iconPin" : "iconUnpin", - label: hasUnpin ? window.siyuan.languages.pin : window.siyuan.languages.unpin, - click() { - if (hasUnpin) { - window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].splice(window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].indexOf(item.id), 1); - item.classList.remove("fn__none"); - } else { - window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].push(item.id); - window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN] = Array.from(new Set(window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN])); - item.classList.add("fn__none"); - } - setStorageVal(Constants.LOCAL_PLUGINTOPUNPIN, window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN]); - } - }]; - if (hasSetting) { - submenu.push({ - icon: "iconSettings", - label: window.siyuan.languages.config, - click() { - plugin.openSetting(); - }, - }); - } - const menuOption: IMenu = { - icon: "iconInfo", - label: item.getAttribute("aria-label"), - click() { - item.dispatchEvent(new CustomEvent("click")); - }, - type: "submenu", - submenu - }; - if (item.querySelector("use")) { - menuOption.icon = item.querySelector("use").getAttribute("xlink:href").replace("#", ""); - } else { - const svgElement = item.querySelector("svg").cloneNode(true) as HTMLElement; - svgElement.classList.add("b3-menu__icon"); - menuOption.iconHTML = svgElement.outerHTML; - } - menu.addItem(menuOption); - hasPlugin = true; - hasTopBar = true; - }); - if (!hasTopBar && hasSetting) { - hasPlugin = true; - menu.addItem({ - icon: "iconSettings", - label: plugin.displayName, - click() { - plugin.openSetting(); - } - }); - } - }); - if (!hasPlugin) { - window.siyuan.menus.menu.element.querySelector(".b3-menu__separator")?.remove(); - } - let rect = target.getBoundingClientRect(); - if (rect.width === 0) { - rect = document.querySelector("#barMore").getBoundingClientRect(); - } - menu.open({x: rect.right, y: rect.bottom, isLeft: true}); -}; diff --git a/app/src/mobile/menu/index.ts b/app/src/mobile/menu/index.ts index 0a9092e45..c012c1e7b 100644 --- a/app/src/mobile/menu/index.ts +++ b/app/src/mobile/menu/index.ts @@ -19,8 +19,8 @@ import {App} from "../../index"; import {isHuawei, isInAndroid, isInIOS, isIPhone} from "../../protyle/util/compatibility"; import {newFile} from "../../util/newFile"; import {afterLoadPlugin} from "../../plugin/loader"; -import {Menu} from "../../plugin/Menu"; import {commandPanel} from "../../boot/globalEvent/command/panel"; +import {openTopBarMenu} from "../../plugin/openTopBarMenu"; export const popMenu = () => { activeBlur(); @@ -121,14 +121,8 @@ export const initRightMenu = (app: App) => { `; processSync(); - const unPinsMenu: IMenu[] = []; app.plugins.forEach(item => { - const unPinMenu = afterLoadPlugin(item); - if (unPinMenu) { - unPinMenu.forEach(unpinItem => { - unPinsMenu.push(unpinItem); - }); - } + afterLoadPlugin(item); }); // 只能用 click,否则无法上下滚动 https://github.com/siyuan-note/siyuan/issues/6628 menuElement.addEventListener("click", (event) => { @@ -186,11 +180,7 @@ export const initRightMenu = (app: App) => { event.stopPropagation(); break; } else if (target.id === "menuPlugin") { - const menu = new Menu(); - unPinsMenu.forEach(item => { - menu.addItem(item); - }); - menu.fullscreen(); + openTopBarMenu(app); event.preventDefault(); event.stopPropagation(); break; diff --git a/app/src/plugin/loader.ts b/app/src/plugin/loader.ts index 7d1b3f2b8..c5daf82ee 100644 --- a/app/src/plugin/loader.ts +++ b/app/src/plugin/loader.ts @@ -114,18 +114,9 @@ export const afterLoadPlugin = (plugin: Plugin) => { } if (!isWindow() || isMobile()) { - const unPinMenu: IMenu[] = []; plugin.topBarIcons.forEach(element => { if (isMobile()) { - if (window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].includes(element.id)) { - unPinMenu.push({ - iconHTML: element.firstElementChild.outerHTML, - label: element.textContent.trim(), - click() { - element.dispatchEvent(new CustomEvent("click")); - } - }); - } else { + if (!window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].includes(element.id)) { document.querySelector("#menuAbout").after(element); } } else if (!isWindow()) { @@ -135,9 +126,6 @@ export const afterLoadPlugin = (plugin: Plugin) => { document.querySelector("#" + (element.getAttribute("data-position") === "right" ? "barPlugins" : "drag")).before(element); } }); - if (isMobile() && unPinMenu.length > 0) { - return unPinMenu; - } } /// #if !MOBILE resizeTopBar(); diff --git a/app/src/plugin/openTopBarMenu.ts b/app/src/plugin/openTopBarMenu.ts new file mode 100644 index 000000000..bb5d1f070 --- /dev/null +++ b/app/src/plugin/openTopBarMenu.ts @@ -0,0 +1,115 @@ +import {App} from "../index"; +import {Menu} from "./Menu"; +import {isHuawei, setStorageVal} from "../protyle/util/compatibility"; +/// #if !MOBILE +import {openSetting} from "../config"; +/// #endif +import {Constants} from "../constants"; + +export const openTopBarMenu = (app: App, target?: Element) => { + const menu = new Menu("topBarPlugin"); + /// #if !MOBILE + menu.addItem({ + icon: "iconSettings", + label: window.siyuan.languages.manage, + ignore: isHuawei() || window.siyuan.config.readonly, + click() { + openSetting(app).element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click")); + } + }); + menu.addSeparator(undefined, isHuawei() || window.siyuan.config.readonly); + /// #endif + let hasPlugin = false; + app.plugins.forEach((plugin) => { + // @ts-ignore + const hasSetting = plugin.setting || plugin.__proto__.hasOwnProperty("openSetting"); + let hasTopBar = false; + plugin.topBarIcons.forEach(item => { + const hasUnpin = window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].includes(item.id); + const submenu = [{ + icon: hasUnpin ? "iconPin" : "iconUnpin", + label: hasUnpin ? window.siyuan.languages.pin : window.siyuan.languages.unpin, + click() { + if (hasUnpin) { + window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].splice(window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].indexOf(item.id), 1); + item.classList.remove("fn__none"); + } else { + window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].push(item.id); + window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN] = Array.from(new Set(window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN])); + item.classList.add("fn__none"); + } + setStorageVal(Constants.LOCAL_PLUGINTOPUNPIN, window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN]); + } + }]; + if (hasSetting) { + submenu.push({ + icon: "iconSettings", + label: window.siyuan.languages.config, + click() { + plugin.openSetting(); + }, + }); + } + const itemLabel = target ? item.getAttribute("aria-label") : item.textContent.trim(); + if (!target) { + submenu.push({ + icon: "iconPlay", + label: itemLabel, + click() { + item.dispatchEvent(new CustomEvent("click")); + return true; + }, + }); + } + const menuOption: IMenu = { + icon: "iconInfo", + label: itemLabel, + click: target ? () => { + item.dispatchEvent(new CustomEvent("click")); + } : undefined, + type: "submenu", + submenu + }; + if (item.querySelector("use")) { + menuOption.icon = item.querySelector("use").getAttribute("xlink:href").replace("#", ""); + } else { + const svgElement = item.querySelector("svg").cloneNode(true) as HTMLElement; + svgElement.classList.add("b3-menu__icon"); + menuOption.iconHTML = svgElement.outerHTML; + } + menu.addItem(menuOption); + hasPlugin = true; + hasTopBar = true; + }); + if (!hasTopBar && hasSetting) { + hasPlugin = true; + menu.addItem({ + icon: "iconSettings", + label: plugin.displayName, + click() { + plugin.openSetting(); + } + }); + } + }); + if (!hasPlugin) { + if (target) { + window.siyuan.menus.menu.element.querySelector(".b3-menu__separator")?.remove(); + } else { + menu.addItem({ + iconHTML: "", + type: "readonly", + label: window.siyuan.languages.emptyContent, + }); + } + } + if (target) { + let rect = target.getBoundingClientRect(); + if (rect.width === 0) { + rect = document.querySelector("#barMore").getBoundingClientRect(); + } + menu.open({x: rect.right, y: rect.bottom, isLeft: true}); + } else { + menu.fullscreen(); + } +};