소스 검색

:recycle: fix https://github.com/siyuan-note/siyuan/pull/11733

Vanessa 1 년 전
부모
커밋
cd40ec50bb

+ 3 - 3
app/src/boot/globalEvent/keydown.ts

@@ -287,7 +287,7 @@ const editKeydown = (app: App, event: KeyboardEvent) => {
         event.preventDefault();
         return true;
     }
-    if (!isFileFocus && matchHotKey(window.siyuan.config.keymap.editor.general.quickMakeCard.custom, event)) {
+    if (!isFileFocus && matchHotKey(window.siyuan.config.keymap.editor.general.quickMakeCard.custom, event) && !window.siyuan.config.readonly) {
         if (protyle.title?.editElement.contains(range.startContainer)) {
             quickMakeCard(protyle, [protyle.title.element]);
         } else {
@@ -316,7 +316,7 @@ const editKeydown = (app: App, event: KeyboardEvent) => {
         event.preventDefault();
         return true;
     }
-    if (!isFileFocus && matchHotKey(window.siyuan.config.keymap.editor.general.spaceRepetition.custom, event)) {
+    if (!isFileFocus && matchHotKey(window.siyuan.config.keymap.editor.general.spaceRepetition.custom, event) && !window.siyuan.config.readonly) {
         fetchPost("/api/riff/getTreeRiffDueCards", {rootID: protyle.block.rootID}, (response) => {
             openCardByData(app, response.data, "doc", protyle.block.rootID, protyle.title?.editElement.textContent || window.siyuan.languages.untitled);
         });
@@ -593,7 +593,7 @@ const fileTreeKeydown = (app: App, event: KeyboardEvent) => {
     const pathString = liElements[0].getAttribute("data-path");
     const isFile = liElements[0].getAttribute("data-type") === "navigation-file";
 
-    if (matchHotKey(window.siyuan.config.keymap.editor.general.spaceRepetition.custom, event)) {
+    if (matchHotKey(window.siyuan.config.keymap.editor.general.spaceRepetition.custom, event) && !window.siyuan.config.readonly) {
         if (isFile) {
             const id = liElements[0].getAttribute("data-node-id");
             fetchPost("/api/riff/getTreeRiffDueCards", {rootID: id}, (response) => {

+ 3 - 0
app/src/card/openCard.ts

@@ -672,6 +672,9 @@ const emitEvent = (app: App, card: ICard, type: string) => {
 };
 
 export const openCard = (app: App) => {
+    if (window.siyuan.config.readonly) {
+        return
+    }
     fetchPost("/api/riff/getRiffDueCards", {deckID: ""}, (cardsResponse) => {
         openCardByData(app, cardsResponse.data, "all");
     });

+ 4 - 6
app/src/config/editor.ts

@@ -310,12 +310,10 @@ export const editor = {
         if (fontFamilyElement.tagName === "SELECT") {
             let fontFamilyHTML = `<option value="">${window.siyuan.languages.default}</option>`;
             fetchPost("/api/system/getSysFonts", {}, (response) => {
-                if (response.code === 0) {
-                    response.data.forEach((item: string) => {
-                        fontFamilyHTML += `<option value="${item}"${window.siyuan.config.editor.fontFamily === item ? " selected" : ""}>${item}</option>`;
-                    });
-                    fontFamilyElement.innerHTML = fontFamilyHTML;
-                }
+                response.data.forEach((item: string) => {
+                    fontFamilyHTML += `<option value="${item}"${window.siyuan.config.editor.fontFamily === item ? " selected" : ""}>${item}</option>`;
+                });
+                fontFamilyElement.innerHTML = fontFamilyHTML;
             });
         }
         editor.element.querySelector("#clearHistory").addEventListener("click", () => {

+ 14 - 32
app/src/index.ts

@@ -38,8 +38,6 @@ export class App {
         registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`);
         /// #endif
         addBaseURL();
-        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"),
 
         this.appId = Constants.SIYUAN_APPID;
         window.siyuan = {
@@ -160,40 +158,24 @@ export class App {
         };
 
         fetchPost("/api/system/getConf", {}, async (response) => {
+            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");
             window.siyuan.config = response.data.conf;
-
-            const promises = [
-                loadPlugins(this),
-                new Promise<void>(resolve => getLocalStorage(resolve)),
-                new Promise<void>(resolve => fetchGet(
-                    `/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`,
-                    (lauguages: IObject) => {
-                        window.siyuan.languages = lauguages;
-                        resolve();
-                    },
-                )),
-            ];
-
-            if (!window.siyuan.config.readonly) {
-                promises.push(new Promise<void>(resolve => {
+            await loadPlugins(this);
+            getLocalStorage(() => {
+                fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages: IObject) => {
+                    window.siyuan.languages = lauguages;
+                    window.siyuan.menus = new Menus(this);
+                    bootSync();
                     fetchPost("/api/setting/getCloudUser", {}, userResponse => {
                         window.siyuan.user = userResponse.data;
-                        resolve();
+                        onGetConfig(response.data.start, this);
+                        account.onSetaccount();
+                        setTitle(window.siyuan.languages.siyuanNote);
+                        initMessage();
                     });
-                }));
-            }
-
-            await Promise.all(promises);
-
-            if (!window.siyuan.config.readonly) {
-                bootSync();
-            }
-
-            window.siyuan.menus = new Menus(this);
-            onGetConfig(response.data.start, this);
-            account.onSetaccount();
-            setTitle(window.siyuan.languages.siyuanNote);
-            initMessage();
+                });
+            });
         });
         setNoteBook();
         initBlockPopover(this);

+ 2 - 2
app/src/layout/Wnd.ts

@@ -67,7 +67,7 @@ export class Wnd {
         <ul class="fn__flex layout-tab-bar"></ul>
         <ul class="layout-tab-bar layout-tab-bar--readonly fn__flex-1">
             <li class="item item--readonly">
-                <span data-type="new" class="block__icon block__icon--show ariaLabel" aria-label="${window.siyuan.languages.newFile}"><svg><use xlink:href="#iconAdd"></use></svg></span>
+                <span data-type="new" class="block__icon block__icon--show ariaLabel${window.siyuan.config.readonly ? " fn__none" : ""}" aria-label="${window.siyuan.languages.newFile}"><svg><use xlink:href="#iconAdd"></use></svg></span>
                 <span class="fn__flex-1"></span>
                 <span data-type="more" data-menu="true" class="block__icon block__icon--show ariaLabel" aria-label="${window.siyuan.languages.switchTab}"><svg><use xlink:href="#iconDown"></use></svg></span>
             </li>
@@ -105,7 +105,7 @@ export class Wnd {
         this.headersElement.parentElement.addEventListener("click", (event) => {
             let target = event.target as HTMLElement;
             while (target && !target.isEqualNode(this.headersElement)) {
-                if (target.classList.contains("block__icon") && target.getAttribute("data-type") === "new" && !window.siyuan.config.readonly) {
+                if (target.classList.contains("block__icon") && target.getAttribute("data-type") === "new") {
                     setPanelFocus(this.headersElement.parentElement.parentElement);
                     newFile({
                         app,

+ 10 - 12
app/src/layout/status.ts

@@ -4,7 +4,7 @@ import {hasClosestByClassName} from "../protyle/util/hasClosest";
 import {fetchPost} from "../util/fetch";
 import {mountHelp} from "../util/mount";
 /// #if !BROWSER
-import { ipcRenderer } from "electron";
+import {ipcRenderer} from "electron";
 /// #endif
 /// #endif
 import {MenuItem} from "../menus/Menu";
@@ -64,16 +64,14 @@ export const initStatus = (isWindow = false) => {
                 }
                 window.siyuan.menus.menu.remove();
                 window.siyuan.menus.menu.element.setAttribute("data-name", "statusHelp");
-                if (!isIPad()) {
-                    window.siyuan.menus.menu.append(new MenuItem({
-                        label: window.siyuan.languages.userGuide,
-                        icon: "iconHelp",
-                        disabled: window.siyuan.config.readonly,
-                        click: () => {
-                            mountHelp();
-                        }
-                    }).element);
-                }
+                window.siyuan.menus.menu.append(new MenuItem({
+                    label: window.siyuan.languages.userGuide,
+                    icon: "iconHelp",
+                    ignore: isIPad() || window.siyuan.config.readonly,
+                    click: () => {
+                        mountHelp();
+                    }
+                }).element);
                 window.siyuan.menus.menu.append(new MenuItem({
                     label: window.siyuan.languages.feedback,
                     icon: "iconFeedback",
@@ -198,7 +196,7 @@ export const renderStatusbarCounter = (stat: {
     imageCount: number,
     refCount: number
 }) => {
-    if(!stat) {
+    if (!stat) {
         return;
     }
     let html = `<span class="ft__on-surface">${window.siyuan.languages.runeCount}</span>&nbsp;${stat.runeCount}<span class="fn__space"></span>

+ 1 - 1
app/src/layout/tabUtil.ts

@@ -192,7 +192,7 @@ export const newCenterEmptyTab = (app: App) => {
         <svg class="b3-list-item__graphic"><use xlink:href="#iconFilesRoot"></use></svg>
         <span>${window.siyuan.languages.newNotebook}</span>
     </div>
-    <div class="b3-list-item${isIPad() ? " fn__none" : ""}" id="editorEmptyHelp">
+    <div class="b3-list-item${(isIPad() || window.siyuan.config.readonly) ? " fn__none" : ""}" id="editorEmptyHelp">
         <svg class="b3-list-item__graphic"><use xlink:href="#iconHelp"></use></svg>
         <span>${window.siyuan.languages.userGuide}</span>
     </div>

+ 9 - 11
app/src/layout/topBar.ts

@@ -301,17 +301,15 @@ export const setZoom = (type: "zoomIn" | "zoomOut" | "restore") => {
 
 const openPlugin = (app: App, target: Element) => {
     const menu = new Menu("topBarPlugin");
-    if (!isHuawei()) {
-        menu.addItem({
-            icon: "iconSettings",
-            label: window.siyuan.languages.manage,
-            disabled: window.siyuan.config.readonly,
-            click() {
-                openSetting(app).element.querySelector('.b3-tab-bar [data-name="bazaar"]').dispatchEvent(new CustomEvent("click"));
-            }
-        });
-        menu.addSeparator();
-    }
+    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

+ 3 - 0
app/src/menus/Menu.ts

@@ -165,6 +165,9 @@ export class MenuItem {
     public element: HTMLElement;
 
     constructor(options: IMenu) {
+        if (options.ignore) {
+            return;
+        }
         if (options.type === "empty") {
             this.element = document.createElement("div");
             this.element.innerHTML = options.label;

+ 1 - 3
app/src/menus/commonMenuItem.ts

@@ -448,7 +448,6 @@ export const exportMd = (id: string) => {
             label: window.siyuan.languages.template,
             iconClass: "ft__error",
             icon: "iconMarkdown",
-            disabled: window.siyuan.config.readonly,
             click: async () => {
                 const result = await fetchSyncPost("/api/block/getRefText", {id: id});
 
@@ -508,9 +507,8 @@ export const exportMd = (id: string) => {
                                 });
                             });
                             return;
-                        } else if (response.code === 0) {
-                            showMessage(window.siyuan.languages.exportTplSucc);
                         }
+                        showMessage(window.siyuan.languages.exportTplSucc);
                     });
                     dialog.destroy();
                 });

+ 140 - 134
app/src/menus/navigation.ts

@@ -73,51 +73,53 @@ const initMultiMenu = (selectItemElements: NodeListOf<Element>, app: App) => {
         return window.siyuan.menus.menu;
     }
     window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
-    const riffCardMenu = [{
-        iconHTML: "",
-        accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
-        label: window.siyuan.languages.quickMakeCard,
-        click: () => {
-            transaction(undefined, [{
-                action: "addFlashcards",
-                deckID: Constants.QUICK_DECK_ID,
-                blockIDs,
-            }], [{
-                action: "removeFlashcards",
-                deckID: Constants.QUICK_DECK_ID,
-                blockIDs,
-            }]);
-        }
-    }, {
-        iconHTML: "",
-        label: window.siyuan.languages.removeCard,
-        click: () => {
-            transaction(undefined, [{
-                action: "removeFlashcards",
-                deckID: Constants.QUICK_DECK_ID,
-                blockIDs,
-            }], [{
-                action: "addFlashcards",
-                deckID: Constants.QUICK_DECK_ID,
-                blockIDs,
-            }]);
-        }
-    }];
-    if (window.siyuan.config.flashcard.deck) {
-        riffCardMenu.push({
+    if (!window.siyuan.config.readonly) {
+        const riffCardMenu = [{
             iconHTML: "",
-            label: window.siyuan.languages.addToDeck,
+            accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
+            label: window.siyuan.languages.quickMakeCard,
             click: () => {
-                makeCard(app, blockIDs);
+                transaction(undefined, [{
+                    action: "addFlashcards",
+                    deckID: Constants.QUICK_DECK_ID,
+                    blockIDs,
+                }], [{
+                    action: "removeFlashcards",
+                    deckID: Constants.QUICK_DECK_ID,
+                    blockIDs,
+                }]);
             }
-        });
+        }, {
+            iconHTML: "",
+            label: window.siyuan.languages.removeCard,
+            click: () => {
+                transaction(undefined, [{
+                    action: "removeFlashcards",
+                    deckID: Constants.QUICK_DECK_ID,
+                    blockIDs,
+                }], [{
+                    action: "addFlashcards",
+                    deckID: Constants.QUICK_DECK_ID,
+                    blockIDs,
+                }]);
+            }
+        }];
+        if (window.siyuan.config.flashcard.deck) {
+            riffCardMenu.push({
+                iconHTML: "",
+                label: window.siyuan.languages.addToDeck,
+                click: () => {
+                    makeCard(app, blockIDs);
+                }
+            });
+        }
+        window.siyuan.menus.menu.append(new MenuItem({
+            label: window.siyuan.languages.riffCard,
+            icon: "iconRiffCard",
+            submenu: riffCardMenu,
+        }).element);
+        window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
     }
-    window.siyuan.menus.menu.append(new MenuItem({
-        label: window.siyuan.languages.riffCard,
-        icon: "iconRiffCard",
-        submenu: riffCardMenu,
-    }).element);
-    window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
     openEditorTab(app, blockIDs);
     if (app.plugins) {
         emitOpenMenu({
@@ -201,33 +203,35 @@ export const initNavigationMenu = (app: App, liElement: HTMLElement) => {
             submenu: subMenu,
         }).element);
     }
-    window.siyuan.menus.menu.append(new MenuItem({
-        label: window.siyuan.languages.riffCard,
-        type: "submenu",
-        icon: "iconRiffCard",
-        submenu: [{
-            iconHTML: "",
-            label: window.siyuan.languages.spaceRepetition,
-            accelerator: window.siyuan.config.keymap.editor.general.spaceRepetition.custom,
-            click: () => {
-                fetchPost("/api/riff/getNotebookRiffDueCards", {notebook: notebookId}, (response) => {
-                    openCardByData(app, response.data, "notebook", notebookId, name);
-                });
-                /// #if MOBILE
-                closePanel();
-                /// #endif
-            }
-        }, {
-            iconHTML: "",
-            label: window.siyuan.languages.manage,
-            click: () => {
-                viewCards(app, notebookId, name, "Notebook");
-                /// #if MOBILE
-                closePanel();
-                /// #endif
-            }
-        }],
-    }).element);
+    if (!window.siyuan.config.readonly) {
+        window.siyuan.menus.menu.append(new MenuItem({
+            label: window.siyuan.languages.riffCard,
+            type: "submenu",
+            icon: "iconRiffCard",
+            submenu: [{
+                iconHTML: "",
+                label: window.siyuan.languages.spaceRepetition,
+                accelerator: window.siyuan.config.keymap.editor.general.spaceRepetition.custom,
+                click: () => {
+                    fetchPost("/api/riff/getNotebookRiffDueCards", {notebook: notebookId}, (response) => {
+                        openCardByData(app, response.data, "notebook", notebookId, name);
+                    });
+                    /// #if MOBILE
+                    closePanel();
+                    /// #endif
+                }
+            }, {
+                iconHTML: "",
+                label: window.siyuan.languages.manage,
+                click: () => {
+                    viewCards(app, notebookId, name, "Notebook");
+                    /// #if MOBILE
+                    closePanel();
+                    /// #endif
+                }
+            }],
+        }).element);
+    }
     window.siyuan.menus.menu.append(new MenuItem({
         label: window.siyuan.languages.search,
         accelerator: window.siyuan.config.keymap.general.search.custom,
@@ -471,76 +475,78 @@ export const initFileMenu = (app: App, notebookId: string, pathString: string, l
                 });
             }
         }).element);
-        const riffCardMenu = [{
-            iconHTML: "",
-            label: window.siyuan.languages.spaceRepetition,
-            accelerator: window.siyuan.config.keymap.editor.general.spaceRepetition.custom,
-            click: () => {
-                fetchPost("/api/riff/getTreeRiffDueCards", {rootID: id}, (response) => {
-                    openCardByData(app, response.data, "doc", id, name);
-                });
-                /// #if MOBILE
-                closePanel();
-                /// #endif
-            }
-        }, {
-            iconHTML: "",
-            label: window.siyuan.languages.manage,
-            click: () => {
-                fetchPost("/api/filetree/getHPathByID", {
-                    id
-                }, (response) => {
-                    viewCards(app, id, pathPosix().join(getNotebookName(notebookId), response.data), "Tree");
-                });
-                /// #if MOBILE
-                closePanel();
-                /// #endif
-            }
-        }, {
-            iconHTML: "",
-            accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
-            label: window.siyuan.languages.quickMakeCard,
-            click: () => {
-                transaction(undefined, [{
-                    action: "addFlashcards",
-                    deckID: Constants.QUICK_DECK_ID,
-                    blockIDs: [id]
-                }], [{
-                    action: "removeFlashcards",
-                    deckID: Constants.QUICK_DECK_ID,
-                    blockIDs: [id]
-                }]);
-            }
-        }, {
-            iconHTML: "",
-            label: window.siyuan.languages.removeCard,
-            click: () => {
-                transaction(undefined, [{
-                    action: "removeFlashcards",
-                    deckID: Constants.QUICK_DECK_ID,
-                    blockIDs: [id]
-                }], [{
-                    action: "addFlashcards",
-                    deckID: Constants.QUICK_DECK_ID,
-                    blockIDs: [id]
-                }]);
-            }
-        }];
-        if (window.siyuan.config.flashcard.deck) {
-            riffCardMenu.push({
+        if (!window.siyuan.config.readonly) {
+            const riffCardMenu = [{
                 iconHTML: "",
-                label: window.siyuan.languages.addToDeck,
+                label: window.siyuan.languages.spaceRepetition,
+                accelerator: window.siyuan.config.keymap.editor.general.spaceRepetition.custom,
                 click: () => {
-                    makeCard(app, [id]);
+                    fetchPost("/api/riff/getTreeRiffDueCards", {rootID: id}, (response) => {
+                        openCardByData(app, response.data, "doc", id, name);
+                    });
+                    /// #if MOBILE
+                    closePanel();
+                    /// #endif
                 }
-            });
+            }, {
+                iconHTML: "",
+                label: window.siyuan.languages.manage,
+                click: () => {
+                    fetchPost("/api/filetree/getHPathByID", {
+                        id
+                    }, (response) => {
+                        viewCards(app, id, pathPosix().join(getNotebookName(notebookId), response.data), "Tree");
+                    });
+                    /// #if MOBILE
+                    closePanel();
+                    /// #endif
+                }
+            }, {
+                iconHTML: "",
+                accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
+                label: window.siyuan.languages.quickMakeCard,
+                click: () => {
+                    transaction(undefined, [{
+                        action: "addFlashcards",
+                        deckID: Constants.QUICK_DECK_ID,
+                        blockIDs: [id]
+                    }], [{
+                        action: "removeFlashcards",
+                        deckID: Constants.QUICK_DECK_ID,
+                        blockIDs: [id]
+                    }]);
+                }
+            }, {
+                iconHTML: "",
+                label: window.siyuan.languages.removeCard,
+                click: () => {
+                    transaction(undefined, [{
+                        action: "removeFlashcards",
+                        deckID: Constants.QUICK_DECK_ID,
+                        blockIDs: [id]
+                    }], [{
+                        action: "addFlashcards",
+                        deckID: Constants.QUICK_DECK_ID,
+                        blockIDs: [id]
+                    }]);
+                }
+            }];
+            if (window.siyuan.config.flashcard.deck) {
+                riffCardMenu.push({
+                    iconHTML: "",
+                    label: window.siyuan.languages.addToDeck,
+                    click: () => {
+                        makeCard(app, [id]);
+                    }
+                });
+            }
+            window.siyuan.menus.menu.append(new MenuItem({
+                label: window.siyuan.languages.riffCard,
+                type: "submenu",
+                icon: "iconRiffCard",
+                submenu: riffCardMenu,
+            }).element);
         }
-        window.siyuan.menus.menu.append(new MenuItem({
-            label: window.siyuan.languages.riffCard,
-            type: "submenu",
-            icon: "iconRiffCard",
-            submenu: riffCardMenu,
-        }).element);
         window.siyuan.menus.menu.append(new MenuItem({
             label: window.siyuan.languages.search,
             icon: "iconSearch",

+ 29 - 29
app/src/menus/workspace.ts

@@ -391,25 +391,27 @@ export const workspaceMenu = (app: App, rect: DOMRect) => {
                     submenu
                 }).element);
             }
-            window.siyuan.menus.menu.append(new MenuItem({
-                label: window.siyuan.languages.riffCard,
-                type: "submenu",
-                icon: "iconRiffCard",
-                submenu: [{
-                    iconHTML: "",
-                    label: window.siyuan.languages.spaceRepetition,
-                    accelerator: window.siyuan.config.keymap.general.riffCard.custom,
-                    click: () => {
-                        openCard(app);
-                    }
-                }, {
-                    iconHTML: "",
-                    label: window.siyuan.languages.manage,
-                    click: () => {
-                        viewCards(app, "", window.siyuan.languages.all, "");
-                    }
-                }],
-            }).element);
+            if (!window.siyuan.config.readonly) {
+                window.siyuan.menus.menu.append(new MenuItem({
+                    label: window.siyuan.languages.riffCard,
+                    type: "submenu",
+                    icon: "iconRiffCard",
+                    submenu: [{
+                        iconHTML: "",
+                        label: window.siyuan.languages.spaceRepetition,
+                        accelerator: window.siyuan.config.keymap.general.riffCard.custom,
+                        click: () => {
+                            openCard(app);
+                        }
+                    }, {
+                        iconHTML: "",
+                        label: window.siyuan.languages.manage,
+                        click: () => {
+                            viewCards(app, "", window.siyuan.languages.all, "");
+                        }
+                    }],
+                }).element);
+            }
             window.siyuan.menus.menu.append(new MenuItem({
                 label: window.siyuan.languages.recentDocs,
                 icon: "iconFile",
@@ -436,16 +438,14 @@ export const workspaceMenu = (app: App, rect: DOMRect) => {
             }).element);
             window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
         }
-        if (!isIPad()) {
-            window.siyuan.menus.menu.append(new MenuItem({
-                label: window.siyuan.languages.userGuide,
-                icon: "iconHelp",
-                disabled: window.siyuan.config.readonly,
-                click: () => {
-                    mountHelp();
-                }
-            }).element);
-        }
+        window.siyuan.menus.menu.append(new MenuItem({
+            label: window.siyuan.languages.userGuide,
+            icon: "iconHelp",
+            ignore: isIPad() || window.siyuan.config.readonly,
+            click: () => {
+                mountHelp();
+            }
+        }).element);
         window.siyuan.menus.menu.append(new MenuItem({
             label: window.siyuan.languages.feedback,
             icon: "iconFeedback",

+ 26 - 49
app/src/mobile/index.ts

@@ -38,9 +38,6 @@ class App {
             registerServiceWorker(`${Constants.SERVICE_WORKER_PATH}?v=${Constants.SIYUAN_VERSION}`);
         }
         addBaseURL();
-        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");
-
         this.appId = Constants.SIYUAN_APPID;
         window.siyuan = {
             zIndex: 10,
@@ -88,9 +85,34 @@ class App {
             updateCardHV();
         });
         fetchPost("/api/system/getConf", {}, async (confResponse) => {
+            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");
             window.siyuan.config = confResponse.data.conf;
             correctHotkey(siyuanApp);
-
+            await loadPlugins(this);
+            getLocalStorage(() => {
+                fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages: IObject) => {
+                    window.siyuan.languages = lauguages;
+                    window.siyuan.menus = new Menus(this);
+                    document.title = window.siyuan.languages.siyuanNote;
+                    bootSync();
+                    loadAssets(confResponse.data.conf.appearance);
+                    initMessage();
+                    initAssets();
+                    fetchPost("/api/setting/getCloudUser", {}, userResponse => {
+                        window.siyuan.user = userResponse.data;
+                        fetchPost("/api/system/getEmojiConf", {}, emojiResponse => {
+                            window.siyuan.emojis = emojiResponse.data as IEmoji[];
+                            setNoteBook(() => {
+                                initFramework(this, confResponse.data.start);
+                                initRightMenu(this);
+                                openChangelog();
+                            });
+                        });
+                    });
+                    addGA();
+                });
+            });
             document.addEventListener("touchstart", handleTouchStart, false);
             document.addEventListener("touchmove", handleTouchMove, false);
             document.addEventListener("touchend", (event) => {
@@ -118,51 +140,6 @@ class App {
                     }
                 }
             });
-
-            const promises = [
-                loadPlugins(this),
-                new Promise<void>(resolve => getLocalStorage(resolve)),
-                new Promise<void>(resolve => fetchGet(
-                    `/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`,
-                    (lauguages: IObject) => {
-                        window.siyuan.languages = lauguages;
-                        resolve();
-                    },
-                )),
-                new Promise<void>(resolve => {
-                    fetchPost("/api/setting/getEmojiConf", {}, emojiResponse => {
-                        window.siyuan.emojis = emojiResponse.data as IEmoji[];
-                        resolve();
-                    });
-                }),
-            ];
-
-            if (!window.siyuan.config.readonly) {
-                promises.push(new Promise<void>(resolve => {
-                    fetchPost("/api/setting/getCloudUser", {}, userResponse => {
-                        window.siyuan.user = userResponse.data;
-                        resolve();
-                    });
-                }));
-            }
-
-            await Promise.all(promises);
-
-            if (!window.siyuan.config.readonly) {
-                bootSync();
-            }
-
-            window.siyuan.menus = new Menus(this);
-            document.title = window.siyuan.languages.siyuanNote;
-            loadAssets(confResponse.data.conf.appearance);
-            initMessage();
-            initAssets();
-            setNoteBook(() => {
-                initFramework(this, confResponse.data.start);
-                initRightMenu(this);
-                openChangelog();
-            });
-            addGA();
         });
     }
 }

+ 1 - 1
app/src/mobile/menu/index.ts

@@ -112,7 +112,7 @@ export const initRightMenu = (app: App) => {
         <svg class="b3-menu__icon"><use xlink:href="#iconPlugin"></use></svg><span class="b3-menu__label">${window.siyuan.languages.plugin}</span>
     </div>
     <div class="b3-menu__separator"></div>
-    <div class="b3-menu__item${isIPhone() ? " fn__none" : ""}" id="menuHelp">
+    <div class="b3-menu__item${(isIPhone() || window.siyuan.config.readonly) ? " fn__none" : ""}" id="menuHelp">
         <svg class="b3-menu__icon"><use xlink:href="#iconHelp"></use></svg><span class="b3-menu__label">${window.siyuan.languages.userGuide}</span>
     </div>
     <a class="b3-menu__item" href="${"zh_CN" === window.siyuan.config.lang || "zh_CHT" === window.siyuan.config.lang ? "https://ld246.com/article/1649901726096" : "https://liuyun.io/article/1686530886208"}" target="_blank">

+ 1 - 1
app/src/mobile/util/setEmpty.ts

@@ -32,7 +32,7 @@ export const setEmpty = (app: App) => {
 <div class="b3-list-item" id="emptyNewNotebook${window.siyuan.config.readonly ? " fn__none" : ""}">
     <svg class="b3-list-item__graphic"><use xlink:href="#iconFilesRoot"></use></svg><span class="fn__space"></span><span class="b3-list-item__text">${window.siyuan.languages.newNotebook}</span>
 </div>
-<div class="b3-list-item${isIPhone() ? " fn__none" : ""}" id="emptyHelp">
+<div class="b3-list-item${(isIPhone() || window.siyuan.config.readonly) ? " fn__none" : ""}" id="emptyHelp">
     <svg class="b3-list-item__graphic"><use xlink:href="#iconHelp"></use></svg><span class="fn__space"></span><span class="b3-list-item__text">${window.siyuan.languages.userGuide}</span>
 </div>`;
     emptyElement.addEventListener("click", (event) => {

+ 4 - 1
app/src/plugin/Menu.ts

@@ -34,7 +34,10 @@ export class Menu {
         return this.menu.addItem(option);
     }
 
-    addSeparator(index?: number) {
+    addSeparator(index?: number, ignore = false) {
+        if (ignore) {
+            return;
+        }
         if (this.isOpen) {
             return;
         }

+ 23 - 24
app/src/protyle/gutter/index.ts

@@ -104,7 +104,7 @@ export class Gutter {
                     const gutterNodeElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${gutterId}"]`)
                     if (gutterNodeElement) {
                         selectElements.forEach((item => {
-                           item.classList.remove("protyle-wysiwyg--select")
+                            item.classList.remove("protyle-wysiwyg--select")
                         }));
                         gutterNodeElement.classList.add("protyle-wysiwyg--select")
                         selectElements = [gutterNodeElement]
@@ -797,20 +797,21 @@ export class Gutter {
         }
         this.genAlign(selectsElement, protyle);
         this.genWidths(selectsElement, protyle);
-        window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
-        window.siyuan.menus.menu.append(new MenuItem({
-            label: window.siyuan.languages.quickMakeCard,
-            accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
-            iconHTML: '<svg class="b3-menu__icon" style="color:var(--b3-theme-primary)"><use xlink:href="#iconRiffCard"></use></svg>',
-            icon: "iconRiffCard",
-            click() {
-                quickMakeCard(protyle, selectsElement);
-            }
-        }).element);
-        if (window.siyuan.config.flashcard.deck) {
+        if (!window.siyuan.config.readonly) {
+            window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
+            window.siyuan.menus.menu.append(new MenuItem({
+                label: window.siyuan.languages.quickMakeCard,
+                accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
+                iconHTML: '<svg class="b3-menu__icon" style="color:var(--b3-theme-primary)"><use xlink:href="#iconRiffCard"></use></svg>',
+                icon: "iconRiffCard",
+                click() {
+                    quickMakeCard(protyle, selectsElement);
+                }
+            }).element);
             window.siyuan.menus.menu.append(new MenuItem({
                 label: window.siyuan.languages.addToDeck,
                 icon: "iconRiffCard",
+                ignore: !window.siyuan.config.flashcard.deck,
                 click() {
                     const ids: string[] = [];
                     selectsElement.forEach(item => {
@@ -1667,32 +1668,30 @@ export class Gutter {
             window.siyuan.menus.menu.append(new MenuItem({
                 label: window.siyuan.languages.wechatReminder,
                 icon: "iconMp",
-                disabled: window.siyuan.config.readonly,
+                ignore: window.siyuan.config.readonly,
                 click() {
                     openWechatNotify(nodeElement);
                 }
             }).element);
         }
-        if (type !== "NodeThematicBreak") {
+        if (type !== "NodeThematicBreak" && !window.siyuan.config.readonly) {
             window.siyuan.menus.menu.append(new MenuItem({
                 label: window.siyuan.languages.quickMakeCard,
                 accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
                 iconHTML: '<svg class="b3-menu__icon" style="color:var(--b3-theme-primary)"><use xlink:href="#iconRiffCard"></use></svg>',
                 icon: "iconRiffCard",
-                disabled: window.siyuan.config.readonly,
                 click() {
                     quickMakeCard(protyle, [nodeElement]);
                 }
             }).element);
-            if (window.siyuan.config.flashcard.deck) {
-                window.siyuan.menus.menu.append(new MenuItem({
-                    label: window.siyuan.languages.addToDeck,
-                    icon: "iconRiffCard",
-                    click() {
-                        makeCard(protyle.app, [id]);
-                    }
-                }).element);
-            }
+            window.siyuan.menus.menu.append(new MenuItem({
+                label: window.siyuan.languages.addToDeck,
+                ignore: !window.siyuan.config.flashcard.deck,
+                icon: "iconRiffCard",
+                click() {
+                    makeCard(protyle.app, [id]);
+                }
+            }).element);
             window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
         }
 

+ 52 - 57
app/src/protyle/header/openTitleMenu.ts

@@ -109,68 +109,63 @@ export const openTitleMenu = (protyle: IProtyle, position: IPosition) => {
                 openFileAttr(response.data.ial, "bookmark", protyle);
             }
         }).element);
-        window.siyuan.menus.menu.append(new MenuItem({
-            label: window.siyuan.languages.wechatReminder,
-            icon: "iconMp",
-            disabled: window.siyuan.config.readonly,
-            click() {
-                openFileWechatNotify(protyle);
-            }
-        }).element);
-        const riffCardMenu = [{
-            iconHTML: "",
-            label: window.siyuan.languages.spaceRepetition,
-            accelerator: window.siyuan.config.keymap.editor.general.spaceRepetition.custom,
-            disabled: window.siyuan.config.readonly,
-            click: () => {
-                fetchPost("/api/riff/getTreeRiffDueCards", {rootID: protyle.block.rootID}, (response) => {
-                    openCardByData(protyle.app, response.data, "doc", protyle.block.rootID, response.data.name);
-                });
-            }
-        }, {
-            iconHTML: "",
-            label: window.siyuan.languages.manage,
-            disabled: window.siyuan.config.readonly,
-            click: () => {
-                fetchPost("/api/filetree/getHPathByID", {
-                    id: protyle.block.rootID
-                }, (response) => {
-                    viewCards(protyle.app, protyle.block.rootID, pathPosix().join(getNotebookName(protyle.notebookId), (response.data)), "Tree");
-                });
-            }
-        }, {
-            iconHTML: "",
-            label: window.siyuan.languages.quickMakeCard,
-            accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
-            disabled: window.siyuan.config.readonly,
-            click: () => {
-                let titleElement = protyle.title?.element;
-                if (!titleElement) {
-                    titleElement = document.createElement("div");
-                    titleElement.setAttribute("data-node-id", protyle.block.rootID);
-                    titleElement.setAttribute(Constants.CUSTOM_RIFF_DECKS, response.data.ial[Constants.CUSTOM_RIFF_DECKS]);
+        if (!window.siyuan.config.readonly) {
+            window.siyuan.menus.menu.append(new MenuItem({
+                label: window.siyuan.languages.wechatReminder,
+                icon: "iconMp",
+                click() {
+                    openFileWechatNotify(protyle);
                 }
-                quickMakeCard(protyle, [titleElement]);
-            }
-        }];
-        if (window.siyuan.config.flashcard.deck) {
-            riffCardMenu.push({
+            }).element);
+            const riffCardMenu: IMenu[] = [{
                 iconHTML: "",
-                label: window.siyuan.languages.addToDeck,
-                disabled: window.siyuan.config.readonly,
+                label: window.siyuan.languages.spaceRepetition,
+                accelerator: window.siyuan.config.keymap.editor.general.spaceRepetition.custom,
                 click: () => {
-                    makeCard(protyle.app, [protyle.block.rootID]);
+                    fetchPost("/api/riff/getTreeRiffDueCards", {rootID: protyle.block.rootID}, (response) => {
+                        openCardByData(protyle.app, response.data, "doc", protyle.block.rootID, response.data.name);
+                    });
                 }
-            });
+            }, {
+                iconHTML: "",
+                label: window.siyuan.languages.manage,
+                click: () => {
+                    fetchPost("/api/filetree/getHPathByID", {
+                        id: protyle.block.rootID
+                    }, (response) => {
+                        viewCards(protyle.app, protyle.block.rootID, pathPosix().join(getNotebookName(protyle.notebookId), (response.data)), "Tree");
+                    });
+                }
+            }, {
+                iconHTML: "",
+                label: window.siyuan.languages.quickMakeCard,
+                accelerator: window.siyuan.config.keymap.editor.general.quickMakeCard.custom,
+                click: () => {
+                    let titleElement = protyle.title?.element;
+                    if (!titleElement) {
+                        titleElement = document.createElement("div");
+                        titleElement.setAttribute("data-node-id", protyle.block.rootID);
+                        titleElement.setAttribute(Constants.CUSTOM_RIFF_DECKS, response.data.ial[Constants.CUSTOM_RIFF_DECKS]);
+                    }
+                    quickMakeCard(protyle, [titleElement]);
+                }
+            }];
+            if (window.siyuan.config.flashcard.deck) {
+                riffCardMenu.push({
+                    iconHTML: "",
+                    label: window.siyuan.languages.addToDeck,
+                    click: () => {
+                        makeCard(protyle.app, [protyle.block.rootID]);
+                    }
+                });
+            }
+            window.siyuan.menus.menu.append(new MenuItem({
+                label: window.siyuan.languages.riffCard,
+                type: "submenu",
+                icon: "iconRiffCard",
+                submenu: riffCardMenu,
+            }).element);
         }
-        window.siyuan.menus.menu.append(new MenuItem({
-            label: window.siyuan.languages.riffCard,
-            type: "submenu",
-            icon: "iconRiffCard",
-            submenu: riffCardMenu,
-            disabled: window.siyuan.config.readonly,
-        }).element);
-
         window.siyuan.menus.menu.append(new MenuItem({
             label: window.siyuan.languages.search,
             icon: "iconSearch",

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

@@ -702,6 +702,7 @@ interface IMenu {
     bind?: (element: HTMLElement) => void
     index?: number
     element?: HTMLElement
+    ignore?: boolean
 }
 
 interface IBazaarItem {

+ 2 - 4
app/src/util/assets.ts

@@ -150,10 +150,8 @@ export const initAssets = () => {
                     return;
                 }
             }
-            if (response.code === 0) {
-                window.siyuan.config.appearance = response.data.appearance;
-                loadAssets(response.data.appearance);
-            }
+            window.siyuan.config.appearance = response.data.appearance;
+            loadAssets(response.data.appearance);
         });
     });
 };

+ 12 - 28
app/src/window/index.ts

@@ -28,9 +28,6 @@ class App {
 
     constructor() {
         addBaseURL();
-        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");
-
         this.appId = Constants.SIYUAN_APPID;
         window.siyuan = {
             zIndex: 10,
@@ -146,35 +143,22 @@ class App {
             }),
         };
         fetchPost("/api/system/getConf", {}, async (response) => {
+            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");
             window.siyuan.config = response.data.conf;
-
-            const promises = [
-                loadPlugins(this),
-                new Promise<void>(resolve => getLocalStorage(resolve)),
-                new Promise<void>(resolve => fetchGet(
-                    `/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`,
-                    (lauguages: IObject) => {
-                        window.siyuan.languages = lauguages;
-                        resolve();
-                    },
-                )),
-            ];
-
-            if (!window.siyuan.config.readonly) {
-                promises.push(new Promise<void>(resolve => {
+            await loadPlugins(this);
+            getLocalStorage(() => {
+                fetchGet(`/appearance/langs/${window.siyuan.config.appearance.lang}.json?v=${Constants.SIYUAN_VERSION}`, (lauguages: IObject) => {
+                    window.siyuan.languages = lauguages;
+                    window.siyuan.menus = new Menus(this);
                     fetchPost("/api/setting/getCloudUser", {}, userResponse => {
                         window.siyuan.user = userResponse.data;
-                        resolve();
+                        init(this);
+                        setTitle(window.siyuan.languages.siyuanNote);
+                        initMessage();
                     });
-                }));
-            }
-
-            await Promise.all(promises);
-
-            window.siyuan.menus = new Menus(this);
-            init(this);
-            setTitle(window.siyuan.languages.siyuanNote);
-            initMessage();
+                });
+            });
         });
         setNoteBook();
         initBlockPopover(this);