feat: verbessere initialTotalDue und begrenze tägliche Übungsanzahl auf MAX_DAILY_DUE
All checks were successful
Deploy to production / deploy (push) Successful in 1m59s

This commit is contained in:
Torsten Schulz (local)
2026-06-04 18:52:20 +02:00
parent 64cc360dbd
commit bfec885a1f
2 changed files with 18 additions and 23 deletions

View File

@@ -161,6 +161,7 @@ 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 {
name: 'VocabPracticeDialog',
@@ -514,13 +515,14 @@ export default {
}
if (!this.srsSession) {
const initialTotal = Math.min(MAX_DAILY_DUE, Number.isFinite(Number(this.srsServerTotalDue)) ? Number(this.srsServerTotalDue) : dueIds.length);
this.srsSession = {
version: SRS_SESSION_STORAGE_VERSION,
dateKey: this.getLocalDateKey(),
courseId: this.openParams.courseId,
// Prefer server-reported total due count when available (shows full-course due count)
initialTotalDue: Number.isFinite(Number(this.srsServerTotalDue)) ? Number(this.srsServerTotalDue) : dueIds.length,
initialDueIds: dueIds,
// For the user's session we cap the number practiced per day to MAX_DAILY_DUE
initialTotalDue: initialTotal,
initialDueIds: dueIds.slice(0, initialTotal),
doneIds: [],
correctCount: 0,
wrongCount: 0,
@@ -536,26 +538,22 @@ export default {
// If the stored session has an invalid initialTotalDue (e.g. 0), repair it from server/pool data.
if (this.srsSession && (!Number.isFinite(Number(this.srsSession.initialTotalDue)) || Number(this.srsSession.initialTotalDue) <= 0)) {
const repairedTotal = Number.isFinite(Number(this.srsServerTotalDue)) && Number(this.srsServerTotalDue) > 0 ? Number(this.srsServerTotalDue) : dueIds.length;
try { console.debug('[VocabPracticeDialog] repair srsSession.initialTotalDue', { before: this.srsSession.initialTotalDue, repairedTotal }); } catch (_) {}
this.srsSession.initialTotalDue = repairedTotal;
this.srsSession.initialDueIds = Array.isArray(this.srsSession.initialDueIds) && this.srsSession.initialDueIds.length ? this.srsSession.initialDueIds : dueIds;
const capped = Math.min(MAX_DAILY_DUE, repairedTotal);
this.srsSession.initialTotalDue = capped;
this.srsSession.initialDueIds = Array.isArray(this.srsSession.initialDueIds) && this.srsSession.initialDueIds.length ? this.srsSession.initialDueIds.slice(0, capped) : dueIds.slice(0, capped);
try { this.saveSrsSession(); } catch (_) {}
}
const doneSet = new Set(Array.isArray(this.srsSession.doneIds) ? this.srsSession.doneIds : []);
this.srsQueueIds = dueIds.filter((id) => !doneSet.has(id));
try {
console.debug('[VocabPracticeDialog] initSrsSessionFromPool', { courseId: this.openParams?.courseId, dueIdsLen: dueIds.length, srsQueueLen: this.srsQueueIds.length, stored: !!this.srsSession });
} catch (_) {}
// 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);
if (fallbackIds.length > 0) {
try { console.debug('[VocabPracticeDialog] initSrsSessionFromPool: srsQueueIds empty, falling back to pool ids', { fallbackLen: fallbackIds.length }); } catch (_) {}
this.srsQueueIds = fallbackIds;
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: fallbackIds.length, initialDueIds: fallbackIds, 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: [], correctCount: 0, wrongCount: 0 };
}
}
this.saveSrsSession();
@@ -595,10 +593,6 @@ export default {
document.addEventListener('keydown', this.handleKeyDown);
});
this.loadHardVocabMap();
// Expose instance for temporary debugging in browser console
try {
window.__vocabPracticeDialog = this;
} catch (_) {}
this.reloadPool();
},
close() {
@@ -747,7 +741,6 @@ export default {
});
const result = mapped.filter(Boolean);
try { console.debug('[VocabPracticeDialog] normalizePool', { inputLen, outLen: result.length, sample: result.slice(0,5) }); } catch (_) {}
return result;
} catch (e) {
console.warn('[VocabPracticeDialog] normalizePool failed', e);