Переглянути джерело

:art: https://github.com/siyuan-note/siyuan/issues/5066

Vanessa 2 роки тому
батько
коміт
8fe520f4af

+ 4 - 1
app/src/index.ts

@@ -54,6 +54,9 @@ export class App {
                 id: genUUID(),
                 type: "main",
                 msgCallback: (data) => {
+                    this.plugins.forEach((plugin) => {
+                        plugin.eventBus.emit("ws-main", data);
+                    });
                     if (data) {
                         switch (data.cmd) {
                             case "syncMergeResult":
@@ -167,8 +170,8 @@ export class App {
                     bootSync();
                     fetchPost("/api/setting/getCloudUser", {}, userResponse => {
                         window.siyuan.user = userResponse.data;
-                        onGetConfig(response.data.start);
                         loadPlugins(siyuanApp);
+                        onGetConfig(response.data.start);
                         account.onSetaccount();
                         resizeDrag();
                         setTitle(window.siyuan.languages.siyuanNote);

+ 9 - 2
app/src/mobile/index.ts

@@ -22,8 +22,11 @@ import {getSearch} from "../util/functions";
 import {initRightMenu} from "./menu";
 import {openChangelog} from "../boot/openChangelog";
 import {registerServiceWorker} from "../util/serviceWorker";
+import {loadPlugins} from "../plugin/loader";
 
 class App {
+    public plugins: import("../plugin").Plugin[] = [];
+
     constructor() {
         if (!window.webkit?.messageHandlers && !window.JSAndroid) {
             registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`);
@@ -41,7 +44,10 @@ class App {
             ws: new Model({
                 id: genUUID(),
                 type: "main",
-                msgCallback(data) {
+                msgCallback: (data)=> {
+                    this.plugins.forEach((plugin) => {
+                        plugin.eventBus.emit("ws-main", data);
+                    });
                     onMessage(data);
                 }
             })
@@ -66,6 +72,7 @@ class App {
                     initAssets();
                     fetchPost("/api/setting/getCloudUser", {}, userResponse => {
                         window.siyuan.user = userResponse.data;
+                        loadPlugins(siyuanApp);
                         fetchPost("/api/system/getEmojiConf", {}, emojiResponse => {
                             window.siyuan.emojis = emojiResponse.data as IEmoji[];
                             initFramework();
@@ -85,7 +92,7 @@ class App {
     }
 }
 
-new App();
+const siyuanApp = new App();
 
 window.goBack = goBack;
 window.showKeyboardToolbar = (height) => {

+ 9 - 0
app/src/plugin/API.ts

@@ -0,0 +1,9 @@
+import {confirmDialog} from "../dialog/confirmDialog";
+import {Plugin} from "./index";
+import {showMessage} from "../dialog/message";
+
+export const API = {
+    Plugin: Plugin,
+    Confirm: confirmDialog,
+    Message: showMessage
+};

+ 23 - 0
app/src/plugin/EventBus.ts

@@ -0,0 +1,23 @@
+export class EventBus<DetailType = any> {
+    private eventTarget: EventTarget;
+
+    constructor(name = "") {
+        this.eventTarget = document.appendChild(document.createComment(name));
+    }
+
+    on(type: TEventBus, listener: (event: CustomEvent<DetailType>) => void) {
+        this.eventTarget.addEventListener(type, listener);
+    }
+
+    once(type: TEventBus, listener: (event: CustomEvent<DetailType>) => void) {
+        this.eventTarget.addEventListener(type, listener, {once: true});
+    }
+
+    off(type: TEventBus, listener: (event: CustomEvent<DetailType>) => void) {
+        this.eventTarget.removeEventListener(type, listener);
+    }
+
+    emit(type: TEventBus, detail?: DetailType) {
+        return this.eventTarget.dispatchEvent(new CustomEvent(type, {detail}));
+    }
+}

+ 4 - 0
app/src/plugin/index.ts

@@ -1,14 +1,18 @@
 import {App} from "../index";
+import {EventBus} from "./EventBus";
 
 export class Plugin {
     public i18n: IObject;
+    public eventBus: EventBus;
 
     constructor(options: {
         app: App,
         id: string,
+        name: string,
         i18n: IObject
     }) {
         this.i18n = options.i18n;
+        this.eventBus = new EventBus(options.name);
     }
 
     public getData() {

+ 8 - 4
app/src/plugin/loader.ts

@@ -1,12 +1,11 @@
 import {fetchPost} from "../util/fetch";
 import {App} from "../index";
 import {Plugin} from "./index";
+import {API} from "./API";
 
 const getObject = (key: string) => {
     const api = {
-        siyuan: {
-            Plugin: Plugin
-        }
+        siyuan: API
     };
     // @ts-ignore
     return api[key];
@@ -37,7 +36,12 @@ export const loadPlugins = (app: App) => {
                 console.error(`plugin ${item.name} does not extends Plugin`);
                 return;
             }
-            const plugin = new pluginClass({app, id: item.id, i18n: item.i18n});
+            const plugin = new pluginClass({
+                app,
+                name: item.name,
+                id: item.id,
+                i18n: item.i18n
+            });
             app.plugins.push(plugin);
             plugin.onload();
             css += item.css || "" + "\n";

+ 2 - 0
app/src/types/index.d.ts

@@ -31,6 +31,8 @@ type TOperation =
     | "removeFlashcards"
 type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins"
 type TCardType = "doc" | "notebook" | "all"
+type TEventBus = "ws-main"
+
 declare module "blueimp-md5"
 
 interface Window {

+ 8 - 1
app/src/window/index.ts

@@ -21,8 +21,11 @@ import {getAllTabs} from "../layout/getAll";
 import {getLocalStorage} from "../protyle/util/compatibility";
 import {init} from "../window/init";
 import {positionPDF, switchTabById} from "./global/function";
+import {loadPlugins} from "../plugin/loader";
 
 class App {
+    public plugins: import("../plugin").Plugin[] = [];
+
     constructor() {
         addScriptSync(`${Constants.PROTYLE_CDN}/js/lute/lute.min.js?v=${Constants.SIYUAN_VERSION}`, "protyleLuteScript");
         addScript(`${Constants.PROTYLE_CDN}/js/protyle-html.js?v=${Constants.SIYUAN_VERSION}`, "protyleWcHtmlScript");
@@ -40,6 +43,9 @@ class App {
                 id: genUUID(),
                 type: "main",
                 msgCallback: (data) => {
+                    this.plugins.forEach((plugin) => {
+                        plugin.eventBus.emit("ws-main", data);
+                    });
                     if (data) {
                         switch (data.cmd) {
                             case "syncMergeResult":
@@ -128,6 +134,7 @@ class App {
                     window.siyuan.menus = new Menus();
                     fetchPost("/api/setting/getCloudUser", {}, userResponse => {
                         window.siyuan.user = userResponse.data;
+                        loadPlugins(siyuanApp);
                         init();
                         setTitle(window.siyuan.languages.siyuanNote);
                         initMessage();
@@ -141,7 +148,7 @@ class App {
     }
 }
 
-new App();
+const siyuanApp = new App();
 
 // 再次点击新窗口已打开的 PDF 时,需进行定位
 window.newWindow = {