Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: extended card title #1027

Merged
merged 10 commits into from
Sep 23, 2024
4 changes: 4 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. Dates are d

Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

[Unreleased]

- Extended card title functionality partly as described in issue [`#851`](https://github.com/st3v3nmw/obsidian-spaced-repetition/issues/851)

#### [1.12.5](https://github.com/st3v3nmw/obsidian-spaced-repetition/compare/1.12.4...1.12.5)

- Support RTL flashcards specified by frontmatter "direction" attribute [`#935`](https://github.com/st3v3nmw/obsidian-spaced-repetition/pull/935)
Expand Down
8 changes: 4 additions & 4 deletions src/gui/FlashcardModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ export class FlashcardModal extends Modal {
}

onClose(): void {
this.mode = FlashcardModalMode.Closed;
this.deckView.close();
this.flashcardView.close();
this.mode = FlashcardModalMode.Closed;
}

private _showDecksList(): void {
Expand All @@ -96,9 +96,9 @@ export class FlashcardModal extends Modal {
this.deckView.hide();
}

private _showFlashcard(): void {
private _showFlashcard(deck: Deck): void {
this._hideDecksList();
this.flashcardView.show();
this.flashcardView.show(deck);
}

private _hideFlashcard(): void {
Expand All @@ -108,7 +108,7 @@ export class FlashcardModal extends Modal {
private _startReviewOfDeck(deck: Deck) {
this.reviewSequencer.setCurrentDeck(deck.getTopicPath());
if (this.reviewSequencer.hasCurrentCard) {
this._showFlashcard();
this._showFlashcard(deck);
} else {
this._showDecksList();
}
Expand Down
138 changes: 98 additions & 40 deletions src/gui/FlashcardReviewView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ export class FlashcardReviewView {
public view: HTMLDivElement;

public header: HTMLDivElement;
public titleWrapper: HTMLDivElement;
public title: HTMLDivElement;
public subTitle: HTMLDivElement;
public backButton: HTMLDivElement;

public controls: HTMLDivElement;
Expand All @@ -45,6 +47,7 @@ export class FlashcardReviewView {
public easyButton: HTMLButtonElement;
public answerButton: HTMLButtonElement;

private chosenDeck: Deck | null;
private reviewSequencer: IFlashcardReviewSequencer;
private settings: SRSettings;
private reviewMode: FlashcardReviewMode;
Expand Down Expand Up @@ -72,6 +75,7 @@ export class FlashcardReviewView {
this.editClickHandler = editClickHandler;
this.modalContentEl = contentEl;
this.modalEl = modalEl;
this.chosenDeck = null;

// Build ui
this.init();
Expand All @@ -81,17 +85,23 @@ export class FlashcardReviewView {
* Initializes all static elements in the FlashcardView
*/
init() {
this._createBackButton();

this.view = this.modalContentEl.createDiv();
this.view.addClasses(["sr-flashcard", "sr-is-hidden"]);

this.header = this.view.createDiv();
this.header.addClass("sr-header");

this._createBackButton();
this.titleWrapper = this.header.createDiv();
this.titleWrapper.addClass("sr-title-wrapper");

this.title = this.header.createDiv();
this.title = this.titleWrapper.createDiv();
this.title.addClass("sr-title");

this.subTitle = this.titleWrapper.createDiv();
this.subTitle.addClasses(["sr-sub-title", "sr-is-hidden"]);

this.controls = this.header.createDiv();
this.controls.addClass("sr-controls");

Expand All @@ -112,14 +122,60 @@ export class FlashcardReviewView {
}

/**
* Shows the FlashcardView & rerenders all dynamic elements
* Shows the FlashcardView if it is hidden
*/
async show(chosenDeck: Deck) {
if (!this.view.hasClass("sr-is-hidden")) {
return;
}
this.chosenDeck = chosenDeck;

await this._drawContent();

// Prevents the following code, from running if this show is just a redraw and not an unhide
this.view.removeClass("sr-is-hidden");
this.backButton.removeClass("sr-is-hidden");
document.addEventListener("keydown", this._keydownHandler);
}

/**
* Refreshes all dynamic elements
*/
async refresh() {
await this._drawContent();
}

/**
* Hides the FlashcardView if it is visible
*/
async show() {
hide() {
// Prevents the following code, from running if this was executed multiple times after one another
if (this.view.hasClass("sr-is-hidden")) {
return;
}

document.removeEventListener("keydown", this._keydownHandler);
this.view.addClass("sr-is-hidden");
this.backButton.addClass("sr-is-hidden");
}

/**
* Closes the FlashcardView
*/
close() {
this.hide();
document.removeEventListener("keydown", this._keydownHandler);
}

// #region -> Functions & helpers

private async _drawContent() {
this.mode = FlashcardModalMode.Front;
const deck: Deck = this.reviewSequencer.currentDeck;
const currentDeck: Deck = this.reviewSequencer.currentDeck;

// Setup title
this._setTitle(deck);
this._setTitle(this.chosenDeck);
this._setSubTitle(this.chosenDeck, currentDeck);
this.resetButton.disabled = true;

// Setup context
Expand All @@ -146,39 +202,8 @@ export class FlashcardReviewView {

// Setup response buttons
this._resetResponseButtons();

// Prevents the following code, from running if this show is just a redraw and not an unhide
if (!this.view.hasClass("sr-is-hidden")) {
return;
}
this.view.removeClass("sr-is-hidden");
this.backButton.removeClass("sr-is-hidden");
document.addEventListener("keydown", this._keydownHandler);
}

/**
* Hides the FlashcardView
*/
hide() {
// Prevents the following code, from running if this was executed multiple times after one another
if (this.view.hasClass("sr-is-hidden")) {
return;
}
this.view.addClass("sr-is-hidden");
this.backButton.addClass("sr-is-hidden");
document.removeEventListener("keydown", this._keydownHandler);
}

/**
* Closes the FlashcardView
*/
close() {
document.removeEventListener("keydown", this._keydownHandler);
this.hide();
}

// -> Functions & helpers

private _keydownHandler = (e: KeyboardEvent) => {
// Prevents any input, if the edit modal is open
if (
Expand Down Expand Up @@ -342,7 +367,7 @@ export class FlashcardReviewView {
}

private async _handleSkipCard(): Promise<void> {
if (this._currentCard != null) await this.show();
if (this._currentCard != null) await this.refresh();
else this.backClickHandler();
}

Expand Down Expand Up @@ -371,13 +396,46 @@ export class FlashcardReviewView {
setIcon(this.backButton, "arrow-left");
this.backButton.setAttribute("aria-label", t("BACK"));
this.backButton.addEventListener("click", () => {
/* this.plugin.data.historyDeck = ""; */
this.backClickHandler();
});
}

private _setTitle(deck: Deck) {
this.title.setText(`${deck.deckName}: ${deck.getCardCount(CardListType.All, true)}`);
let text = deck.deckName;

const deckStats = this.reviewSequencer.getDeckStats(deck.getTopicPath());
const cardsInQueue = deckStats.dueCount + deckStats.newCount;
text += `: ${cardsInQueue}`;

this.title.setText(text);
}

private _setSubTitle(chosenDeck: Deck, currentDeck: Deck) {
if (chosenDeck.subdecks.length === 0) {
if (!this.subTitle.hasClass("sr-is-hidden")) {
this.subTitle.addClass("sr-is-hidden");
}
return;
}

if (this.subTitle.hasClass("sr-is-hidden")) {
this.subTitle.removeClass("sr-is-hidden");
}

let text = `${currentDeck.deckName}`;

const isRandomMode = this.settings.flashcardCardOrder === "EveryCardRandomDeckAndCard";
if (!isRandomMode) {
const subDecksWithCardsInQueue = chosenDeck.subdecks.filter((subDeck) => {
const deckStats = this.reviewSequencer.getDeckStats(subDeck.getTopicPath());
return deckStats.dueCount + deckStats.newCount > 0;
});

text = `${t("DECKS")}: ${subDecksWithCardsInQueue.length} | ${text}`;
text += `: ${currentDeck.getCardCount(CardListType.All, false)}`;
}

this.subTitle.setText(text);
}

// -> Controls
Expand Down
22 changes: 15 additions & 7 deletions styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ body:not(.native-scrollbars) #sr-modal .modal-close-button {
line-height: var(--line-height-tight);
}

.sr-sub-title {
font-size: var(--font-ui-medium);
text-align: center;
line-height: var(--line-height-tight);
color: var(--text-muted);
}

.sr-content {
overflow-y: auto;
}
Expand Down Expand Up @@ -230,15 +237,16 @@ body:not(.native-scrollbars) #sr-modal .modal-close-button {
padding-bottom: 8px;
}

.sr-flashcard .sr-button:disabled {
cursor: not-allowed;
.sr-flashcard .sr-title-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 4px;
}

.sr-flashcard .sr-back-button {
position: absolute;
left: 0;
top: 0;
z-index: 21;
.sr-flashcard .sr-button:disabled {
cursor: not-allowed;
}

.sr-flashcard .sr-controls {
Expand Down
Loading