diff --git a/app/appearance/icons/ant/icon.js b/app/appearance/icons/ant/icon.js index 5d8047002..07a9f5ff9 100644 --- a/app/appearance/icons/ant/icon.js +++ b/app/appearance/icons/ant/icon.js @@ -1,5 +1,8 @@ document.body.insertAdjacentHTML('afterbegin', ` + + + diff --git a/app/appearance/icons/index.html b/app/appearance/icons/index.html index b43a8e671..f70f05344 100644 --- a/app/appearance/icons/index.html +++ b/app/appearance/icons/index.html @@ -28,6 +28,12 @@

SiYuan

+
+ + + + iconPlugin +
diff --git a/app/appearance/icons/material/icon.js b/app/appearance/icons/material/icon.js index 83da9f550..ec87636e3 100644 --- a/app/appearance/icons/material/icon.js +++ b/app/appearance/icons/material/icon.js @@ -1,5 +1,8 @@ document.body.insertAdjacentHTML('afterbegin', ` + + + diff --git a/app/src/layout/topBar.ts b/app/src/layout/topBar.ts index c0684bbd5..092cfd00f 100644 --- a/app/src/layout/topBar.ts +++ b/app/src/layout/topBar.ts @@ -15,6 +15,7 @@ import {webFrame} from "electron"; /// #endif import {Constants} from "../constants"; import {isBrowser, isWindow} from "../util/functions"; +import {Menu} from "../plugin/API"; export const updateEditModeElement = () => { const target = document.querySelector("#barReadonly"); @@ -47,6 +48,9 @@ export const initBar = (app: App) => {
开发版,使用前请进行备份 Development version, please backup before use
+
+ +
@@ -177,6 +181,10 @@ export const initBar = (app: App) => { }); event.stopPropagation(); break; + } else if (targetId === "barPlugins") { + openPlugin(app, target); + event.stopPropagation(); + break; } else if (targetId === "barZoom") { if (!window.siyuan.menus.menu.element.classList.contains("fn__none") && window.siyuan.menus.menu.element.getAttribute("data-name") === "barZoom") { @@ -259,3 +267,62 @@ export const setZoom = (type: "zoomIn" | "zoomOut" | "restore") => { } /// #endif }; + +const openPlugin = (app: App, target: Element) => { + const menu = new Menu("topBarPlugin"); + let hasPlugin = false; + app.plugins.forEach((plugin) => { + // @ts-ignore + const hasSetting = plugin.setting || plugin.__proto__.hasOwnProperty("openSetting"); + plugin.topBarIcons.forEach(item => { + const menuOption: IMenu = { + icon: "iconInfo", + label: item.getAttribute("aria-label"), + click() { + item.dispatchEvent(new CustomEvent("click")) + }, + type: "submenu", + submenu: [{ + icon: "iconPin", + label: window.siyuan.languages.pin, + click() { + + } + }, { + icon: "iconSettings", + label: window.siyuan.languages.config, + disabled: !hasSetting, + click() { + plugin.openSetting(); + }, + }] + } + if (item.querySelector("use")) { + menuOption.icon = item.querySelector("use").getAttribute("xlink:href").replace("#", ""); + } else { + const svgElement = item.querySelector("svg"); + svgElement.classList.add("b3-menu__icon") + menuOption.iconHTML = svgElement.outerHTML; + } + menu.addItem(menuOption); + hasPlugin = true + }) + }) + + if (hasPlugin) { + menu.addSeparator() + } + menu.addItem({ + icon: "iconSettings", + label: window.siyuan.languages.config, + click() { + const dialogSetting = openSetting(app); + dialogSetting.element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click")); + } + }); + 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/plugin/API.ts b/app/src/plugin/API.ts index 199d54c8a..0b2e40dba 100644 --- a/app/src/plugin/API.ts +++ b/app/src/plugin/API.ts @@ -53,7 +53,7 @@ export class Menu { this.menu.addSeparator(index); } - open(options: { x: number, y: number, h?: number, w?: number, isLeft: false }) { + open(options: { x: number, y: number, h?: number, w?: number, isLeft?: boolean }) { if (this.isOpen) { return; } diff --git a/app/src/plugin/loader.ts b/app/src/plugin/loader.ts index 1e8690c56..be4dbcb94 100644 --- a/app/src/plugin/loader.ts +++ b/app/src/plugin/loader.ts @@ -141,7 +141,7 @@ export const afterLoadPlugin = (plugin: Plugin) => { if (isMobile()) { document.querySelector("#menuAbout").after(element); } else if (!isWindow()) { - document.querySelector("#" + (element.getAttribute("data-position") === "right" ? "barSearch" : "drag")).before(element); + document.querySelector("#" + (element.getAttribute("data-position") === "right" ? "barPlugins" : "drag")).before(element); } }); } diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index 33c5c950b..cbb6599b3 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -736,6 +736,7 @@ export class Gutter { window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element); window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.plugin, + icon: "iconPlugin", type: "submenu", submenu: pluginSubMenu.menus, }).element); @@ -1552,6 +1553,7 @@ export class Gutter { if (pluginSubMenu.menus.length > 0) { window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.plugin, + icon: "iconPlugin", type: "submenu", submenu: pluginSubMenu.menus, }).element); diff --git a/app/src/protyle/header/Title.ts b/app/src/protyle/header/Title.ts index 30e3377a4..948ff3006 100644 --- a/app/src/protyle/header/Title.ts +++ b/app/src/protyle/header/Title.ts @@ -413,6 +413,7 @@ export class Title { window.siyuan.menus.menu.append(new MenuItem({ type: "separator" }).element); window.siyuan.menus.menu.append(new MenuItem({ label: window.siyuan.languages.plugin, + icon: "iconPlugin", type: "submenu", submenu: pluginSubMenu.menus, }).element);