Browse Source

:art: fix https://github.com/siyuan-note/siyuan/issues/8258

Vanessa 2 năm trước cách đây
mục cha
commit
1ac623ebb1

+ 13 - 13
app/src/config/bazaar.ts

@@ -15,6 +15,7 @@ import {hasClosestByAttribute, hasClosestByClassName} from "../protyle/util/hasC
 import {Plugin} from "../plugin";
 import {App} from "../index";
 import {escapeAttr} from "../util/escape";
+import {uninstall} from "../plugin/uninstall";
 
 export const bazaar = {
     element: undefined as Element,
@@ -571,12 +572,7 @@ export const bazaar = {
                                 this._genMyHTML(bazaarType, app);
                                 bazaar._onBazaar(response, bazaarType, ["themes", "icons"].includes(bazaarType));
                                 if (bazaarType === "plugins") {
-                                    // TODO destroy plugin
-                                    exportLayout({
-                                        reload: true,
-                                        onlyData: false,
-                                        errorExit: false,
-                                    });
+                                    uninstall(app, packageName);
                                 }
                             });
                         });
@@ -641,16 +637,20 @@ export const bazaar = {
                 } else if (type === "plugin-enable") {
                     const itemElement = hasClosestByClassName(target, "b3-card");
                     if (itemElement) {
+                        const enabled = (target as HTMLInputElement).checked
                         fetchPost("/api/petal/setPetalEnabled", {
                             packageName: dataObj.name,
-                            enabled: (target as HTMLInputElement).checked
+                            enabled,
                         }, () => {
-                            // TODO destroy plugin
-                            exportLayout({
-                                reload: true,
-                                onlyData: false,
-                                errorExit: false,
-                            });
+                            if (enabled) {
+                                exportLayout({
+                                    reload: true,
+                                    onlyData: false,
+                                    errorExit: false,
+                                });
+                            } else {
+                                uninstall(app, dataObj.name);
+                            }
                         });
                     }
                     event.stopPropagation();

+ 11 - 2
app/src/layout/dock/index.ts

@@ -17,6 +17,7 @@ import {resetFloatDockSize} from "./util";
 import {hasClosestByClassName} from "../../protyle/util/hasClosest";
 import {App} from "../../index";
 import {Plugin} from "../../plugin";
+import {Custom} from "./Custom";
 
 export class Dock {
     public element: HTMLElement;
@@ -267,7 +268,7 @@ export class Dock {
         this.layout.element.querySelector(".layout__tab--active")?.classList.remove("layout__tab--active");
     }
 
-    public toggleModel(type: string, show = false, close = false) {
+    public toggleModel(type: string, show = false, close = false, hide = false) {
         if (!type) {
             return;
         }
@@ -277,7 +278,7 @@ export class Dock {
         }
         const index = parseInt(target.getAttribute("data-index"));
         const wnd = this.layout.children[index] as Wnd;
-        if (target.classList.contains("dock__item--active")) {
+        if (target.classList.contains("dock__item--active") || hide) {
             if (!close) {
                 let needFocus = false;
                 Array.from(wnd.element.querySelector(".layout-tab-container").children).find(item => {
@@ -544,6 +545,14 @@ export class Dock {
         }
     }
 
+    public remove(key: string) {
+        this.toggleModel(key, false, true, true);
+        this.element.querySelector(`[data-type="${key}"]`).remove();
+        const custom = this.data[key] as Custom;
+        custom.parent.parent.removeTab(custom.parent.id);
+        delete this.data[key];
+    }
+
     private getClassDirect(index: number) {
         let direct = "e";
         switch (this.position) {

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

@@ -14,6 +14,7 @@ export class Plugin {
     public eventBus: EventBus;
     public data: any;
     public name: string;
+    public topBarIcons: Element[] = [];
     public models: {
         /// #if !MOBILE
         [key: string]: (options: { tab: Tab, data: any }) => Custom
@@ -65,6 +66,7 @@ export class Plugin {
             iconElement.addEventListener("click", options.callback);
             document.querySelector("#" + (options.position === "right" ? "barSearch" : "drag")).before(iconElement);
         }
+        this.topBarIcons.push(iconElement);
         return iconElement;
     }
 

+ 48 - 0
app/src/plugin/uninstall.ts

@@ -0,0 +1,48 @@
+import {App} from "../index";
+import {Plugin} from "../plugin";
+import {getAllModels} from "../layout/getAll";
+import {exportLayout} from "../layout/util";
+
+export const uninstall = (app: App, name: string) => {
+    app.plugins.find((plugin: Plugin, index) => {
+        if (plugin.name === name) {
+            // rm tab
+            const modelsKeys = Object.keys(plugin.models)
+            getAllModels().custom.forEach(custom => {
+                if (modelsKeys.includes(custom.type)) {
+                    custom.parent.parent.removeTab(custom.parent.id)
+                }
+            })
+            // rm topbar
+            plugin.topBarIcons.forEach(item => {
+                item.remove();
+            })
+            // rm dock
+            const docksKeys = Object.keys(plugin.docks)
+            docksKeys.forEach(key => {
+                if (Object.keys(window.siyuan.layout.leftDock.data).includes(key)) {
+                    window.siyuan.layout.leftDock.remove(key)
+                } else if (Object.keys(window.siyuan.layout.rightDock.data).includes(key)) {
+                    window.siyuan.layout.rightDock.remove(key)
+                } else if (Object.keys(window.siyuan.layout.bottomDock.data).includes(key)) {
+                    window.siyuan.layout.bottomDock.remove(key)
+                }
+            })
+            exportLayout({
+                reload: false,
+                onlyData: false,
+                errorExit: false
+            });
+            // rm listen
+            Array.from(document.childNodes).find(item => {
+                if (item.nodeType === 8 && item.textContent === name) {
+                    item.remove();
+                    return true;
+                }
+            })
+            // rm plugin
+            app.plugins.splice(index, 1)
+            return true
+        }
+    })
+}

+ 5 - 2
app/src/util/fetch.ts

@@ -29,11 +29,11 @@ export const fetchPost = (url: string, data?: any, cb?: (response: IWebSocketDat
     }
     fetch(url, init).then((response) => {
         if (response.status === 404) {
-            cb({
+            return {
                 data: null,
                 msg: response.statusText,
                 code: response.status,
-            });
+            };
         } else {
             if (response.headers.get("content-type").indexOf("application/json") > -1) {
                 return response.json();
@@ -48,6 +48,9 @@ export const fetchPost = (url: string, data?: any, cb?: (response: IWebSocketDat
             }
             return;
         }
+        if (typeof response.msg === "undefined") {
+            return;
+        }
         if (["/api/search/searchRefBlock", "/api/graph/getGraph", "/api/graph/getLocalGraph"].includes(url)) {
             if (response.data.reqId && window.siyuan.reqIds[url] && window.siyuan.reqIds[url] > response.data.reqId) {
                 return;