A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {App} from "../index";
2import {Menu} from "./Menu";
3import {isHuawei, setStorageVal} from "../protyle/util/compatibility";
4/// #if !MOBILE
5import {openSetting} from "../config";
6/// #endif
7import {Constants} from "../constants";
8
9export const openTopBarMenu = (app: App, target?: Element) => {
10 const menu = new Menu(Constants.MENU_BAR_PLUGIN);
11 /// #if !MOBILE
12 menu.addItem({
13 id: "manage",
14 icon: "iconSettings",
15 label: window.siyuan.languages.manage,
16 ignore: isHuawei() || window.siyuan.config.readonly,
17 click() {
18 openSetting(app).element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click"));
19 }
20 });
21 menu.addSeparator({id: "separator_1", ignore: isHuawei() || window.siyuan.config.readonly});
22 /// #endif
23 let hasPlugin = false;
24 app.plugins.forEach((plugin) => {
25 // @ts-ignore
26 const hasSetting = plugin.setting || plugin.__proto__.hasOwnProperty("openSetting");
27 let hasTopBar = false;
28 for (let i = 0; i < plugin.topBarIcons.length; i++) {
29 const item = plugin.topBarIcons[i];
30 if (!document.contains(item)) {
31 plugin.topBarIcons.splice(i, 1);
32 i--;
33 continue;
34 }
35 const hasUnpin = window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].includes(item.id);
36 const submenu = [{
37 id: hasUnpin ? "pin" : "unpin",
38 icon: hasUnpin ? "iconPin" : "iconUnpin",
39 label: hasUnpin ? window.siyuan.languages.pin : window.siyuan.languages.unpin,
40 click() {
41 if (hasUnpin) {
42 window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].splice(window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].indexOf(item.id), 1);
43 item.classList.remove("fn__none");
44 } else {
45 window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN].push(item.id);
46 window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN] = Array.from(new Set(window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN]));
47 item.classList.add("fn__none");
48 }
49 setStorageVal(Constants.LOCAL_PLUGINTOPUNPIN, window.siyuan.storage[Constants.LOCAL_PLUGINTOPUNPIN]);
50 }
51 }];
52 if (hasSetting) {
53 submenu.push({
54 id: "config",
55 icon: "iconSettings",
56 label: window.siyuan.languages.config,
57 click() {
58 plugin.openSetting();
59 },
60 });
61 }
62 const itemLabel = target ? item.getAttribute("aria-label") : item.textContent.trim();
63 if (!target) {
64 submenu.push({
65 id: "play",
66 icon: "iconPlay",
67 label: itemLabel,
68 click() {
69 item.dispatchEvent(new CustomEvent("click"));
70 return true;
71 },
72 });
73 }
74 const menuOption: IMenu = {
75 id: item.id,
76 icon: "iconInfo",
77 label: itemLabel,
78 click: target ? () => {
79 item.dispatchEvent(new CustomEvent("click"));
80 } : undefined,
81 type: "submenu",
82 submenu
83 };
84 if (item.querySelector("use")) {
85 menuOption.icon = item.querySelector("use").getAttribute("xlink:href").replace("#", "");
86 } else {
87 const svgElement = item.querySelector("svg").cloneNode(true) as HTMLElement;
88 svgElement.classList.add("b3-menu__icon");
89 menuOption.iconHTML = svgElement.outerHTML;
90 }
91 menu.addItem(menuOption);
92 hasPlugin = true;
93 hasTopBar = true;
94 }
95 if (!hasTopBar && hasSetting) {
96 hasPlugin = true;
97 menu.addItem({
98 id: plugin.name,
99 icon: "iconSettings",
100 label: plugin.displayName,
101 click() {
102 plugin.openSetting();
103 }
104 });
105 }
106 });
107 if (!hasPlugin) {
108 if (target) {
109 window.siyuan.menus.menu.element.querySelector(".b3-menu__separator")?.remove();
110 } else {
111 menu.addItem({
112 id: "emptyContent",
113 iconHTML: "",
114 type: "readonly",
115 label: window.siyuan.languages.emptyContent,
116 });
117 }
118 }
119 if (target) {
120 let rect = target.getBoundingClientRect();
121 if (rect.width === 0) {
122 rect = document.querySelector("#barMore").getBoundingClientRect();
123 }
124 menu.open({x: rect.right, y: rect.bottom, isLeft: true});
125 } else {
126 menu.fullscreen();
127 }
128};