Tageswiederholung verbessert
This commit is contained in:
@@ -180,7 +180,7 @@ export default {
|
||||
|
||||
// SRS session (Langzeitgedächtnis) progress & persistence
|
||||
// Stored per day and course so the user can close/reopen without starting over.
|
||||
srsSession: null, // { version, dateKey, courseId, initialTotalDue, initialDueIds, doneIds, correctCount, wrongCount }
|
||||
srsSession: null, // { version, dateKey, courseId, initialTotalDue, initialDueIds, doneIds, retryPendingIds, finalReviewIds, correctCount, wrongCount }
|
||||
srsQueueIds: [], // remaining due ids for this session, in due order
|
||||
srsServerTotalDue: null,
|
||||
|
||||
@@ -545,6 +545,8 @@ export default {
|
||||
initialTotalDue: initialTotal,
|
||||
initialDueIds: dueIds.slice(0, initialTotal),
|
||||
doneIds: [],
|
||||
retryPendingIds: [],
|
||||
finalReviewIds: [],
|
||||
correctCount: 0,
|
||||
wrongCount: 0,
|
||||
};
|
||||
@@ -566,7 +568,13 @@ export default {
|
||||
}
|
||||
|
||||
const doneSet = new Set(Array.isArray(this.srsSession.doneIds) ? this.srsSession.doneIds : []);
|
||||
this.srsQueueIds = dueIds.filter((id) => !doneSet.has(id));
|
||||
const finalReviewIds = Array.isArray(this.srsSession.finalReviewIds) ? this.srsSession.finalReviewIds : [];
|
||||
const finalReviewSet = new Set(finalReviewIds);
|
||||
const availableIds = new Set(dueIds);
|
||||
this.srsQueueIds = [
|
||||
...dueIds.filter((id) => !doneSet.has(id) && !finalReviewSet.has(id)),
|
||||
...finalReviewIds.filter((id) => !doneSet.has(id) && availableIds.has(id))
|
||||
];
|
||||
// Fallback: if SRS mode but queue is empty (e.g. mismatch between stored session and current pool), fall back to pool order
|
||||
if (this.srsMode && Array.isArray(this.srsQueueIds) && this.srsQueueIds.length === 0) {
|
||||
const fallbackIds = (this.pool || []).map((it) => it.id).filter(Boolean);
|
||||
@@ -574,7 +582,7 @@ export default {
|
||||
const limited = fallbackIds.slice(0, MAX_DAILY_DUE);
|
||||
this.srsQueueIds = limited;
|
||||
// keep initialTotalDue stable if possible
|
||||
if (!this.srsSession) this.srsSession = { version: SRS_SESSION_STORAGE_VERSION, dateKey: this.getLocalDateKey(), courseId: this.openParams.courseId, initialTotalDue: limited.length, initialDueIds: limited, doneIds: [], correctCount: 0, wrongCount: 0 };
|
||||
if (!this.srsSession) this.srsSession = { version: SRS_SESSION_STORAGE_VERSION, dateKey: this.getLocalDateKey(), courseId: this.openParams.courseId, initialTotalDue: limited.length, initialDueIds: limited, doneIds: [], retryPendingIds: [], finalReviewIds: [], correctCount: 0, wrongCount: 0 };
|
||||
}
|
||||
}
|
||||
this.saveSrsSession();
|
||||
@@ -1259,12 +1267,20 @@ export default {
|
||||
if (!this.srsMode || !this.answered || this.locked) {
|
||||
return;
|
||||
}
|
||||
this.locked = true;
|
||||
await this.reportSrsReview(this.lastCorrect, rating);
|
||||
|
||||
const id = this.current?.id;
|
||||
const treatAsAgain = rating === 'again' || !this.lastCorrect;
|
||||
const moveToHardPractice = treatAsAgain && this.isItemMarkedHard(this.current);
|
||||
const retryPendingIds = Array.isArray(this.srsSession?.retryPendingIds)
|
||||
? this.srsSession.retryPendingIds
|
||||
: [];
|
||||
const needsFinalRepeat = this.lastCorrect && retryPendingIds.includes(id);
|
||||
|
||||
this.locked = true;
|
||||
// The immediate correction after a wrong answer is a rehearsal, not the
|
||||
// SRS result. Only the later repetition at the end is recorded as right.
|
||||
if (!needsFinalRepeat) {
|
||||
await this.reportSrsReview(this.lastCorrect, rating);
|
||||
}
|
||||
|
||||
if (id && this.srsSession) {
|
||||
if (treatAsAgain && !moveToHardPractice) {
|
||||
@@ -1273,6 +1289,24 @@ export default {
|
||||
if (Array.isArray(this.srsSession.doneIds)) {
|
||||
this.srsSession.doneIds = this.srsSession.doneIds.filter((x) => x !== id);
|
||||
}
|
||||
if (!retryPendingIds.includes(id)) {
|
||||
this.srsSession.retryPendingIds = [...retryPendingIds, id];
|
||||
}
|
||||
} else if (needsFinalRepeat) {
|
||||
// The correction was right, but the item must be recalled once more
|
||||
// after the rest of today's cards before it counts as complete.
|
||||
this.srsSession.retryPendingIds = retryPendingIds.filter((x) => x !== id);
|
||||
const finalReviewIds = Array.isArray(this.srsSession.finalReviewIds)
|
||||
? this.srsSession.finalReviewIds
|
||||
: [];
|
||||
if (!finalReviewIds.includes(id)) {
|
||||
this.srsSession.finalReviewIds = [...finalReviewIds, id];
|
||||
}
|
||||
const remaining = Array.isArray(this.srsQueueIds)
|
||||
? this.srsQueueIds.filter((x) => x !== id)
|
||||
: [];
|
||||
remaining.push(id);
|
||||
this.srsQueueIds = remaining;
|
||||
} else {
|
||||
// Hard cards leave the daily review after a wrong answer. They are
|
||||
// practiced separately through the hard-vocab drill.
|
||||
@@ -1281,6 +1315,10 @@ export default {
|
||||
done.push(id);
|
||||
this.srsSession.doneIds = done;
|
||||
}
|
||||
this.srsSession.retryPendingIds = retryPendingIds.filter((x) => x !== id);
|
||||
this.srsSession.finalReviewIds = (Array.isArray(this.srsSession.finalReviewIds)
|
||||
? this.srsSession.finalReviewIds
|
||||
: []).filter((x) => x !== id);
|
||||
if (Array.isArray(this.srsQueueIds) && this.srsQueueIds[0] === id) {
|
||||
this.srsQueueIds = this.srsQueueIds.slice(1);
|
||||
} else if (Array.isArray(this.srsQueueIds)) {
|
||||
|
||||
Reference in New Issue
Block a user