From 2c78eb48f35ee0ea8b1d1e15044da9b81aa72e36 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 3 Jul 2024 13:43:46 +0800 Subject: [PATCH 1/8] extract markdown rendering logic --- src/gui/FlashcardReviewView.tsx | 67 ++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/src/gui/FlashcardReviewView.tsx b/src/gui/FlashcardReviewView.tsx index cb6024b4..42e62ae1 100644 --- a/src/gui/FlashcardReviewView.tsx +++ b/src/gui/FlashcardReviewView.tsx @@ -131,12 +131,7 @@ export class FlashcardReviewView { // Setup card content this.content.empty(); - const wrapper: RenderMarkdownWrapper = new RenderMarkdownWrapper( - this.app, - this.plugin, - this._currentNote.filePath, - ); - await wrapper.renderMarkdownWrapper(this._currentCard.front, this.content); + await this._renderMarkdownFront(); // Setup response buttons this._resetResponseButtons(); @@ -150,6 +145,30 @@ export class FlashcardReviewView { document.addEventListener("keydown", this._keydownHandler); } + /** + * If the card is already being shown, re-render just the Markdown + * contents if needed + */ + async rerenderCardContents() { + this.content.empty(); + this._renderMarkdownFront(); + if (this.mode == FlashcardModalMode.Back) { + this._renderMarkdownBackAndDivider(); + } + } + + /** + * Set up the Markdown rendering for the card's front side + */ + private async _renderMarkdownFront() { + const wrapper: RenderMarkdownWrapper = new RenderMarkdownWrapper( + this.app, + this.plugin, + this._currentNote.filePath + ); + await wrapper.renderMarkdownWrapper(this._currentCard.front, this.content); + } + /** * Hides the FlashcardView */ @@ -276,21 +295,7 @@ export class FlashcardReviewView { this.resetButton.disabled = false; - // Show answer text - if (this._currentQuestion.questionType !== CardType.Cloze) { - const hr: HTMLElement = document.createElement("hr"); - hr.addClass("sr-card-divide"); - this.content.appendChild(hr); - } else { - this.content.empty(); - } - - const wrapper: RenderMarkdownWrapper = new RenderMarkdownWrapper( - this.app, - this.plugin, - this._currentNote.filePath, - ); - wrapper.renderMarkdownWrapper(this._currentCard.back, this.content); + this._renderMarkdownBackAndDivider(); // Show response buttons this.answerButton.addClass("sr-is-hidden"); @@ -321,6 +326,26 @@ export class FlashcardReviewView { } } + /** + * Setup Markdown rendering for the card's back side and the divider + */ + private _renderMarkdownBackAndDivider() { + if (this._currentQuestion.questionType !== CardType.Cloze) { + const hr: HTMLElement = document.createElement("hr"); + hr.addClass("sr-card-divide"); + this.content.appendChild(hr); + } else { + this.content.empty(); + } + + const wrapper: RenderMarkdownWrapper = new RenderMarkdownWrapper( + this.app, + this.plugin, + this._currentNote.filePath + ); + wrapper.renderMarkdownWrapper(this._currentCard.back, this.content); + } + private async _processReview(response: ReviewResponse): Promise { await this.reviewSequencer.processReview(response); await this._handleSkipCard(); From 4562a90cec6d3eda9fc8d05b250123959c59f17d Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 3 Jul 2024 13:44:57 +0800 Subject: [PATCH 2/8] implement updateCurrentQuestionTextAndCards --- src/FlashcardReviewSequencer.ts | 26 ++++++++++++++++----- src/gui/FlashcardModal.tsx | 4 +++- tests/unit/FlashcardReviewSequencer.test.ts | 4 ++-- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/FlashcardReviewSequencer.ts b/src/FlashcardReviewSequencer.ts index 5ef74668..04446650 100644 --- a/src/FlashcardReviewSequencer.ts +++ b/src/FlashcardReviewSequencer.ts @@ -8,6 +8,7 @@ import { CardScheduleInfo, ICardScheduleCalculator } from "./CardSchedule"; import { Note } from "./Note"; import { IDeckTreeIterator } from "./DeckTreeIterator"; import { IQuestionPostponementList } from "./QuestionPostponementList"; +import { CardFrontBack, CardFrontBackUtil } from "./QuestionType"; export interface IFlashcardReviewSequencer { get hasCurrentCard(): boolean; @@ -23,7 +24,7 @@ export interface IFlashcardReviewSequencer { skipCurrentCard(): void; determineCardSchedule(response: ReviewResponse, card: Card): CardScheduleInfo; processReview(response: ReviewResponse): Promise; - updateCurrentQuestionText(text: string): Promise; + updateCurrentQuestionTextAndCards(text: string): Promise; } export class DeckStats { @@ -207,11 +208,24 @@ export class FlashcardReviewSequencer implements IFlashcardReviewSequencer { return result; } - async updateCurrentQuestionText(text: string): Promise { - const q: QuestionText = this.currentQuestion.questionText; - + async updateCurrentQuestionTextAndCards(text: string): Promise { + const question = this.currentQuestion; + const q: QuestionText = question.questionText; q.actualQuestion = text; + // Update front/back properties of all cards which question is linked to + const cardFrontBackList: CardFrontBack[] = CardFrontBackUtil.expand( + question.questionType, + question.questionText.actualQuestion, + this.settings + ) + await this.currentQuestion.writeQuestion(this.settings); - } -} + + question.cards.forEach((card, i) => { + const { front, back } = cardFrontBackList[i]; + card.front = front; + card.back = back; + }) + } +} \ No newline at end of file diff --git a/src/gui/FlashcardModal.tsx b/src/gui/FlashcardModal.tsx index 9ff4b372..864eab50 100644 --- a/src/gui/FlashcardModal.tsx +++ b/src/gui/FlashcardModal.tsx @@ -14,6 +14,7 @@ import { import { FlashcardEditModal } from "./EditModal"; import { DeckListView } from "./DeckListView"; import { FlashcardReviewView } from "./FlashcardReviewView"; +import { CardFrontBack, CardFrontBackUtil } from "src/QuestionType"; export enum FlashcardModalMode { DecksList, @@ -121,7 +122,8 @@ export class FlashcardModal extends Modal { const editModal = FlashcardEditModal.Prompt(this.app, textPrompt); editModal .then(async (modifiedCardText) => { - this.reviewSequencer.updateCurrentQuestionText(modifiedCardText); + await this.reviewSequencer.updateCurrentQuestionTextAndCards(modifiedCardText); + this.flashcardView.rerenderCardContents() }) .catch((reason) => console.log(reason)); } diff --git a/tests/unit/FlashcardReviewSequencer.test.ts b/tests/unit/FlashcardReviewSequencer.test.ts index 7d67a93f..5bf2224d 100644 --- a/tests/unit/FlashcardReviewSequencer.test.ts +++ b/tests/unit/FlashcardReviewSequencer.test.ts @@ -753,7 +753,7 @@ ${indent}- bar?::baz }); }); -describe("updateCurrentQuestionText", () => { +describe("updateCurrentQuestionTextAndCards", () => { let space: string = " "; describe("Checking update to file", () => { @@ -1161,7 +1161,7 @@ async function checkUpdateCurrentQuestionText( await c.setSequencerDeckTreeFromOriginalText(); expect(c.reviewSequencer.currentCard.front).toEqual("Q2"); - await c.reviewSequencer.updateCurrentQuestionText(updatedQ); + await c.reviewSequencer.updateCurrentQuestionTextAndCards(updatedQ); // originalText should remain the same except for the specific substring change from originalStr => updatedStr if (!c.originalText.includes(originalStr)) throw `Text not found: ${originalStr}`; From efce503091aea5305519d693fc6ff55cf2e36bc4 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 3 Jul 2024 14:04:05 +0800 Subject: [PATCH 3/8] apply linter fixes --- src/FlashcardReviewSequencer.ts | 10 +++++----- src/gui/FlashcardModal.tsx | 2 +- src/gui/FlashcardReviewView.tsx | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/FlashcardReviewSequencer.ts b/src/FlashcardReviewSequencer.ts index 04446650..28c41b28 100644 --- a/src/FlashcardReviewSequencer.ts +++ b/src/FlashcardReviewSequencer.ts @@ -217,15 +217,15 @@ export class FlashcardReviewSequencer implements IFlashcardReviewSequencer { const cardFrontBackList: CardFrontBack[] = CardFrontBackUtil.expand( question.questionType, question.questionText.actualQuestion, - this.settings - ) + this.settings, + ); await this.currentQuestion.writeQuestion(this.settings); - + question.cards.forEach((card, i) => { const { front, back } = cardFrontBackList[i]; card.front = front; card.back = back; - }) + }); } -} \ No newline at end of file +} diff --git a/src/gui/FlashcardModal.tsx b/src/gui/FlashcardModal.tsx index 864eab50..70e39a12 100644 --- a/src/gui/FlashcardModal.tsx +++ b/src/gui/FlashcardModal.tsx @@ -123,7 +123,7 @@ export class FlashcardModal extends Modal { editModal .then(async (modifiedCardText) => { await this.reviewSequencer.updateCurrentQuestionTextAndCards(modifiedCardText); - this.flashcardView.rerenderCardContents() + this.flashcardView.rerenderCardContents(); }) .catch((reason) => console.log(reason)); } diff --git a/src/gui/FlashcardReviewView.tsx b/src/gui/FlashcardReviewView.tsx index 42e62ae1..ee54cd12 100644 --- a/src/gui/FlashcardReviewView.tsx +++ b/src/gui/FlashcardReviewView.tsx @@ -164,7 +164,7 @@ export class FlashcardReviewView { const wrapper: RenderMarkdownWrapper = new RenderMarkdownWrapper( this.app, this.plugin, - this._currentNote.filePath + this._currentNote.filePath, ); await wrapper.renderMarkdownWrapper(this._currentCard.front, this.content); } @@ -341,7 +341,7 @@ export class FlashcardReviewView { const wrapper: RenderMarkdownWrapper = new RenderMarkdownWrapper( this.app, this.plugin, - this._currentNote.filePath + this._currentNote.filePath, ); wrapper.renderMarkdownWrapper(this._currentCard.back, this.content); } From 46450fade867f9031f406366002ea8e8572bd83a Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 3 Jul 2024 14:51:29 +0800 Subject: [PATCH 4/8] update FlashcardReviewSequencer tests --- tests/unit/FlashcardReviewSequencer.test.ts | 96 ++++++++++++++++++--- 1 file changed, 85 insertions(+), 11 deletions(-) diff --git a/tests/unit/FlashcardReviewSequencer.test.ts b/tests/unit/FlashcardReviewSequencer.test.ts index 5bf2224d..e275d5ad 100644 --- a/tests/unit/FlashcardReviewSequencer.test.ts +++ b/tests/unit/FlashcardReviewSequencer.test.ts @@ -772,11 +772,16 @@ describe("updateCurrentQuestionTextAndCards", () => { `; let updatedStr: string = `#flashcards A much more in depth question::A much more detailed answer `; - await checkUpdateCurrentQuestionText( + let updatedFront = `A much more in depth question` + let updatedBack = `A much more detailed answer` + + await checkUpdateCurrentQuestionTextAndCard( text, updatedQ, originalStr, updatedStr, + updatedFront, + updatedBack, DEFAULT_SETTINGS, ); }); @@ -793,13 +798,19 @@ describe("updateCurrentQuestionTextAndCards", () => { let originalStr: string = `#flashcards Q2::A2 `; let expectedUpdatedStr: string = `#flashcards A much more in depth question::A much more detailed answer `; - await checkUpdateCurrentQuestionText( + let updatedFront = `A much more in depth question` + let updatedBack = `A much more detailed answer` + + await checkUpdateCurrentQuestionTextAndCard( text, updatedQ, originalStr, expectedUpdatedStr, + updatedFront, + updatedBack, DEFAULT_SETTINGS, ); + }); }); @@ -818,13 +829,20 @@ describe("updateCurrentQuestionTextAndCards", () => { let updatedQ: string = "A much more in depth question::A much more detailed answer"; let originalStr: string = `#flashcards Q2::A2 `; let updatedStr: string = `#flashcards A much more in depth question::A much more detailed answer `; - await checkUpdateCurrentQuestionText( + + let updatedFront = `A much more in depth question` + let updatedBack = `A much more detailed answer` + + await checkUpdateCurrentQuestionTextAndCard( text1, updatedQ, originalStr, updatedStr, + updatedFront, + updatedBack, settings, ); + }); test("Question has schedule on following line (but placed on same line due to settings)", async () => { @@ -840,13 +858,21 @@ describe("updateCurrentQuestionTextAndCards", () => { let originalStr: string = `#flashcards Q2::A2 `; let updatedStr: string = `#flashcards A much more in depth question::A much more detailed answer `; - await checkUpdateCurrentQuestionText( + + let updatedFront = "A much more in depth question" + let updatedBack = "A much more detailed answer" + + + await checkUpdateCurrentQuestionTextAndCard( text, updatedQ, originalStr, updatedStr, + updatedFront, + updatedBack, settings, ); + }); }); @@ -877,13 +903,21 @@ A2 (answer now includes more detail) extra answer line 2 `; - await checkUpdateCurrentQuestionText( + let updatedFront = `Multiline question +Question starting immediately after tag` + let updatedBack = `A2 (answer now includes more detail) +extra answer line 2` + + await checkUpdateCurrentQuestionTextAndCard( text, updatedQ, originalStr, expectedUpdatedStr, + updatedFront, + updatedBack, DEFAULT_SETTINGS, ); + }); test("Question starts on same line as tag (after two spaces); Existing schedule present", async () => { @@ -912,13 +946,21 @@ A2 (answer now includes more detail) extra answer line 2 `; - await checkUpdateCurrentQuestionText( + let updatedFront = `Multiline question +Question starting immediately after tag` + let updatedBack = `A2 (answer now includes more detail) +extra answer line 2` + + await checkUpdateCurrentQuestionTextAndCard( text, updatedQ, originalStr, expectedUpdatedStr, + updatedFront, + updatedBack, DEFAULT_SETTINGS, ); + }); test("Question starts line after tag; Existing schedule present", async () => { @@ -949,13 +991,21 @@ A2 (answer now includes more detail) extra answer line 2 `; - await checkUpdateCurrentQuestionText( + let updatedFront = `Multiline question +Question starting line after tag` + let updatedBack = `A2 (answer now includes more detail) +extra answer line 2` + + await checkUpdateCurrentQuestionTextAndCard( text, updatedQ, originalStr, expectedUpdatedStr, + updatedFront, + updatedBack, DEFAULT_SETTINGS, ); + }); test("Question starts line after tag (no white space after tag); New card", async () => { @@ -980,11 +1030,18 @@ extra answer line 2`; let expectedUpdatedStr: string = `#flashcards ${updatedQuestionText}`; - await checkUpdateCurrentQuestionText( + let updatedFront = `Multiline question +Question starting immediately after tag`; + let updatedBack = `A2 (answer now includes more detail) +extra answer line 2` + + await checkUpdateCurrentQuestionTextAndCard( fileText, updatedQuestionText, originalQuestionStr, expectedUpdatedStr, + updatedFront, + updatedBack, DEFAULT_SETTINGS, ); }); @@ -1011,11 +1068,18 @@ extra answer line 2`; let expectedUpdatedStr: string = `#flashcards ${updatedQuestionText}`; - await checkUpdateCurrentQuestionText( + let updatedFront = `Multiline question +Question starting immediately after tag` + let updatedBack = `A2 (answer now includes more detail) +extra answer line 2` + + await checkUpdateCurrentQuestionTextAndCard( fileText, updatedQuestionText, originalQuestionStr, expectedUpdatedStr, + updatedFront, + updatedBack, DEFAULT_SETTINGS, ); }); @@ -1113,12 +1177,16 @@ describe("Sequences", () => { let updatedQ: string = "A much more in depth question::A much more detailed answer"; let originalStr: string = `#flashcards Q2::A2`; let updatedStr: string = `#flashcards A much more in depth question::A much more detailed answer`; + let updatedFront = 'A much more in depth question' + let updatedBack = 'A much more detailed answer' - let c: TestContext = await checkUpdateCurrentQuestionText( + let c: TestContext = await checkUpdateCurrentQuestionTextAndCard( text1, updatedQ, originalStr, updatedStr, + updatedFront, + updatedBack, DEFAULT_SETTINGS, ); @@ -1145,11 +1213,13 @@ function skipAndCheckNoRemainingCards(c: TestContext) { expect(c.reviewSequencer.hasCurrentCard).toEqual(false); } -async function checkUpdateCurrentQuestionText( +async function checkUpdateCurrentQuestionTextAndCard( noteText: string, updatedQ: string, originalStr: string, updatedStr: string, + updatedFront: string, + updatedBack: string, settings: SRSettings, ): Promise { let c: TestContext = TestContext.Create( @@ -1167,5 +1237,9 @@ async function checkUpdateCurrentQuestionText( if (!c.originalText.includes(originalStr)) throw `Text not found: ${originalStr}`; let expectedFileText: string = c.originalText.replace(originalStr, updatedStr); expect(await c.file.read()).toEqual(expectedFileText); + + expect(c.reviewSequencer.currentCard.front).toStrictEqual(updatedFront); + expect(c.reviewSequencer.currentCard.back).toStrictEqual(updatedBack); + return c; } From adb505e533c35a5693cf196d850e91f3b1fbffb6 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 3 Jul 2024 14:53:50 +0800 Subject: [PATCH 5/8] fix linter issues --- tests/unit/FlashcardReviewSequencer.test.ts | 45 +++++++++------------ 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/tests/unit/FlashcardReviewSequencer.test.ts b/tests/unit/FlashcardReviewSequencer.test.ts index e275d5ad..10a65fff 100644 --- a/tests/unit/FlashcardReviewSequencer.test.ts +++ b/tests/unit/FlashcardReviewSequencer.test.ts @@ -772,8 +772,8 @@ describe("updateCurrentQuestionTextAndCards", () => { `; let updatedStr: string = `#flashcards A much more in depth question::A much more detailed answer `; - let updatedFront = `A much more in depth question` - let updatedBack = `A much more detailed answer` + let updatedFront = `A much more in depth question`; + let updatedBack = `A much more detailed answer`; await checkUpdateCurrentQuestionTextAndCard( text, @@ -798,8 +798,8 @@ describe("updateCurrentQuestionTextAndCards", () => { let originalStr: string = `#flashcards Q2::A2 `; let expectedUpdatedStr: string = `#flashcards A much more in depth question::A much more detailed answer `; - let updatedFront = `A much more in depth question` - let updatedBack = `A much more detailed answer` + let updatedFront = `A much more in depth question`; + let updatedBack = `A much more detailed answer`; await checkUpdateCurrentQuestionTextAndCard( text, @@ -810,7 +810,6 @@ describe("updateCurrentQuestionTextAndCards", () => { updatedBack, DEFAULT_SETTINGS, ); - }); }); @@ -830,8 +829,8 @@ describe("updateCurrentQuestionTextAndCards", () => { let originalStr: string = `#flashcards Q2::A2 `; let updatedStr: string = `#flashcards A much more in depth question::A much more detailed answer `; - let updatedFront = `A much more in depth question` - let updatedBack = `A much more detailed answer` + let updatedFront = `A much more in depth question`; + let updatedBack = `A much more detailed answer`; await checkUpdateCurrentQuestionTextAndCard( text1, @@ -842,7 +841,6 @@ describe("updateCurrentQuestionTextAndCards", () => { updatedBack, settings, ); - }); test("Question has schedule on following line (but placed on same line due to settings)", async () => { @@ -859,9 +857,8 @@ describe("updateCurrentQuestionTextAndCards", () => { `; let updatedStr: string = `#flashcards A much more in depth question::A much more detailed answer `; - let updatedFront = "A much more in depth question" - let updatedBack = "A much more detailed answer" - + let updatedFront = "A much more in depth question"; + let updatedBack = "A much more detailed answer"; await checkUpdateCurrentQuestionTextAndCard( text, @@ -872,7 +869,6 @@ describe("updateCurrentQuestionTextAndCards", () => { updatedBack, settings, ); - }); }); @@ -904,9 +900,9 @@ extra answer line 2 `; let updatedFront = `Multiline question -Question starting immediately after tag` +Question starting immediately after tag`; let updatedBack = `A2 (answer now includes more detail) -extra answer line 2` +extra answer line 2`; await checkUpdateCurrentQuestionTextAndCard( text, @@ -917,7 +913,6 @@ extra answer line 2` updatedBack, DEFAULT_SETTINGS, ); - }); test("Question starts on same line as tag (after two spaces); Existing schedule present", async () => { @@ -947,9 +942,9 @@ extra answer line 2 `; let updatedFront = `Multiline question -Question starting immediately after tag` +Question starting immediately after tag`; let updatedBack = `A2 (answer now includes more detail) -extra answer line 2` +extra answer line 2`; await checkUpdateCurrentQuestionTextAndCard( text, @@ -960,7 +955,6 @@ extra answer line 2` updatedBack, DEFAULT_SETTINGS, ); - }); test("Question starts line after tag; Existing schedule present", async () => { @@ -992,9 +986,9 @@ extra answer line 2 `; let updatedFront = `Multiline question -Question starting line after tag` +Question starting line after tag`; let updatedBack = `A2 (answer now includes more detail) -extra answer line 2` +extra answer line 2`; await checkUpdateCurrentQuestionTextAndCard( text, @@ -1005,7 +999,6 @@ extra answer line 2` updatedBack, DEFAULT_SETTINGS, ); - }); test("Question starts line after tag (no white space after tag); New card", async () => { @@ -1033,7 +1026,7 @@ ${updatedQuestionText}`; let updatedFront = `Multiline question Question starting immediately after tag`; let updatedBack = `A2 (answer now includes more detail) -extra answer line 2` +extra answer line 2`; await checkUpdateCurrentQuestionTextAndCard( fileText, @@ -1069,9 +1062,9 @@ extra answer line 2`; ${updatedQuestionText}`; let updatedFront = `Multiline question -Question starting immediately after tag` +Question starting immediately after tag`; let updatedBack = `A2 (answer now includes more detail) -extra answer line 2` +extra answer line 2`; await checkUpdateCurrentQuestionTextAndCard( fileText, @@ -1177,8 +1170,8 @@ describe("Sequences", () => { let updatedQ: string = "A much more in depth question::A much more detailed answer"; let originalStr: string = `#flashcards Q2::A2`; let updatedStr: string = `#flashcards A much more in depth question::A much more detailed answer`; - let updatedFront = 'A much more in depth question' - let updatedBack = 'A much more detailed answer' + let updatedFront = "A much more in depth question"; + let updatedBack = "A much more detailed answer"; let c: TestContext = await checkUpdateCurrentQuestionTextAndCard( text1, From 7670da3c69e95b5a0940a1b7e70df373bf350bd2 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 3 Jul 2024 15:05:07 +0800 Subject: [PATCH 6/8] add error handling for missing front/back and card length change --- src/FlashcardReviewSequencer.ts | 32 ++++++++++++++++++++++++++++++-- src/gui/FlashcardModal.tsx | 16 +++++++++++++--- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/FlashcardReviewSequencer.ts b/src/FlashcardReviewSequencer.ts index 28c41b28..8631380f 100644 --- a/src/FlashcardReviewSequencer.ts +++ b/src/FlashcardReviewSequencer.ts @@ -211,15 +211,29 @@ export class FlashcardReviewSequencer implements IFlashcardReviewSequencer { async updateCurrentQuestionTextAndCards(text: string): Promise { const question = this.currentQuestion; const q: QuestionText = question.questionText; - q.actualQuestion = text; // Update front/back properties of all cards which question is linked to const cardFrontBackList: CardFrontBack[] = CardFrontBackUtil.expand( question.questionType, - question.questionText.actualQuestion, + text, this.settings, ); + // Prevent the edit if the number of cards linked to the question + // would be changed on edit + if (cardFrontBackList.length != question.cards.length) { + throw new CardLengthMismatchError( + "Mismatch between number of cards generated and current number of cards", + ); + } + + cardFrontBackList.forEach(({ front, back }) => { + if (front.length == 0 || back.length == 0) { + throw new CardFrontBackMissingError("Card's front or back has length of 0."); + } + }); + + q.actualQuestion = text; await this.currentQuestion.writeQuestion(this.settings); question.cards.forEach((card, i) => { @@ -229,3 +243,17 @@ export class FlashcardReviewSequencer implements IFlashcardReviewSequencer { }); } } + +export class CardLengthMismatchError extends Error { + constructor(message: string) { + super(message); + this.name = "CardLengthMismatchError"; + } +} + +export class CardFrontBackMissingError extends Error { + constructor(message: string) { + super(message); + this.name = "CardFrontBackMissingError"; + } +} diff --git a/src/gui/FlashcardModal.tsx b/src/gui/FlashcardModal.tsx index 70e39a12..d0bd5ac5 100644 --- a/src/gui/FlashcardModal.tsx +++ b/src/gui/FlashcardModal.tsx @@ -1,4 +1,4 @@ -import { Modal, App } from "obsidian"; +import { Modal, App, Notice } from "obsidian"; // eslint-disable-next-line @typescript-eslint/no-unused-vars import h from "vhtml"; @@ -8,13 +8,14 @@ import { SRSettings } from "src/settings"; import { Deck } from "../Deck"; import { Question } from "../Question"; import { + CardFrontBackMissingError, + CardLengthMismatchError, FlashcardReviewMode, IFlashcardReviewSequencer as IFlashcardReviewSequencer, } from "src/FlashcardReviewSequencer"; import { FlashcardEditModal } from "./EditModal"; import { DeckListView } from "./DeckListView"; import { FlashcardReviewView } from "./FlashcardReviewView"; -import { CardFrontBack, CardFrontBackUtil } from "src/QuestionType"; export enum FlashcardModalMode { DecksList, @@ -125,6 +126,15 @@ export class FlashcardModal extends Modal { await this.reviewSequencer.updateCurrentQuestionTextAndCards(modifiedCardText); this.flashcardView.rerenderCardContents(); }) - .catch((reason) => console.log(reason)); + .catch((reason) => { + if (reason instanceof CardLengthMismatchError) { + new Notice( + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + ); + } else if (reason instanceof CardFrontBackMissingError) { + new Notice("Unable to update flashcard. Missing front or back side of card."); + } + console.log(reason); + }); } } From bfc2b904b4f25d3187ac3e137a3ae8b6d8301ad6 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 3 Jul 2024 15:14:18 +0800 Subject: [PATCH 7/8] add notices to locale map --- src/gui/FlashcardModal.tsx | 7 +++---- src/lang/locale/en.ts | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/FlashcardModal.tsx b/src/gui/FlashcardModal.tsx index d0bd5ac5..f90f98a3 100644 --- a/src/gui/FlashcardModal.tsx +++ b/src/gui/FlashcardModal.tsx @@ -16,6 +16,7 @@ import { import { FlashcardEditModal } from "./EditModal"; import { DeckListView } from "./DeckListView"; import { FlashcardReviewView } from "./FlashcardReviewView"; +import { t } from "src/lang/helpers"; export enum FlashcardModalMode { DecksList, @@ -128,11 +129,9 @@ export class FlashcardModal extends Modal { }) .catch((reason) => { if (reason instanceof CardLengthMismatchError) { - new Notice( - "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", - ); + new Notice(t("CARD_LENGTH_MISMATCH_NOTICE")); } else if (reason instanceof CardFrontBackMissingError) { - new Notice("Unable to update flashcard. Missing front or back side of card."); + new Notice(t("CARD_FRONT_BACK_MISSING_NOTICE")); } console.log(reason); }); diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 2112229c..e2635fd8 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Current Ease: ", CURRENT_INTERVAL_HELP_TEXT: "Current Interval: ", CARD_GENERATED_FROM: "Generated from: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "Open a note for review", From b55a66e2f8b53b5971c7ee94ff0b88221e60a206 Mon Sep 17 00:00:00 2001 From: Brendan Chen Date: Wed, 3 Jul 2024 16:02:40 +0800 Subject: [PATCH 8/8] update locales for consistency --- src/lang/locale/ar.ts | 3 +++ src/lang/locale/cz.ts | 3 +++ src/lang/locale/de.ts | 3 +++ src/lang/locale/es.ts | 3 +++ src/lang/locale/it.ts | 3 +++ src/lang/locale/ja.ts | 3 +++ src/lang/locale/ko.ts | 3 +++ src/lang/locale/pl.ts | 3 +++ src/lang/locale/pt-br.ts | 3 +++ src/lang/locale/ru.ts | 3 +++ src/lang/locale/zh-cn.ts | 3 +++ src/lang/locale/zh-tw.ts | 3 +++ 12 files changed, 36 insertions(+) diff --git a/src/lang/locale/ar.ts b/src/lang/locale/ar.ts index d4dee92e..fa8e857d 100644 --- a/src/lang/locale/ar.ts +++ b/src/lang/locale/ar.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: ":السهولة الحالية", CURRENT_INTERVAL_HELP_TEXT: ":الفاصل الزمني الحالي", CARD_GENERATED_FROM: "${notePath} :تم إنشاؤها من", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "افتح الملاحظة للمراجعة", diff --git a/src/lang/locale/cz.ts b/src/lang/locale/cz.ts index ebece0a5..2faa2ab8 100644 --- a/src/lang/locale/cz.ts +++ b/src/lang/locale/cz.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Current Ease: ", CURRENT_INTERVAL_HELP_TEXT: "Current Interval: ", CARD_GENERATED_FROM: "Generated from: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "Otevřít poznámku k revizi", diff --git a/src/lang/locale/de.ts b/src/lang/locale/de.ts index d4e142d9..8ae4ed64 100644 --- a/src/lang/locale/de.ts +++ b/src/lang/locale/de.ts @@ -24,6 +24,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Aktuelle Schwierigkeit: ", CURRENT_INTERVAL_HELP_TEXT: "Aktueller Intervall: ", CARD_GENERATED_FROM: "Erstellt von: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "Notiz zur Wiederholung öffnen", diff --git a/src/lang/locale/es.ts b/src/lang/locale/es.ts index 337105ad..838f424f 100644 --- a/src/lang/locale/es.ts +++ b/src/lang/locale/es.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Facilidad Actual: ", CURRENT_INTERVAL_HELP_TEXT: "Intervalo Actual: ", CARD_GENERATED_FROM: "Generado Desde: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "Abrir nota para revisión", diff --git a/src/lang/locale/it.ts b/src/lang/locale/it.ts index 33ddff94..5fbf06be 100644 --- a/src/lang/locale/it.ts +++ b/src/lang/locale/it.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Difficoltà attuale: ", CURRENT_INTERVAL_HELP_TEXT: "Intervallo attuale: ", CARD_GENERATED_FROM: "Generato da: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "Apri una nota per rivisita", diff --git a/src/lang/locale/ja.ts b/src/lang/locale/ja.ts index 96bbbcfd..24577ece 100644 --- a/src/lang/locale/ja.ts +++ b/src/lang/locale/ja.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Current Ease: ", CURRENT_INTERVAL_HELP_TEXT: "Current Interval: ", CARD_GENERATED_FROM: "Generated from: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "レビューするノートを開く", diff --git a/src/lang/locale/ko.ts b/src/lang/locale/ko.ts index 4f1e6206..244ac10a 100644 --- a/src/lang/locale/ko.ts +++ b/src/lang/locale/ko.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Current Ease: ", CURRENT_INTERVAL_HELP_TEXT: "Current Interval: ", CARD_GENERATED_FROM: "Generated from: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "리뷰할 노트 열기", diff --git a/src/lang/locale/pl.ts b/src/lang/locale/pl.ts index 3d3cf47d..92bc5ccc 100644 --- a/src/lang/locale/pl.ts +++ b/src/lang/locale/pl.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Aktualna łatwość: ", CURRENT_INTERVAL_HELP_TEXT: "Aktualny interwał: ", CARD_GENERATED_FROM: "Wygenerowano z: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "Otwórz notatkę do przeglądu", diff --git a/src/lang/locale/pt-br.ts b/src/lang/locale/pt-br.ts index 7656563f..e20e3ccc 100644 --- a/src/lang/locale/pt-br.ts +++ b/src/lang/locale/pt-br.ts @@ -22,6 +22,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Facilidade atual: ", CURRENT_INTERVAL_HELP_TEXT: "Intervalo atual: ", CARD_GENERATED_FROM: "Gerada a partir de: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "Abrir uma nota para revisar", diff --git a/src/lang/locale/ru.ts b/src/lang/locale/ru.ts index 6a05f222..58e52107 100644 --- a/src/lang/locale/ru.ts +++ b/src/lang/locale/ru.ts @@ -30,6 +30,9 @@ export default { CURRENT_EASE_HELP_TEXT: "Текущий прогресс: ", CURRENT_INTERVAL_HELP_TEXT: "Текущий интервал: ", CARD_GENERATED_FROM: "Сгенерированно из: ${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "Открыть заметку для изучения", diff --git a/src/lang/locale/zh-cn.ts b/src/lang/locale/zh-cn.ts index d34d01ca..820ef774 100644 --- a/src/lang/locale/zh-cn.ts +++ b/src/lang/locale/zh-cn.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "目前掌握程度:", CURRENT_INTERVAL_HELP_TEXT: "目前间隔:", CARD_GENERATED_FROM: "生成自:${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "打开一个笔记开始复习", diff --git a/src/lang/locale/zh-tw.ts b/src/lang/locale/zh-tw.ts index 6b2dd287..5dc2646f 100644 --- a/src/lang/locale/zh-tw.ts +++ b/src/lang/locale/zh-tw.ts @@ -21,6 +21,9 @@ export default { CURRENT_EASE_HELP_TEXT: "目前掌握程度:", CURRENT_INTERVAL_HELP_TEXT: "目前間隔時間:", CARD_GENERATED_FROM: "生成自:${notePath}", + CARD_LENGTH_MISMATCH_NOTICE: + "Unable to update flashcard. The number of cards after the edit does not match the original number of cards.", + CARD_FRONT_BACK_MISSING_NOTICE: "Unable to update flashcard. The front or back is missing.", // main.ts OPEN_NOTE_FOR_REVIEW: "打開一個筆記開始復習",