Pārlūkot izejas kodu

:sparkles: https://github.com/siyuan-note/siyuan/issues/7057

Vanessa 2 gadi atpakaļ
vecāks
revīzija
a2dba45103

+ 1 - 1
app/appearance/langs/en_US.json

@@ -22,7 +22,7 @@
   "new": "New",
   "share2LiandiConfirmTip": "Are you sure to share this document to Liandi?",
   "share2Liandi": "Share to Liandi",
-  "noDueCard": "\uD83D\uDD2E Great job! There are no more review tasks at the moment, check back later!",
+  "noDueCard": "Great job! There are no more review tasks at the moment, check back later!",
   "createDeck": "Create Deck",
   "addDeck": "Add to deck",
   "removeDeck": "Remove from deck",

+ 1 - 1
app/appearance/langs/es_ES.json

@@ -22,7 +22,7 @@
   "new": "Nuevo",
   "share2LiandiConfirmTip": "¿Estás seguro de compartir este documento con Liandi?",
   "share2Liandi": "Compartir con Liandi",
-  "noDueCard": "\uD83D\uDD2E ¡Buen trabajo! No hay más tareas de revisión en este momento, ¡vuelve a comprobar más tarde!",
+  "noDueCard": "¡Buen trabajo! No hay más tareas de revisión en este momento, ¡vuelve a comprobar más tarde!",
   "createDeck": "Crear mazo",
   "addDeck": "Añadir al mazo",
   "removeDeck": "Eliminar del mazo",

+ 1 - 1
app/appearance/langs/fr_FR.json

@@ -22,7 +22,7 @@
   "new": "Nouveau",
   "share2LiandiConfirmTip": "Êtes-vous sûr de partager ce document avec Liandi ?",
   "share2Liandi": "Partager avec Liandi",
-  "noDueCard": "\uD83D\uDD2E Excellent travail ! Il n'y a plus de tâches de révision pour le moment, revenez plus tard !",
+  "noDueCard": "Excellent travail ! Il n'y a plus de tâches de révision pour le moment, revenez plus tard !",
   "createDeck": "Créer un deck",
   "addDeck": "Ajouter au deck",
   "removeDeck": "Retirer du deck",

+ 1 - 1
app/appearance/langs/zh_CHT.json

@@ -22,7 +22,7 @@
   "new": "新建",
   "share2LiandiConfirmTip": "確定將該文檔分享到鏈滴嗎?",
   "share2Liandi": "分享到鏈滴",
-  "noDueCard": "\uD83D\uDD2E 幹得漂亮!目前已經沒有更多複習任務,過一會再來看看吧!",
+  "noDueCard": "幹得漂亮!目前已經沒有更多複習任務,過一會再來看看吧!",
   "createDeck": "創建卡包",
   "addDeck": "加入卡包",
   "removeDeck": "從卡包中移除",

+ 1 - 1
app/appearance/langs/zh_CN.json

@@ -22,7 +22,7 @@
   "new": "新建",
   "share2LiandiConfirmTip": "确定将该文档分享到链滴吗?",
   "share2Liandi": "分享到链滴",
-  "noDueCard": "\uD83D\uDD2E 干得漂亮!目前已经没有更多复习任务,过一会再来看看吧!",
+  "noDueCard": "干得漂亮!目前已经没有更多复习任务,过一会再来看看吧!",
   "createDeck": "创建卡包",
   "addDeck": "加入卡包",
   "removeDeck": "从卡包中移除",

+ 15 - 7
app/src/assets/scss/_dialog.scss

@@ -118,17 +118,25 @@
     flex-direction: column;
     flex: 1;
     text-align: center;
-    color: var(--b3-theme-on-surface);
     background-color: var(--b3-theme-background);
     font-size: 16px;
+
+    & > div {
+      font-size: 64px;
+      margin-bottom: 16px;
+    }
   }
 
-  &__cardaction > div > span {
-    display: block;
-    color: var(--b3-theme-on-surface);
-    text-align: center;
-    line-height: 15px;
-    font-size: 10px;
+  &__cardaction {
+    padding: 16px 24px;
+
+    & > div > span {
+      display: block;
+      color: var(--b3-theme-on-surface);
+      text-align: center;
+      line-height: 15px;
+      font-size: 10px;
+    }
   }
 
   &__cardblock {

+ 16 - 2
app/src/card/makeCard.ts

@@ -7,7 +7,7 @@ import {confirmDialog} from "../dialog/confirmDialog";
 import {hideElements} from "../protyle/ui/hideElements";
 import {viewCards} from "./viewCards";
 
-export const genCardItem = (item: ICard) => {
+export const genCardItem = (item: ICardPackage) => {
     return `<li data-id="${item.id}" class="b3-list-item b3-list-item--narrow${isMobile() ? "" : " b3-list-item--hide-action"}">
 <span class="b3-list-item__text">${item.name}</span>
 <span class="counter b3-tooltips b3-tooltips__w${isMobile() ? "" : " fn__none"}" aria-label="${window.siyuan.languages.riffCard}">${item.size}</span>
@@ -48,7 +48,7 @@ export const makeCard = (nodeElement: Element[]) => {
             }
             ids.push(item.getAttribute("data-node-id"));
         });
-        response.data.forEach((item: ICard) => {
+        response.data.forEach((item: ICardPackage) => {
             html += genCardItem(item);
         });
         const dialog = new Dialog({
@@ -170,5 +170,19 @@ export const makeCard = (nodeElement: Element[]) => {
     });
 };
 
+export const quickMakeCard = (nodeElement: Element[]) => {
+    const ids: string[] = [];
+    nodeElement.forEach(item => {
+        if (item.getAttribute("data-type") === "NodeThematicBreak") {
+            return;
+        }
+        ids.push(item.getAttribute("data-node-id"));
+    });
+    fetchPost("/api/riff/addRiffCards", {
+        deckID: "20230218211946-2kw8jgx",
+        blockIDs: ids
+    });
+}
+
 
 

+ 148 - 137
app/src/card/openCard.ts

@@ -23,29 +23,38 @@ export const openCard = () => {
             decksHTML += `<option value="${deck.id}">${deck.name}</option>`;
         });
         fetchPost("/api/riff/getRiffDueCards", {deckID: ""}, (cardsResponse) => {
-            let blocks = cardsResponse.data;
-            let countHTML = "";
-            let index = 0;
-            if (blocks.length > 0) {
-                countHTML = `<span>1</span>/${blocks.length}`;
-            }
-            const dialog = new Dialog({
-                title: window.siyuan.languages.riffCard,
-                content: `<div class="fn__flex-column" style="box-sizing: border-box;max-height: 100%;padding: 0 0 16px 0;">
-    <div class="fn__flex b3-dialog__content">
-        <select class="b3-select fn__flex-1">${decksHTML}</select>
-        <span class="fn__space"></span>
-        <span data-type="view" class="block__icon block__icon--show b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.cardPreview}">
-            <svg><use xlink:href="#iconEye"></use></svg>
-        </span>
-        <span class="fn__space"></span>
-        <div class="ft__on-surface ft__smaller fn__flex-center${blocks.length === 0 ? " fn__none" : ""}" data-type="count">${countHTML}</div>
+            openCardByData(cardsResponse.data, `<select class="b3-select">${decksHTML}</select>`)
+        });
+    });
+};
+
+export const openCardByData = (cardsData: ICard[], html = "") => {
+    let blocks = cardsData;
+    let index = 0;
+    if (blocks.length > 0) {
+        html += `<div class="fn__flex" style="align-items: center" data-type="count">
+    <span class="fn__space"></span>
+    <span data-type="view" class="block__icon block__icon--show b3-tooltips b3-tooltips__w" aria-label="${window.siyuan.languages.cardPreview}">
+        <svg><use xlink:href="#iconEye"></use></svg>
+    </span>
+    <span class="fn__space"></span>
+    <div class="ft__on-surface ft__smaller"><span>1</span>/${blocks.length}</div>
+</div>`;
+    }
+    const dialog = new Dialog({
+        content: `<div class="fn__flex-column" style="box-sizing: border-box;max-height: 100%">
+    <div class="fn__flex b3-form__space--small">
+        <span class="fn__flex-1 fn__flex-center">${window.siyuan.languages.riffCard}</span>
+        ${html}
     </div>
     <div class="b3-dialog__cardblock b3-dialog__cardblock--hide fn__flex-1${blocks.length === 0 ? " fn__none" : ""}" data-type="render"></div>
-    <div class="b3-dialog__cardempty${blocks.length === 0 ? "" : " fn__none"}" data-type="empty">${window.siyuan.languages.noDueCard}</div>
+    <div class="b3-dialog__cardempty${blocks.length === 0 ? "" : " fn__none"}" data-type="empty">
+        <div>🎉</div>
+        ${window.siyuan.languages.noDueCard}
+    </div>
     <div class="fn__flex b3-dialog__cardaction${blocks.length === 0 ? " fn__none" : ""}">
         <span class="fn__flex-1"></span>
-        <button data-type="-1" class="b3-button" style="margin-top: 16px">Show (S)</button>
+        <button data-type="-1" class="b3-button">Show (S)</button>
         <span class="fn__flex-1"></span>
     </div>
     <div class="fn__flex b3-dialog__cardaction fn__none">
@@ -70,22 +79,122 @@ export const openCard = () => {
         </div>
     </div>
 </div>`,
-                width: isMobile() ? "98vw" : "80vw",
-                height: isMobile() ? "80vh" : "70vh",
+        width: isMobile() ? "98vw" : "80vw",
+        height: isMobile() ? "80vh" : "70vh",
+    });
+    (dialog.element.querySelector(".b3-dialog__scrim") as HTMLElement).style.backgroundColor = "var(--b3-theme-background)";
+    const editor = new Protyle(dialog.element.querySelector("[data-type='render']") as HTMLElement, {
+        blockId: "",
+        action: [Constants.CB_GET_ALL],
+        render: {
+            background: false,
+            title: false,
+            gutter: true,
+            breadcrumbDocName: true,
+        },
+        typewriterMode: false
+    });
+    if (blocks.length > 0) {
+        fetchPost("/api/filetree/getDoc", {
+            id: blocks[index].blockID,
+            mode: 0,
+            size: Constants.SIZE_GET_MAX
+        }, (response) => {
+            onGet(response, editor.protyle, [Constants.CB_GET_ALL, Constants.CB_GET_HTML]);
+        });
+    }
+    (dialog.element.firstElementChild as HTMLElement).style.zIndex = "200";
+    dialog.element.setAttribute("data-key", window.siyuan.config.keymap.general.riffCard.custom);
+    const countElement = dialog.element.querySelector('[data-type="count"]');
+    const actionElements = dialog.element.querySelectorAll(".b3-dialog__cardaction");
+    dialog.element.addEventListener("click", (event) => {
+        const viewElement = hasClosestByAttribute(event.target as HTMLElement, "data-type", "view");
+        if (viewElement) {
+            // TODO 文档卡
+            viewCards(selectElement.value, selectElement.options[selectElement.selectedIndex].text);
+            event.preventDefault();
+            event.stopPropagation();
+            return;
+        }
+        let type = "";
+        if (typeof event.detail === "string") {
+            if (event.detail === "a") {
+                type = "0";
+            } else if (event.detail === "h") {
+                type = "1";
+            } else if (event.detail === "g") {
+                type = "2";
+            } else if (event.detail === "e") {
+                type = "3";
+            } else if (event.detail === "s") {
+                type = "-1";
+            }
+        }
+        if (!type) {
+            const buttonElement = hasClosestByClassName(event.target as HTMLElement, "b3-button");
+            if (buttonElement) {
+                type = buttonElement.getAttribute("data-type");
+            }
+        }
+        if (!type || !blocks[index]) {
+            return;
+        }
+        event.preventDefault();
+        event.stopPropagation();
+        if (type === "-1") {
+            editor.protyle.element.classList.remove("b3-dialog__cardblock--hide");
+            actionElements[0].classList.add("fn__none");
+            actionElements[1].querySelectorAll(".b3-button").forEach((element, btnIndex) => {
+                element.previousElementSibling.textContent = blocks[index].nextDues[btnIndex];
             });
-            (dialog.element.querySelector(".b3-dialog__scrim") as HTMLElement).style.backgroundColor = "var(--b3-theme-background)";
-            const editor = new Protyle(dialog.element.querySelector("[data-type='render']") as HTMLElement, {
-                blockId: "",
-                action: [Constants.CB_GET_ALL],
-                render: {
-                    background: false,
-                    title: false,
-                    gutter: true,
-                    breadcrumbDocName: true,
-                },
-                typewriterMode: false
+            actionElements[1].classList.remove("fn__none");
+            return;
+        }
+        if (["0", "1", "2", "3"].includes(type)) {
+            fetchPost("/api/riff/reviewRiffCard", {
+                deckID: blocks[index].deckID,
+                blockID: blocks[index].blockID,
+                rating: parseInt(type)
+            }, () => {
+                index++;
+                editor.protyle.element.classList.add("b3-dialog__cardblock--hide");
+                if (index > blocks.length - 1) {
+                    countElement.classList.add("fn__none");
+                    editor.protyle.element.classList.add("fn__none");
+                    editor.protyle.element.nextElementSibling.classList.remove("fn__none");
+                    actionElements[0].classList.add("fn__none");
+                    actionElements[1].classList.add("fn__none");
+                    return;
+                }
+                actionElements[0].classList.remove("fn__none");
+                actionElements[1].classList.add("fn__none");
+                countElement.lastElementChild.firstElementChild.innerHTML = (index + 1).toString();
+                fetchPost("/api/filetree/getDoc", {
+                    id: blocks[index].blockID,
+                    mode: 0,
+                    size: Constants.SIZE_GET_MAX
+                }, (response) => {
+                    onGet(response, editor.protyle, [Constants.CB_GET_ALL, Constants.CB_GET_HTML]);
+                });
             });
+        }
+    });
+    const selectElement = dialog.element.querySelector("select");
+    if (!selectElement) {
+        return
+    }
+    selectElement.addEventListener("change", () => {
+        fetchPost("/api/riff/getRiffDueCards", {deckID: selectElement.value}, (cardsChangeResponse) => {
+            blocks = cardsChangeResponse.data;
+            index = 0;
+            editor.protyle.element.classList.add("b3-dialog__cardblock--hide");
             if (blocks.length > 0) {
+                countElement.lastElementChild.innerHTML = `<span>1</span>/${blocks.length}`;
+                countElement.classList.remove("fn__none");
+                editor.protyle.element.classList.remove("fn__none");
+                editor.protyle.element.nextElementSibling.classList.add("fn__none");
+                actionElements[0].classList.remove("fn__none");
+                actionElements[1].classList.add("fn__none");
                 fetchPost("/api/filetree/getDoc", {
                     id: blocks[index].blockID,
                     mode: 0,
@@ -93,111 +202,13 @@ export const openCard = () => {
                 }, (response) => {
                     onGet(response, editor.protyle, [Constants.CB_GET_ALL, Constants.CB_GET_HTML]);
                 });
+            } else {
+                countElement.classList.add("fn__none");
+                editor.protyle.element.classList.add("fn__none");
+                editor.protyle.element.nextElementSibling.classList.remove("fn__none");
+                actionElements[0].classList.add("fn__none");
+                actionElements[1].classList.add("fn__none");
             }
-            (dialog.element.firstElementChild as HTMLElement).style.zIndex = "200";
-            dialog.element.setAttribute("data-key", window.siyuan.config.keymap.general.riffCard.custom);
-            const countElement = dialog.element.querySelector('[data-type="count"]');
-            const actionElements = dialog.element.querySelectorAll(".b3-dialog__cardaction");
-            const selectElement = dialog.element.querySelector("select");
-            selectElement.addEventListener("change", () => {
-                fetchPost("/api/riff/getRiffDueCards", {deckID: selectElement.value}, (cardsChangeResponse) => {
-                    blocks = cardsChangeResponse.data;
-                    index = 0;
-                    editor.protyle.element.classList.add("b3-dialog__cardblock--hide");
-                    if (blocks.length > 0) {
-                        countElement.innerHTML = `<span>1</span>/${blocks.length}`;
-                        countElement.classList.remove("fn__none");
-                        editor.protyle.element.classList.remove("fn__none");
-                        editor.protyle.element.nextElementSibling.classList.add("fn__none");
-                        actionElements[0].classList.remove("fn__none");
-                        actionElements[1].classList.add("fn__none");
-                        fetchPost("/api/filetree/getDoc", {
-                            id: blocks[index].blockID,
-                            mode: 0,
-                            size: Constants.SIZE_GET_MAX
-                        }, (response) => {
-                            onGet(response, editor.protyle, [Constants.CB_GET_ALL, Constants.CB_GET_HTML]);
-                        });
-                    } else {
-                        countElement.classList.add("fn__none");
-                        editor.protyle.element.classList.add("fn__none");
-                        editor.protyle.element.nextElementSibling.classList.remove("fn__none");
-                        actionElements[0].classList.add("fn__none");
-                        actionElements[1].classList.add("fn__none");
-                    }
-                });
-            });
-            dialog.element.addEventListener("click", (event) => {
-                const viewElement = hasClosestByAttribute(event.target as HTMLElement, "data-type", "view");
-                if (viewElement) {
-                    viewCards(selectElement.value, selectElement.options[selectElement.selectedIndex].text);
-                    event.preventDefault();
-                    event.stopPropagation();
-                    return;
-                }
-                let type = "";
-                if (typeof event.detail === "string") {
-                    if (event.detail === "a") {
-                        type = "0";
-                    } else if (event.detail === "h") {
-                        type = "1";
-                    } else if (event.detail === "g") {
-                        type = "2";
-                    } else if (event.detail === "e") {
-                        type = "3";
-                    } else if (event.detail === "s") {
-                        type = "-1";
-                    }
-                }
-                if (!type) {
-                    const buttonElement = hasClosestByClassName(event.target as HTMLElement, "b3-button");
-                    if (buttonElement) {
-                        type = buttonElement.getAttribute("data-type");
-                    }
-                }
-                if (!type || !blocks[index]) {
-                    return;
-                }
-                event.preventDefault();
-                event.stopPropagation();
-                if (type === "-1") {
-                    editor.protyle.element.classList.remove("b3-dialog__cardblock--hide");
-                    actionElements[0].classList.add("fn__none");
-                    actionElements[1].querySelectorAll(".b3-button").forEach((element, btnIndex) => {
-                        element.previousElementSibling.textContent = blocks[index].nextDues[btnIndex];
-                    });
-                    actionElements[1].classList.remove("fn__none");
-                    return;
-                }
-                if (["0", "1", "2", "3"].includes(type)) {
-                    fetchPost("/api/riff/reviewRiffCard", {
-                        deckID: blocks[index].deckID,
-                        blockID: blocks[index].blockID,
-                        rating: parseInt(type)
-                    }, () => {
-                        index++;
-                        editor.protyle.element.classList.add("b3-dialog__cardblock--hide");
-                        if (index > blocks.length - 1) {
-                            countElement.classList.add("fn__none");
-                            editor.protyle.element.classList.add("fn__none");
-                            editor.protyle.element.nextElementSibling.classList.remove("fn__none");
-                            actionElements[0].classList.add("fn__none");
-                            actionElements[1].classList.add("fn__none");
-                            return;
-                        }
-                        actionElements[0].classList.remove("fn__none");
-                        actionElements[1].classList.add("fn__none");
-                        countElement.firstElementChild.innerHTML = (index + 1).toString();
-                        fetchPost("/api/filetree/getDoc", {
-                            id: blocks[index].blockID,
-                            mode: 0,
-                            size: Constants.SIZE_GET_MAX
-                        }, (response) => {
-                            onGet(response, editor.protyle, [Constants.CB_GET_ALL, Constants.CB_GET_HTML]);
-                        });
-                    });
-                }
-            });
         });
     });
-};
+}

+ 3 - 5
app/src/card/viewCards.ts

@@ -16,19 +16,17 @@ export const viewCards = (deckID: string, title: string, sourceElement?: HTMLEle
     let edit: Protyle;
     fetchPost("/api/riff/getRiffCards", {deckID, page: pageIndex}, (response) => {
         const dialog = new Dialog({
-            title,
             content: `<div class="fn__flex-column" style="height: 100%">
-    <div class="fn__hr"></div>
-    <div class="fn__flex">
+    <div class="fn__flex b3-form__space--small">
+        <span class="fn__flex-center">${title}</span>
+        <div class="fn__flex-1"></div>
         <span class="fn__space"></span>
         <span data-type="previous" class="block__icon block__icon--show b3-tooltips b3-tooltips__ne" disabled="disabled" aria-label="${window.siyuan.languages.previousLabel}"><svg><use xlink:href='#iconLeft'></use></svg></span>
         <span class="fn__space"></span>
         <span data-type="next" class="block__icon block__icon--show b3-tooltips b3-tooltips__ne" disabled="disabled" aria-label="${window.siyuan.languages.nextLabel}"><svg><use xlink:href='#iconRight'></use></svg></span>
         <span class="fn__space"></span>
         <span class="fn__flex-center ft__on-surface">${pageIndex}/${response.data.pageCount || 1}</span>
-        <div class="fn__flex-1"></div>
     </div>
-    <div class="fn__hr"></div>
     <div class="${isMobile() ? "fn__flex-column" : "fn__flex"} fn__flex-1" style="min-height: auto">
         <ul class="fn__flex-1 b3-list b3-list--background" style="user-select: none">
             ${renderViewItem(response.data.blocks)}

+ 19 - 3
app/src/protyle/gutter/index.ts

@@ -32,7 +32,7 @@ import {mathRender} from "../markdown/mathRender";
 import {duplicateBlock} from "../wysiwyg/commonHotkey";
 import {movePathTo} from "../../util/pathName";
 import {hintMoveBlock} from "../hint/extend";
-import {makeCard} from "../../card/makeCard";
+import {makeCard, quickMakeCard} from "../../card/makeCard";
 import {transferBlockRef} from "../../menus/block";
 
 export class Gutter {
@@ -667,7 +667,15 @@ export class Gutter {
         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.riffCard,
+            label: window.siyuan.languages.quickMakeCard,
+            iconHTML:`<svg class="b3-menu__icon"><use xlink:href="#iconRiffCard"></use></svg>`,
+            icon: "iconRiffCard",
+            click() {
+                quickMakeCard(selectsElement);
+            }
+        }).element);
+        window.siyuan.menus.menu.append(new MenuItem({
+            label: window.siyuan.languages.addToDeck,
             icon: "iconRiffCard",
             click() {
                 makeCard(selectsElement);
@@ -1431,7 +1439,15 @@ export class Gutter {
         }
         if (type !== "NodeThematicBreak") {
             window.siyuan.menus.menu.append(new MenuItem({
-                label: window.siyuan.languages.riffCard,
+                label: window.siyuan.languages.quickMakeCard,
+                iconHTML:`<svg class="b3-menu__icon"><use xlink:href="#iconRiffCard"></use></svg>`,
+                icon: "iconRiffCard",
+                click() {
+                    quickMakeCard([nodeElement]);
+                }
+            }).element);
+            window.siyuan.menus.menu.append(new MenuItem({
+                label: window.siyuan.languages.addToDeck,
                 icon: "iconRiffCard",
                 click() {
                     makeCard([nodeElement]);

+ 13 - 1
app/src/protyle/header/Title.ts

@@ -33,6 +33,7 @@ import {genEmptyElement} from "../../block/util";
 import {transaction} from "../wysiwyg/transaction";
 import {hideTooltip} from "../../dialog/tooltip";
 import {transferBlockRef} from "../../menus/block";
+import {openCardByData} from "../../card/openCard";
 
 export class Title {
     public element: HTMLElement;
@@ -230,7 +231,9 @@ export class Title {
             }).element);
             window.siyuan.menus.menu.popup({x: event.clientX, y: event.clientY});
         });
-        this.element.querySelector(".protyle-attr").addEventListener("click", (event: MouseEvent & { target: HTMLElement }) => {
+        this.element.querySelector(".protyle-attr").addEventListener("click", (event: MouseEvent & {
+            target: HTMLElement
+        }) => {
             fetchPost("/api/block/getDocInfo", {
                 id: protyle.block.rootID
             }, (response) => {
@@ -353,6 +356,15 @@ export class Title {
                     openFileWechatNotify(protyle);
                 }
             }).element);
+            window.siyuan.menus.menu.append(new MenuItem({
+                label: window.siyuan.languages.riffCard,
+                icon: "iconRiffCard",
+                click: () => {
+                    fetchPost("/api/riff/getTreeRiffDueCards", {rootID: protyle.block.rootID}, (response) => {
+                        openCardByData(response.data, `<span class="fn__flex-center">${escapeHtml(this.editElement.textContent)}</span>`);
+                    });
+                }
+            }).element);
             window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
             window.siyuan.menus.menu.append(new MenuItem({
                 iconHTML: Constants.ZWSP,

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

@@ -59,13 +59,19 @@ interface IWorkspace {
     closed: boolean
 }
 
-interface ICard {
+interface ICardPackage {
     id: string
     updated: string
     name: string
     size: number
 }
 
+interface ICard {
+    blockID: string
+    deckID: string
+    nextDues: IObject
+}
+
 interface ISearchOption {
     name?: string
     sort: number,  //  0:按块类型(默认),1:按创建时间升序,2:按创建时间降序,3:按更新时间升序,4:按更新时间降序,5:按内容顺序(仅在按文档分组时),6:按相关度升序,7:按相关度降序