mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 22:50:13 +01:00
Improve spaced repetition interface (#15627)
* Improve spaced repetition interface fix https://github.com/siyuan-note/siyuan/issues/10331 * Improve spaced repetition interface fix https://github.com/siyuan-note/siyuan/issues/14149 * Improve spaced repetition interface fix https://github.com/siyuan-note/siyuan/issues/10331 * Improve spaced repetition interface fix https://github.com/siyuan-note/siyuan/issues/10331
This commit is contained in:
parent
404d9f63d0
commit
b6a9ef2bb5
2 changed files with 113 additions and 64 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import {Tab} from "../layout/Tab";
|
import {Tab} from "../layout/Tab";
|
||||||
import {Custom} from "../layout/dock/Custom";
|
import {Custom} from "../layout/dock/Custom";
|
||||||
import {bindCardEvent, genCardHTML} from "./openCard";
|
import {bindCardEvent, genCardHTML, initCardComponent} from "./openCard";
|
||||||
import {fetchPost} from "../util/fetch";
|
import {fetchPost} from "../util/fetch";
|
||||||
import {Protyle} from "../protyle";
|
import {Protyle} from "../protyle";
|
||||||
import {setPanelFocus} from "../layout/util";
|
import {setPanelFocus} from "../layout/util";
|
||||||
|
|
@ -19,6 +19,57 @@ export const newCardModel = (options: {
|
||||||
}
|
}
|
||||||
}) => {
|
}) => {
|
||||||
let editor: Protyle;
|
let editor: Protyle;
|
||||||
|
|
||||||
|
const fetchCardsData = async (): Promise<ICardData> => {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
fetchPost(options.data.cardType === "all" ? "/api/riff/getRiffDueCards" :
|
||||||
|
(options.data.cardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), {
|
||||||
|
rootID: options.data.id,
|
||||||
|
deckID: options.data.id,
|
||||||
|
notebook: options.data.id,
|
||||||
|
}, async (response) => {
|
||||||
|
let cardsData: ICardData = response.data;
|
||||||
|
for (let i = 0; i < options.app.plugins.length; i++) {
|
||||||
|
cardsData = await options.app.plugins[i].updateCards(response.data);
|
||||||
|
}
|
||||||
|
resolve(cardsData);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderCardsAndBindEvents = async (element: HTMLElement, data: any, cardsData: ICardData, index?: number, isUpdate?: boolean) => {
|
||||||
|
customObj.editors.forEach(editor => {
|
||||||
|
editor.destroy();
|
||||||
|
});
|
||||||
|
customObj.editors.length = 0;
|
||||||
|
|
||||||
|
element.innerHTML = genCardHTML({
|
||||||
|
id: data.id,
|
||||||
|
cardType: data.cardType,
|
||||||
|
cardsData,
|
||||||
|
isTab: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const cardOptions = {
|
||||||
|
app: options.app,
|
||||||
|
element: element,
|
||||||
|
id: data.id,
|
||||||
|
title: data.title,
|
||||||
|
cardType: data.cardType,
|
||||||
|
cardsData,
|
||||||
|
index,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isUpdate) {
|
||||||
|
const initResult = await initCardComponent(cardOptions);
|
||||||
|
editor = initResult.editor;
|
||||||
|
} else {
|
||||||
|
editor = await bindCardEvent(cardOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
customObj.editors.push(editor);
|
||||||
|
};
|
||||||
|
|
||||||
const customObj = new Custom({
|
const customObj = new Custom({
|
||||||
app: options.app,
|
app: options.app,
|
||||||
type: "siyuan-card",
|
type: "siyuan-card",
|
||||||
|
|
@ -26,58 +77,18 @@ export const newCardModel = (options: {
|
||||||
data: options.data,
|
data: options.data,
|
||||||
async init() {
|
async init() {
|
||||||
if (options.data.cardsData) {
|
if (options.data.cardsData) {
|
||||||
|
// 使用现有的 cardsData
|
||||||
for (let i = 0; i < options.app.plugins.length; i++) {
|
for (let i = 0; i < options.app.plugins.length; i++) {
|
||||||
options.data.cardsData = await options.app.plugins[i].updateCards(options.data.cardsData);
|
options.data.cardsData = await options.app.plugins[i].updateCards(options.data.cardsData);
|
||||||
}
|
}
|
||||||
this.element.innerHTML = genCardHTML({
|
await renderCardsAndBindEvents(this.element, this.data, options.data.cardsData, options.data.index);
|
||||||
id: this.data.id,
|
|
||||||
cardType: this.data.cardType,
|
|
||||||
cardsData: options.data.cardsData,
|
|
||||||
isTab: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
editor = await bindCardEvent({
|
|
||||||
app: options.app,
|
|
||||||
element: this.element,
|
|
||||||
id: this.data.id,
|
|
||||||
title: this.data.title,
|
|
||||||
cardType: this.data.cardType,
|
|
||||||
cardsData: options.data.cardsData,
|
|
||||||
index: options.data.index,
|
|
||||||
});
|
|
||||||
customObj.editors.push(editor);
|
|
||||||
// https://github.com/siyuan-note/siyuan/issues/9561#issuecomment-1794473512
|
// https://github.com/siyuan-note/siyuan/issues/9561#issuecomment-1794473512
|
||||||
delete options.data.cardsData;
|
delete options.data.cardsData;
|
||||||
delete options.data.index;
|
delete options.data.index;
|
||||||
} else {
|
} else {
|
||||||
fetchPost(this.data.cardType === "all" ? "/api/riff/getRiffDueCards" :
|
// 获取新的 cardsData
|
||||||
(this.data.cardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), {
|
const cardsData = await fetchCardsData();
|
||||||
rootID: this.data.id,
|
await renderCardsAndBindEvents(this.element, this.data, cardsData);
|
||||||
deckID: this.data.id,
|
|
||||||
notebook: this.data.id,
|
|
||||||
}, async (response) => {
|
|
||||||
let cardsData: ICardData = response.data;
|
|
||||||
for (let i = 0; i < options.app.plugins.length; i++) {
|
|
||||||
cardsData = await options.app.plugins[i].updateCards(response.data);
|
|
||||||
}
|
|
||||||
this.element.innerHTML = genCardHTML({
|
|
||||||
id: this.data.id,
|
|
||||||
cardType: this.data.cardType,
|
|
||||||
cardsData,
|
|
||||||
isTab: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
editor = await bindCardEvent({
|
|
||||||
app: options.app,
|
|
||||||
element: this.element,
|
|
||||||
id: this.data.id,
|
|
||||||
title: this.data.title,
|
|
||||||
cardType: this.data.cardType,
|
|
||||||
cardsData,
|
|
||||||
});
|
|
||||||
|
|
||||||
customObj.editors.push(editor);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
|
|
@ -90,23 +101,9 @@ export const newCardModel = (options: {
|
||||||
editor.resize();
|
editor.resize();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
update() {
|
async update() {
|
||||||
fetchPost(this.data.cardType === "all" ? "/api/riff/getRiffDueCards" :
|
const cardsData = await fetchCardsData();
|
||||||
(this.data.cardType === "doc" ? "/api/riff/getTreeRiffDueCards" : "/api/riff/getNotebookRiffDueCards"), {
|
await renderCardsAndBindEvents(this.element, this.data, cardsData ,undefined, true);
|
||||||
rootID: this.data.id,
|
|
||||||
deckID: this.data.id,
|
|
||||||
notebook: this.data.id,
|
|
||||||
}, async (response) => {
|
|
||||||
for (let i = 0; i < options.app.plugins.length; i++) {
|
|
||||||
options.data.cardsData = await options.app.plugins[i].updateCards(options.data.cardsData);
|
|
||||||
}
|
|
||||||
this.element.innerHTML = genCardHTML({
|
|
||||||
id: this.data.id,
|
|
||||||
cardType: this.data.cardType,
|
|
||||||
cardsData: response.data,
|
|
||||||
isTab: true,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
customObj.element.addEventListener("click", () => {
|
customObj.element.addEventListener("click", () => {
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ const getEditor = (id: string, protyle: IProtyle, element: Element, currentCard:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const bindCardEvent = async (options: {
|
export const initCardComponent = async (options: {
|
||||||
app: App,
|
app: App,
|
||||||
element: Element,
|
element: Element,
|
||||||
title?: string,
|
title?: string,
|
||||||
|
|
@ -301,6 +301,33 @@ export const bindCardEvent = async (options: {
|
||||||
};
|
};
|
||||||
|
|
||||||
countElement.innerHTML = genCardCount(options.cardsData, index);
|
countElement.innerHTML = genCardCount(options.cardsData, index);
|
||||||
|
|
||||||
|
return {
|
||||||
|
editor,
|
||||||
|
index,
|
||||||
|
actionElements,
|
||||||
|
countElement,
|
||||||
|
filterElement,
|
||||||
|
fetchNewRound
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const bindCardEvent = async (options: {
|
||||||
|
app: App,
|
||||||
|
element: Element,
|
||||||
|
title?: string,
|
||||||
|
cardsData: ICardData
|
||||||
|
cardType: TCardType,
|
||||||
|
id?: string,
|
||||||
|
dialog?: Dialog,
|
||||||
|
index?: number
|
||||||
|
}) => {
|
||||||
|
// 初始化卡片组件
|
||||||
|
const initResult = await initCardComponent(options);
|
||||||
|
const { editor, actionElements, countElement, filterElement, fetchNewRound } = initResult;
|
||||||
|
let index = initResult.index;
|
||||||
|
|
||||||
|
// 绑定点击事件
|
||||||
options.element.addEventListener("click", (event: MouseEvent) => {
|
options.element.addEventListener("click", (event: MouseEvent) => {
|
||||||
const target = event.target as HTMLElement;
|
const target = event.target as HTMLElement;
|
||||||
let type = "";
|
let type = "";
|
||||||
|
|
@ -489,6 +516,29 @@ export const bindCardEvent = async (options: {
|
||||||
const sticktabElement = hasClosestByAttribute(target, "data-type", "sticktab");
|
const sticktabElement = hasClosestByAttribute(target, "data-type", "sticktab");
|
||||||
if (sticktabElement) {
|
if (sticktabElement) {
|
||||||
const stickMenu = new Menu();
|
const stickMenu = new Menu();
|
||||||
|
stickMenu.addItem({
|
||||||
|
id: "openInNewTab",
|
||||||
|
icon: "iconOpen",
|
||||||
|
label: window.siyuan.languages.openInNewTab,
|
||||||
|
click() {
|
||||||
|
openFile({
|
||||||
|
app: options.app,
|
||||||
|
custom: {
|
||||||
|
icon: "iconRiffCard",
|
||||||
|
title: window.siyuan.languages.spaceRepetition,
|
||||||
|
data: {
|
||||||
|
cardsData: options.cardsData,
|
||||||
|
index,
|
||||||
|
cardType: filterElement.getAttribute("data-cardtype") as TCardType,
|
||||||
|
id: docId,
|
||||||
|
title: options.title
|
||||||
|
},
|
||||||
|
id: "siyuan-card"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
options.dialog.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
stickMenu.addItem({
|
stickMenu.addItem({
|
||||||
id: "insertRight",
|
id: "insertRight",
|
||||||
icon: "iconLayoutRight",
|
icon: "iconLayoutRight",
|
||||||
|
|
@ -527,6 +577,8 @@ export const bindCardEvent = async (options: {
|
||||||
"instance": "Custom",
|
"instance": "Custom",
|
||||||
"customModelType": "siyuan-card",
|
"customModelType": "siyuan-card",
|
||||||
"customModelData": {
|
"customModelData": {
|
||||||
|
"cardsData": options.cardsData,
|
||||||
|
"index": index,
|
||||||
"cardType": filterElement.getAttribute("data-cardtype"),
|
"cardType": filterElement.getAttribute("data-cardtype"),
|
||||||
"id": docId,
|
"id": docId,
|
||||||
"title": options.title
|
"title": options.title
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue