Enhanced handling of hard relearning
This commit is contained in:
@@ -161,7 +161,6 @@ import { normalizeComparableWithNumberWords } from '@/utils/numberAnswerVariants
|
||||
const PRACTICE_MIN_EXPOSURES = 3;
|
||||
const SRS_SESSION_STORAGE_VERSION = 2;
|
||||
const HARD_REQUIRED_CONSECUTIVE_CORRECT = 5;
|
||||
const SRS_AGAIN_REINSERT_OFFSET = 3;
|
||||
const MAX_DAILY_DUE = 50;
|
||||
|
||||
export default {
|
||||
@@ -175,6 +174,7 @@ export default {
|
||||
allVocabs: false,
|
||||
srsMode: false,
|
||||
initialPool: null,
|
||||
closeOnHardCompletion: false,
|
||||
simpleMode: false,
|
||||
pool: [],
|
||||
|
||||
@@ -450,10 +450,8 @@ export default {
|
||||
const matchingKey = this.findMatchingHardKey(this.current);
|
||||
if (!matchingKey) return;
|
||||
this.removeHardEntriesForItem(this.current);
|
||||
if (this.hardPhaseActive && this.hardRemainingCount <= 0) {
|
||||
this.hardPhaseActive = false;
|
||||
}
|
||||
this.saveHardVocabMap();
|
||||
this.maybeFinishHardPhase();
|
||||
},
|
||||
addCurrentToCycle() {
|
||||
if (!this.current?.id) return;
|
||||
@@ -467,10 +465,16 @@ export default {
|
||||
this.hardPhaseActive = true;
|
||||
},
|
||||
maybeFinishHardPhase() {
|
||||
if (!this.hardPhaseActive) return;
|
||||
if (this.hardRemainingCount > 0) return;
|
||||
if (!this.hardPhaseActive && !this.closeOnHardCompletion) return false;
|
||||
if (this.hardRemainingCount > 0) return false;
|
||||
if (this.hardCount <= 0 && this.closeOnHardCompletion) {
|
||||
this.close();
|
||||
return true;
|
||||
}
|
||||
if (!this.hardPhaseActive) return false;
|
||||
this.hardPhaseActive = false;
|
||||
this.cycleAskedIds = [];
|
||||
return false;
|
||||
},
|
||||
getLocalDateKey() {
|
||||
const d = new Date();
|
||||
@@ -575,7 +579,7 @@ export default {
|
||||
}
|
||||
this.saveSrsSession();
|
||||
},
|
||||
open({ languageId, chapterId, lessonId, courseId, initialPool = null, srsMode = false, onClose = null }) {
|
||||
open({ languageId, chapterId, lessonId, courseId, initialPool = null, srsMode = false, closeOnHardCompletion = false, onClose = null }) {
|
||||
if (this.autoAdvanceTimer) {
|
||||
clearTimeout(this.autoAdvanceTimer);
|
||||
this.autoAdvanceTimer = null;
|
||||
@@ -588,6 +592,7 @@ export default {
|
||||
this.onClose = typeof onClose === 'function' ? onClose : null;
|
||||
this.srsMode = Boolean(srsMode);
|
||||
this.initialPool = Array.isArray(initialPool) ? initialPool : null;
|
||||
this.closeOnHardCompletion = Boolean(closeOnHardCompletion);
|
||||
this.allVocabs = false;
|
||||
this.simpleMode = false;
|
||||
this.srsSession = null;
|
||||
@@ -1231,6 +1236,9 @@ export default {
|
||||
delete next[mapKey];
|
||||
this.hardVocabMap = next;
|
||||
this.saveHardVocabMap();
|
||||
if (this.maybeFinishHardPhase()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1256,21 +1264,18 @@ export default {
|
||||
|
||||
const id = this.current?.id;
|
||||
const treatAsAgain = rating === 'again' || !this.lastCorrect;
|
||||
const moveToHardPractice = treatAsAgain && this.isItemMarkedHard(this.current);
|
||||
|
||||
if (id && this.srsSession) {
|
||||
if (treatAsAgain) {
|
||||
// Wrong answers are not done yet: requeue near the end so the user
|
||||
// sees them again before the session finishes.
|
||||
if (Array.isArray(this.srsQueueIds)) {
|
||||
const remaining = this.srsQueueIds.filter((x) => x !== id);
|
||||
const insertAt = Math.min(remaining.length, SRS_AGAIN_REINSERT_OFFSET);
|
||||
remaining.splice(insertAt, 0, id);
|
||||
this.srsQueueIds = remaining;
|
||||
}
|
||||
if (treatAsAgain && !moveToHardPractice) {
|
||||
// Keep the card at the front of the queue. After the solution has
|
||||
// been shown, the user must type it correctly before moving on.
|
||||
if (Array.isArray(this.srsSession.doneIds)) {
|
||||
this.srsSession.doneIds = this.srsSession.doneIds.filter((x) => x !== id);
|
||||
}
|
||||
} else {
|
||||
// Hard cards leave the daily review after a wrong answer. They are
|
||||
// practiced separately through the hard-vocab drill.
|
||||
const done = Array.isArray(this.srsSession.doneIds) ? this.srsSession.doneIds : [];
|
||||
if (!done.includes(id)) {
|
||||
done.push(id);
|
||||
@@ -1285,6 +1290,21 @@ export default {
|
||||
this.saveSrsSession();
|
||||
}
|
||||
|
||||
if (treatAsAgain && !moveToHardPractice) {
|
||||
const retryItem = this.pool.find((item) => item.id === id) || this.current;
|
||||
const retryDirection = this.direction;
|
||||
this.resetQuestion();
|
||||
this.current = retryItem;
|
||||
this.direction = retryDirection;
|
||||
const prompt = this.currentAnswerPrompt;
|
||||
this.acceptableAnswers = this.getAnswersForPrompt(prompt, this.direction);
|
||||
if (this.simpleMode) this.buildChoices();
|
||||
this.$nextTick(() => {
|
||||
if (!this.simpleMode) this.$refs.answerInput?.focus?.();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.next();
|
||||
},
|
||||
submitChoice(opt) {
|
||||
@@ -1338,7 +1358,7 @@ export default {
|
||||
this.addCurrentToCycle();
|
||||
}
|
||||
this.maybeStartHardPhase();
|
||||
this.maybeFinishHardPhase();
|
||||
if (this.maybeFinishHardPhase()) return;
|
||||
const retryDirection = this.pendingRetry?.direction || null;
|
||||
this.resetQuestion();
|
||||
if (retryDirection) {
|
||||
@@ -1346,7 +1366,7 @@ export default {
|
||||
}
|
||||
this.current = this.pickNextItem();
|
||||
if (!this.current) {
|
||||
this.maybeFinishHardPhase();
|
||||
if (this.maybeFinishHardPhase()) return;
|
||||
if (!this.hardPhaseActive) {
|
||||
this.current = this.pickNextItem();
|
||||
}
|
||||
|
||||
@@ -966,6 +966,7 @@ export default {
|
||||
this.$refs.practiceDialog?.open?.({
|
||||
courseId: this.courseId,
|
||||
initialPool: this.hardVocabList,
|
||||
closeOnHardCompletion: true,
|
||||
onClose: () => this.refreshHardVocabList()
|
||||
});
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user