Vanessa 2023-12-22 10:25:55 +08:00
parent 1d0d7cb890
commit 4bb9f0e1f1
3 changed files with 68 additions and 38 deletions

View file

@ -13,7 +13,12 @@ export const newCardModel = (options: {
cardType: TCardType, cardType: TCardType,
id: string, id: string,
title?: string title?: string
blocks?: ICard[], cardsData?: {
cards: ICard[],
unreviewedCount: number
unreviewedNewCardCount: number
unreviewedOldCardCount: number
},
index?: number, index?: number,
} }
}) => { }) => {
@ -24,11 +29,11 @@ export const newCardModel = (options: {
tab: options.tab, tab: options.tab,
data: options.data, data: options.data,
init() { init() {
if (options.data.blocks) { if (options.data.cardsData) {
this.element.innerHTML = genCardHTML({ this.element.innerHTML = genCardHTML({
id: this.data.id, id: this.data.id,
cardType: this.data.cardType, cardType: this.data.cardType,
blocks: options.data.blocks, cardsData: options.data.cardsData,
isTab: true, isTab: true,
}); });
@ -38,12 +43,12 @@ export const newCardModel = (options: {
id: this.data.id, id: this.data.id,
title: this.data.title, title: this.data.title,
cardType: this.data.cardType, cardType: this.data.cardType,
blocks: options.data.blocks, cardsData: options.data.cardsData,
index: options.data.index, index: options.data.index,
}); });
this.data.editor = editor; this.data.editor = editor;
// https://github.com/siyuan-note/siyuan/issues/9561#issuecomment-1794473512 // https://github.com/siyuan-note/siyuan/issues/9561#issuecomment-1794473512
delete options.data.blocks; delete options.data.cardsData;
delete options.data.index; delete options.data.index;
} else { } else {
fetchPost(this.data.cardType === "all" ? "/api/riff/getRiffDueCards" : fetchPost(this.data.cardType === "all" ? "/api/riff/getRiffDueCards" :
@ -55,7 +60,7 @@ export const newCardModel = (options: {
this.element.innerHTML = genCardHTML({ this.element.innerHTML = genCardHTML({
id: this.data.id, id: this.data.id,
cardType: this.data.cardType, cardType: this.data.cardType,
blocks: response.data.cards, cardsData: response.data,
isTab: true, isTab: true,
}); });
@ -65,7 +70,7 @@ export const newCardModel = (options: {
id: this.data.id, id: this.data.id,
title: this.data.title, title: this.data.title,
cardType: this.data.cardType, cardType: this.data.cardType,
blocks: response.data.cards, cardsData: response.data,
}); });
customObj.data.editor = editor; customObj.data.editor = editor;
}); });
@ -91,7 +96,7 @@ export const newCardModel = (options: {
this.element.innerHTML = genCardHTML({ this.element.innerHTML = genCardHTML({
id: this.data.id, id: this.data.id,
cardType: this.data.cardType, cardType: this.data.cardType,
blocks: response.data.cards, cardsData: response.data,
isTab: true, isTab: true,
}); });
}); });

View file

@ -18,10 +18,19 @@ import {App} from "../index";
import {resize} from "../protyle/util/resize"; import {resize} from "../protyle/util/resize";
import {setStorageVal} from "../protyle/util/compatibility"; import {setStorageVal} from "../protyle/util/compatibility";
const genCardCount = (unreviewedNewCardCount: number, unreviewedOldCardCount: number,) => {
return `<span>${unreviewedNewCardCount}</span> + <span>${unreviewedOldCardCount}</span>`;
}
export const genCardHTML = (options: { export const genCardHTML = (options: {
id: string, id: string,
cardType: TCardType, cardType: TCardType,
blocks: ICard[], cardsData: {
cards: ICard[],
unreviewedCount: number
unreviewedNewCardCount: number
unreviewedOldCardCount: number
},
isTab: boolean isTab: boolean
}) => { }) => {
let iconsHTML: string; let iconsHTML: string;
@ -29,7 +38,7 @@ export const genCardHTML = (options: {
iconsHTML = `<div class="toolbar toolbar--border"> iconsHTML = `<div class="toolbar toolbar--border">
<svg class="toolbar__icon"><use xlink:href="#iconRiffCard"></use></svg> <svg class="toolbar__icon"><use xlink:href="#iconRiffCard"></use></svg>
<span class="fn__flex-1 fn__flex-center toolbar__text">${window.siyuan.languages.riffCard}</span> <span class="fn__flex-1 fn__flex-center toolbar__text">${window.siyuan.languages.riffCard}</span>
<div data-type="count" class="${options.blocks.length === 0 ? "fn__none" : ""}">1/${options.blocks.length}</span></div> <div data-type="count" class="${options.cardsData.unreviewedCount === 0 ? "fn__none" : ""}"><span>1</span>/${genCardCount(options.cardsData.unreviewedNewCardCount, options.cardsData.unreviewedOldCardCount)}</span></div>
<svg class="toolbar__icon" data-id="${options.id || ""}" data-cardtype="${options.cardType}" data-type="filter"><use xlink:href="#iconFilter"></use></svg> <svg class="toolbar__icon" data-id="${options.id || ""}" data-cardtype="${options.cardType}" data-type="filter"><use xlink:href="#iconFilter"></use></svg>
<svg class="toolbar__icon" data-type="close"><use xlink:href="#iconCloseRound"></use></svg> <svg class="toolbar__icon" data-type="close"><use xlink:href="#iconCloseRound"></use></svg>
</div>`; </div>`;
@ -41,7 +50,7 @@ export const genCardHTML = (options: {
<span class="fn__space"></span> <span class="fn__space"></span>
<span class="fn__flex-center">${window.siyuan.languages.riffCard}</span>`} <span class="fn__flex-center">${window.siyuan.languages.riffCard}</span>`}
<span class="fn__space fn__flex-1 resize__move" style="min-height: 100%"></span> <span class="fn__space fn__flex-1 resize__move" style="min-height: 100%"></span>
<div data-type="count" class="ft__on-surface ft__smaller fn__flex-center${options.blocks.length === 0 ? " fn__none" : ""}">1/${options.blocks.length}</span></div> <div data-type="count" class="ft__on-surface ft__smaller fn__flex-center${options.cardsData.unreviewedCount === 0 ? " fn__none" : ""}"><span>1</span>/${genCardCount(options.cardsData.unreviewedNewCardCount, options.cardsData.unreviewedOldCardCount)}</span></div>
<div class="fn__space"></div> <div class="fn__space"></div>
<div data-id="${options.id || ""}" data-cardtype="${options.cardType}" data-type="filter" class="block__icon block__icon--show"> <div data-id="${options.id || ""}" data-cardtype="${options.cardType}" data-type="filter" class="block__icon block__icon--show">
<svg><use xlink:href="#iconFilter"></use></svg> <svg><use xlink:href="#iconFilter"></use></svg>
@ -58,16 +67,16 @@ export const genCardHTML = (options: {
/// #endif /// #endif
return `<div class="card__main"> return `<div class="card__main">
${iconsHTML} ${iconsHTML}
<div class="card__block fn__flex-1 ${options.blocks.length === 0 ? "fn__none" : ""} <div class="card__block fn__flex-1 ${options.cardsData.unreviewedCount === 0 ? "fn__none" : ""}
${window.siyuan.config.flashcard.mark ? "card__block--hidemark" : ""} ${window.siyuan.config.flashcard.mark ? "card__block--hidemark" : ""}
${window.siyuan.config.flashcard.superBlock ? "card__block--hidesb" : ""} ${window.siyuan.config.flashcard.superBlock ? "card__block--hidesb" : ""}
${window.siyuan.config.flashcard.heading ? "card__block--hideh" : ""} ${window.siyuan.config.flashcard.heading ? "card__block--hideh" : ""}
${window.siyuan.config.flashcard.list ? "card__block--hideli" : ""}" data-type="render"></div> ${window.siyuan.config.flashcard.list ? "card__block--hideli" : ""}" data-type="render"></div>
<div class="card__empty card__empty--space${options.blocks.length === 0 ? "" : " fn__none"}" data-type="empty"> <div class="card__empty card__empty--space${options.cardsData.unreviewedCount === 0 ? "" : " fn__none"}" data-type="empty">
<div>🔮</div> <div>🔮</div>
${window.siyuan.languages.noDueCard} ${window.siyuan.languages.noDueCard}
</div> </div>
<div class="fn__flex card__action${options.blocks.length === 0 ? " fn__none" : ""}"> <div class="fn__flex card__action${options.cardsData.unreviewedCount === 0 ? " fn__none" : ""}">
<button class="b3-button b3-button--cancel" disabled="disabled" data-type="-2" style="width: 25%;min-width: 86px;display: flex"> <button class="b3-button b3-button--cancel" disabled="disabled" data-type="-2" style="width: 25%;min-width: 86px;display: flex">
<svg><use xlink:href="#iconLeft"></use></svg> <svg><use xlink:href="#iconLeft"></use></svg>
(p) (p)
@ -119,7 +128,12 @@ export const bindCardEvent = (options: {
app: App, app: App,
element: Element, element: Element,
title?: string, title?: string,
blocks: ICard[], cardsData: {
cards: ICard[],
unreviewedCount: number
unreviewedNewCardCount: number
unreviewedOldCardCount: number
}
cardType: TCardType, cardType: TCardType,
id?: string, id?: string,
dialog?: Dialog, dialog?: Dialog,
@ -147,9 +161,9 @@ export const bindCardEvent = (options: {
if (window.siyuan.mobile) { if (window.siyuan.mobile) {
window.siyuan.mobile.popEditor = editor; window.siyuan.mobile.popEditor = editor;
} }
if (options.blocks.length > 0) { if (options.cardsData.unreviewedCount > 0) {
fetchPost("/api/filetree/getDoc", { fetchPost("/api/filetree/getDoc", {
id: options.blocks[index].blockID, id: options.cardsData.cards[index].blockID,
mode: 0, mode: 0,
size: Constants.SIZE_GET_MAX size: Constants.SIZE_GET_MAX
}, (response) => { }, (response) => {
@ -161,8 +175,8 @@ export const bindCardEvent = (options: {
}); });
} }
options.element.setAttribute("data-key", window.siyuan.config.keymap.general.riffCard.custom); options.element.setAttribute("data-key", window.siyuan.config.keymap.general.riffCard.custom);
const countElement = options.element.querySelector('[data-type="count"]'); const countElement = options.element.querySelector('[data-type="count"] span');
countElement.innerHTML = `${index + 1}/${options.blocks.length}`; countElement.innerHTML = (index + 1).toString();
const actionElements = options.element.querySelectorAll(".card__action"); const actionElements = options.element.querySelectorAll(".card__action");
const filterElement = options.element.querySelector('[data-type="filter"]'); const filterElement = options.element.querySelector('[data-type="filter"]');
const fetchNewRound = () => { const fetchNewRound = () => {
@ -174,14 +188,14 @@ export const bindCardEvent = (options: {
notebook: filterElement.getAttribute("data-id"), notebook: filterElement.getAttribute("data-id"),
}, (treeCards) => { }, (treeCards) => {
index = 0; index = 0;
options.blocks = treeCards.data.cards; options.cardsData.cards = treeCards.data.cards;
if (options.blocks.length > 0) { if (options.cardsData.unreviewedCount > 0) {
nextCard({ nextCard({
countElement, countElement,
editor, editor,
actionElements, actionElements,
index, index,
blocks: options.blocks blocks: options.cardsData.cards
}); });
} else { } else {
allDone(countElement, editor, actionElements); allDone(countElement, editor, actionElements);
@ -230,7 +244,7 @@ export const bindCardEvent = (options: {
icon: "iconRiffCard", icon: "iconRiffCard",
title: window.siyuan.languages.spaceRepetition, title: window.siyuan.languages.spaceRepetition,
data: { data: {
blocks: options.blocks, blocks: options.cardsData.cards,
index, index,
cardType: filterElement.getAttribute("data-cardtype") as TCardType, cardType: filterElement.getAttribute("data-cardtype") as TCardType,
id: filterElement.getAttribute("data-id"), id: filterElement.getAttribute("data-id"),
@ -328,7 +342,7 @@ export const bindCardEvent = (options: {
type = buttonElement.getAttribute("data-type"); type = buttonElement.getAttribute("data-type");
} }
} }
if (!type || !options.blocks[index]) { if (!type || !options.cardsData.cards[index]) {
return; return;
} }
event.preventDefault(); event.preventDefault();
@ -341,7 +355,7 @@ export const bindCardEvent = (options: {
editor.protyle.element.classList.remove("card__block--hidemark", "card__block--hideli", "card__block--hidesb", "card__block--hideh"); editor.protyle.element.classList.remove("card__block--hidemark", "card__block--hideli", "card__block--hidesb", "card__block--hideh");
actionElements[0].classList.add("fn__none"); actionElements[0].classList.add("fn__none");
actionElements[1].querySelectorAll(".b3-button").forEach((element, btnIndex) => { actionElements[1].querySelectorAll(".b3-button").forEach((element, btnIndex) => {
element.previousElementSibling.textContent = options.blocks[index].nextDues[btnIndex]; element.previousElementSibling.textContent = options.cardsData.cards[index].nextDues[btnIndex];
}); });
actionElements[1].classList.remove("fn__none"); actionElements[1].classList.remove("fn__none");
return; return;
@ -357,17 +371,17 @@ export const bindCardEvent = (options: {
editor, editor,
actionElements, actionElements,
index, index,
blocks: options.blocks blocks: options.cardsData.cards
}); });
} }
return; return;
} }
if (["1", "2", "3", "4", "-3"].includes(type) && actionElements[0].classList.contains("fn__none")) { if (["1", "2", "3", "4", "-3"].includes(type) && actionElements[0].classList.contains("fn__none")) {
fetchPost(type === "-3" ? "/api/riff/skipReviewRiffCard" : "/api/riff/reviewRiffCard", { fetchPost(type === "-3" ? "/api/riff/skipReviewRiffCard" : "/api/riff/reviewRiffCard", {
deckID: options.blocks[index].deckID, deckID: options.cardsData.cards[index].deckID,
cardID: options.blocks[index].cardID, cardID: options.cardsData.cards[index].cardID,
rating: parseInt(type), rating: parseInt(type),
reviewedCards: options.blocks reviewedCards: options.cardsData.cards
}, () => { }, () => {
/// #if MOBILE /// #if MOBILE
if (type !== "-3" && if (type !== "-3" &&
@ -378,18 +392,18 @@ export const bindCardEvent = (options: {
} }
/// #endif /// #endif
index++; index++;
if (index > options.blocks.length - 1) { if (index > options.cardsData.unreviewedCount - 1) {
const currentCardType = filterElement.getAttribute("data-cardtype"); const currentCardType = filterElement.getAttribute("data-cardtype");
fetchPost(currentCardType === "all" ? "/api/riff/getRiffDueCards" : fetchPost(currentCardType === "all" ? "/api/riff/getRiffDueCards" :
(currentCardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), { (currentCardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), {
rootID: filterElement.getAttribute("data-id"), rootID: filterElement.getAttribute("data-id"),
deckID: filterElement.getAttribute("data-id"), deckID: filterElement.getAttribute("data-id"),
notebook: filterElement.getAttribute("data-id"), notebook: filterElement.getAttribute("data-id"),
reviewedCards: options.blocks reviewedCards: options.cardsData.cards
}, (result) => { }, (result) => {
index = 0; index = 0;
options.blocks = result.data.cards; options.cardsData.cards = result.data.cards;
if (options.blocks.length === 0) { if (options.cardsData.unreviewedCount === 0) {
if (result.data.unreviewedCount > 0) { if (result.data.unreviewedCount > 0) {
newRound(countElement, editor, actionElements, result.data.unreviewedCount); newRound(countElement, editor, actionElements, result.data.unreviewedCount);
} else { } else {
@ -401,7 +415,7 @@ export const bindCardEvent = (options: {
editor, editor,
actionElements, actionElements,
index, index,
blocks: options.blocks blocks: options.cardsData.cards
}); });
} }
}); });
@ -412,7 +426,7 @@ export const bindCardEvent = (options: {
editor, editor,
actionElements, actionElements,
index, index,
blocks: options.blocks blocks: options.cardsData.cards
}); });
}); });
} }
@ -429,6 +443,8 @@ export const openCard = (app: App) => {
export const openCardByData = (app: App, cardsData: { export const openCardByData = (app: App, cardsData: {
cards: ICard[], cards: ICard[],
unreviewedCount: number unreviewedCount: number
unreviewedNewCardCount: number
unreviewedOldCardCount: number
}, cardType: TCardType, id?: string, title?: string) => { }, cardType: TCardType, id?: string, title?: string) => {
const exit = window.siyuan.dialogs.find(item => { const exit = window.siyuan.dialogs.find(item => {
if (item.element.getAttribute("data-key") === window.siyuan.config.keymap.general.riffCard.custom) { if (item.element.getAttribute("data-key") === window.siyuan.config.keymap.general.riffCard.custom) {
@ -441,7 +457,7 @@ export const openCardByData = (app: App, cardsData: {
} }
const dialog = new Dialog({ const dialog = new Dialog({
content: genCardHTML({id, cardType, blocks: cardsData.cards, isTab: false}), content: genCardHTML({id, cardType, cardsData, isTab: false}),
width: isMobile() ? "100vw" : "80vw", width: isMobile() ? "100vw" : "80vw",
height: isMobile() ? "100vh" : "70vh", height: isMobile() ? "100vh" : "70vh",
destroyCallback() { destroyCallback() {
@ -458,7 +474,7 @@ export const openCardByData = (app: App, cardsData: {
const editor = bindCardEvent({ const editor = bindCardEvent({
app, app,
element: dialog.element, element: dialog.element,
blocks: cardsData.cards, cardsData,
title, title,
id, id,
cardType, cardType,
@ -491,7 +507,7 @@ const nextCard = (options: {
options.actionElements[1].classList.add("fn__none"); options.actionElements[1].classList.add("fn__none");
options.editor.protyle.element.classList.remove("fn__none"); options.editor.protyle.element.classList.remove("fn__none");
options.editor.protyle.element.nextElementSibling.classList.add("fn__none"); options.editor.protyle.element.nextElementSibling.classList.add("fn__none");
options.countElement.innerHTML = `${options.index + 1}/${options.blocks.length}`; options.countElement.firstElementChild.innerHTML = (options.index + 1).toString();
options.countElement.classList.remove("fn__none"); options.countElement.classList.remove("fn__none");
if (options.index === 0) { if (options.index === 0) {
options.actionElements[0].firstElementChild.setAttribute("disabled", "disabled"); options.actionElements[0].firstElementChild.setAttribute("disabled", "disabled");

View file

@ -680,6 +680,15 @@ export const newModelByInitData = (app: App, tab: Tab, json: any) => {
let model: Model; let model: Model;
if (json.instance === "Custom") { if (json.instance === "Custom") {
if (json.customModelType === "siyuan-card") { if (json.customModelType === "siyuan-card") {
// https://github.com/siyuan-note/siyuan/issues/9377 历史数据兼容
if (!json.customModelData.cardsData) {
json.customModelData.cardsData = {
cards: json.customModelData.blocks,
unreviewedCount: json.customModelData.blocks.length,
unreviewedNewCardCount: 0,
unreviewedOldCardCount: json.customModelData.blocks.length
}
}
model = newCardModel({ model = newCardModel({
app, app,
tab: tab, tab: tab,