Tageswiederholung verbessert
This commit is contained in:
@@ -180,7 +180,7 @@ export default {
|
|||||||
|
|
||||||
// SRS session (Langzeitgedächtnis) progress & persistence
|
// SRS session (Langzeitgedächtnis) progress & persistence
|
||||||
// Stored per day and course so the user can close/reopen without starting over.
|
// 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
|
srsQueueIds: [], // remaining due ids for this session, in due order
|
||||||
srsServerTotalDue: null,
|
srsServerTotalDue: null,
|
||||||
|
|
||||||
@@ -545,6 +545,8 @@ export default {
|
|||||||
initialTotalDue: initialTotal,
|
initialTotalDue: initialTotal,
|
||||||
initialDueIds: dueIds.slice(0, initialTotal),
|
initialDueIds: dueIds.slice(0, initialTotal),
|
||||||
doneIds: [],
|
doneIds: [],
|
||||||
|
retryPendingIds: [],
|
||||||
|
finalReviewIds: [],
|
||||||
correctCount: 0,
|
correctCount: 0,
|
||||||
wrongCount: 0,
|
wrongCount: 0,
|
||||||
};
|
};
|
||||||
@@ -566,7 +568,13 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const doneSet = new Set(Array.isArray(this.srsSession.doneIds) ? this.srsSession.doneIds : []);
|
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
|
// 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) {
|
if (this.srsMode && Array.isArray(this.srsQueueIds) && this.srsQueueIds.length === 0) {
|
||||||
const fallbackIds = (this.pool || []).map((it) => it.id).filter(Boolean);
|
const fallbackIds = (this.pool || []).map((it) => it.id).filter(Boolean);
|
||||||
@@ -574,7 +582,7 @@ export default {
|
|||||||
const limited = fallbackIds.slice(0, MAX_DAILY_DUE);
|
const limited = fallbackIds.slice(0, MAX_DAILY_DUE);
|
||||||
this.srsQueueIds = limited;
|
this.srsQueueIds = limited;
|
||||||
// keep initialTotalDue stable if possible
|
// 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();
|
this.saveSrsSession();
|
||||||
@@ -1259,12 +1267,20 @@ export default {
|
|||||||
if (!this.srsMode || !this.answered || this.locked) {
|
if (!this.srsMode || !this.answered || this.locked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.locked = true;
|
|
||||||
await this.reportSrsReview(this.lastCorrect, rating);
|
|
||||||
|
|
||||||
const id = this.current?.id;
|
const id = this.current?.id;
|
||||||
const treatAsAgain = rating === 'again' || !this.lastCorrect;
|
const treatAsAgain = rating === 'again' || !this.lastCorrect;
|
||||||
const moveToHardPractice = treatAsAgain && this.isItemMarkedHard(this.current);
|
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 (id && this.srsSession) {
|
||||||
if (treatAsAgain && !moveToHardPractice) {
|
if (treatAsAgain && !moveToHardPractice) {
|
||||||
@@ -1273,6 +1289,24 @@ export default {
|
|||||||
if (Array.isArray(this.srsSession.doneIds)) {
|
if (Array.isArray(this.srsSession.doneIds)) {
|
||||||
this.srsSession.doneIds = this.srsSession.doneIds.filter((x) => x !== id);
|
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 {
|
} else {
|
||||||
// Hard cards leave the daily review after a wrong answer. They are
|
// Hard cards leave the daily review after a wrong answer. They are
|
||||||
// practiced separately through the hard-vocab drill.
|
// practiced separately through the hard-vocab drill.
|
||||||
@@ -1281,6 +1315,10 @@ export default {
|
|||||||
done.push(id);
|
done.push(id);
|
||||||
this.srsSession.doneIds = done;
|
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) {
|
if (Array.isArray(this.srsQueueIds) && this.srsQueueIds[0] === id) {
|
||||||
this.srsQueueIds = this.srsQueueIds.slice(1);
|
this.srsQueueIds = this.srsQueueIds.slice(1);
|
||||||
} else if (Array.isArray(this.srsQueueIds)) {
|
} else if (Array.isArray(this.srsQueueIds)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user