import {Dialog} from "../dialog";
import {fetchPost} from "../util/fetch";
import {isMobile} from "../util/functions";
import {Protyle} from "../protyle";
import {Constants} from "../constants";
import {disabledProtyle, onGet} from "../protyle/util/onGet";
import {hasClosestByAttribute, hasClosestByClassName} from "../protyle/util/hasClosest";
import {hideElements} from "../protyle/ui/hideElements";
import {needSubscribe} from "../util/needSubscribe";
import {fullscreen} from "../protyle/breadcrumb/action";
import {MenuItem} from "../menus/Menu";
import {escapeHtml} from "../util/escape";
import {getDisplayName, movePathTo} from "../util/pathName";
import {newCardTab} from "./newCardTab";
export const genCardHTML = (options: {
id: string,
cardType: TCardType,
blocks: ICard[],
isTab: boolean
}) => {
return `
🔮
${window.siyuan.languages.noDueCard}
${window.siyuan.languages.nextRound}
`;
};
export const openCard = () => {
fetchPost("/api/riff/getRiffDueCards", {deckID: ""}, (cardsResponse) => {
openCardByData(cardsResponse.data, "all");
});
};
export const openCardByData = (cardsData: {
cards: ICard[],
unreviewedCount: number
}, cardType: TCardType, id?: string, title?: string) => {
const exit = window.siyuan.dialogs.find(item => {
if (item.element.getAttribute("data-key") === window.siyuan.config.keymap.general.riffCard.custom) {
item.destroy();
return true;
}
});
if (exit) {
return;
}
let blocks = cardsData.cards;
let index = 0;
const dialog = new Dialog({
content: genCardHTML({id, cardType, blocks, isTab: false}),
width: isMobile() ? "100vw" : "80vw",
height: isMobile() ? "100vh" : "70vh",
destroyCallback() {
if (editor) {
editor.destroy();
if (window.siyuan.mobile) {
window.siyuan.mobile.popEditor = null;
}
}
}
});
(dialog.element.querySelector(".b3-dialog__scrim") as HTMLElement).style.backgroundColor = "var(--b3-theme-background)";
(dialog.element.querySelector(".b3-dialog__container") as HTMLElement).style.maxWidth = "1024px";
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 (window.siyuan.mobile) {
window.siyuan.mobile.popEditor = editor;
}
if (window.siyuan.config.editor.readOnly) {
disabledProtyle(editor.protyle);
}
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(".card__action");
const filterElement = dialog.element.querySelector('[data-type="filter"]');
const fetchNewRound = () => {
const currentCardType = filterElement.getAttribute("data-cardtype");
fetchPost(currentCardType === "all" ? "/api/riff/getRiffDueCards" :
(currentCardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), {
rootID: filterElement.getAttribute("data-id"),
deckID: filterElement.getAttribute("data-id"),
notebook: filterElement.getAttribute("data-id"),
}, (treeCards) => {
index = 0;
blocks = treeCards.data.cards;
if (blocks.length > 0) {
nextCard({
countElement,
editor,
actionElements,
index,
blocks
});
} else {
allDone(countElement, editor, actionElements);
}
});
};
dialog.element.addEventListener("click", (event) => {
const target = event.target as HTMLElement;
let type = "";
if (typeof event.detail === "string") {
if (event.detail === "1" || event.detail === "j") {
type = "0";
} else if (event.detail === "2" || event.detail === "k") {
type = "1";
} else if (event.detail === "3" || event.detail === "l") {
type = "2";
} else if (event.detail === "4" || event.detail === ";") {
type = "3";
} else if (event.detail === " ") {
type = "-1";
} else if (event.detail === "p") {
type = "-2";
} else if (event.detail === "0") {
type = "-3";
}
} else {
const fullscreenElement = hasClosestByAttribute(target, "data-type", "fullscreen");
if (fullscreenElement) {
fullscreen(dialog.element.querySelector(".card__main"),
dialog.element.querySelector('[data-type="fullscreen"]'));
event.stopPropagation();
event.preventDefault();
return;
}
const sticktabElement = hasClosestByAttribute(target, "data-type", "sticktab");
if (sticktabElement) {
newCardTab({
type: filterElement.getAttribute("data-cardtype") as TCardType,
id: filterElement.getAttribute("data-id"),
dialog,
});
event.stopPropagation();
event.preventDefault();
return;
}
const closeElement = hasClosestByAttribute(target, "data-type", "close");
if (closeElement) {
dialog.destroy();
event.stopPropagation();
event.preventDefault();
return;
}
const filterTempElement = hasClosestByAttribute(target, "data-type", "filter");
if (filterTempElement) {
fetchPost("/api/riff/getRiffDecks", {}, (response) => {
window.siyuan.menus.menu.remove();
window.siyuan.menus.menu.append(new MenuItem({
iconHTML: Constants.ZWSP,
label: window.siyuan.languages.all,
click() {
filterElement.setAttribute("data-id", "");
filterElement.setAttribute("data-cardtype", "all");
fetchNewRound();
},
}).element);
window.siyuan.menus.menu.append(new MenuItem({
iconHTML: Constants.ZWSP,
label: window.siyuan.languages.fileTree,
click() {
movePathTo((toPath, toNotebook) => {
filterElement.setAttribute("data-id", toPath[0] === "/" ? toNotebook[0] : getDisplayName(toPath[0], true, true));
filterElement.setAttribute("data-cardtype", toPath[0] === "/" ? "notebook" : "doc");
fetchNewRound();
}, [], undefined, window.siyuan.languages.specifyPath, true);
}
}).element);
if (title || response.data.length > 0) {
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
}
if (title) {
window.siyuan.menus.menu.append(new MenuItem({
iconHTML: Constants.ZWSP,
label: escapeHtml(title),
click() {
filterElement.setAttribute("data-id", id);
filterElement.setAttribute("data-cardtype", cardType);
fetchNewRound();
},
}).element);
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
}
response.data.forEach((deck: { id: string, name: string }) => {
window.siyuan.menus.menu.append(new MenuItem({
iconHTML: Constants.ZWSP,
label: escapeHtml(deck.name),
click() {
filterElement.setAttribute("data-id", deck.id);
filterElement.setAttribute("data-cardtype", "all");
fetchNewRound();
},
}).element);
});
const filterRect = filterTempElement.getBoundingClientRect();
window.siyuan.menus.menu.popup({x: filterRect.left, y: filterRect.bottom});
});
event.stopPropagation();
event.preventDefault();
return;
}
const newroundElement = hasClosestByAttribute(target, "data-type", "newround");
if (newroundElement) {
fetchNewRound();
event.stopPropagation();
event.preventDefault();
return;
}
}
if (!type) {
const buttonElement = hasClosestByClassName(target, "b3-button");
if (buttonElement) {
type = buttonElement.getAttribute("data-type");
}
}
if (!type || !blocks[index]) {
return;
}
event.preventDefault();
event.stopPropagation();
hideElements(["toolbar", "hint", "util"], editor.protyle);
if (type === "-1") { // 显示答案
if (actionElements[0].classList.contains("fn__none")) {
return;
}
editor.protyle.element.classList.remove("card__block--hidemark", "card__block--hideli", "card__block--hidesb");
actionElements[0].classList.add("fn__none");
actionElements[1].querySelectorAll(".b3-button").forEach((element, btnIndex) => {
if (btnIndex !== 0) {
element.previousElementSibling.textContent = blocks[index].nextDues[btnIndex - 1];
}
});
actionElements[1].classList.remove("fn__none");
return;
}
if (type === "-2") { // 上一步
if (actionElements[0].classList.contains("fn__none")) {
return;
}
if (index > 0) {
index--;
nextCard({
countElement,
editor,
actionElements,
index,
blocks
});
}
return;
}
if (["0", "1", "2", "3", "-3"].includes(type) && actionElements[0].classList.contains("fn__none")) {
fetchPost(type === "-3" ? "/api/riff/skipReviewRiffCard" : "/api/riff/reviewRiffCard", {
deckID: blocks[index].deckID,
cardID: blocks[index].cardID,
rating: parseInt(type),
reviewedCards: blocks
}, () => {
/// #if MOBILE
if (type !== "-3" &&
(0 !== window.siyuan.config.sync.provider || (0 === window.siyuan.config.sync.provider && !needSubscribe(""))) &&
window.siyuan.config.repo.key && window.siyuan.config.sync.enabled) {
document.getElementById("toolbarSync").classList.remove("fn__none");
}
/// #endif
index++;
if (index > blocks.length - 1) {
const currentCardType = filterElement.getAttribute("data-cardtype");
fetchPost(currentCardType === "all" ? "/api/riff/getRiffDueCards" :
(currentCardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), {
rootID: filterElement.getAttribute("data-id"),
deckID: filterElement.getAttribute("data-id"),
notebook: filterElement.getAttribute("data-id"),
reviewedCards: blocks
}, (result) => {
index = 0;
blocks = result.data.cards;
if (blocks.length === 0) {
if (result.data.unreviewedCount > 0) {
newRound(countElement, editor, actionElements, result.data.unreviewedCount);
} else {
allDone(countElement, editor, actionElements);
}
} else {
nextCard({
countElement,
editor,
actionElements,
index,
blocks
});
}
});
return;
}
nextCard({
countElement,
editor,
actionElements,
index,
blocks
});
});
}
});
};
const nextCard = (options: {
countElement: Element, editor: Protyle, actionElements: NodeListOf