feat(bisaya-course): expand lesson didactics with new topics and detailed grammar focus
All checks were successful
Deploy to production / deploy (push) Successful in 2m59s

- Added new lesson topics including 'Überlebenssätze - Teil 1', 'Familien-Gespräche', 'Gefühle & Zuneigung', and 'Überlebenssätze - Teil 2' to enhance the curriculum.
- Updated existing lessons with more detailed learning goals, core patterns, grammar focus, speaking prompts, and practical tasks to improve learner engagement and comprehension.
- Refactored core patterns to include glosses for better understanding of vocabulary context.
- Enhanced the structure of lesson didactics to provide a more comprehensive learning experience for users.
This commit is contained in:
Torsten Schulz (local)
2026-04-01 14:30:31 +02:00
parent 09015b4244
commit 0421b2bc00
4 changed files with 534 additions and 33 deletions

View File

@@ -2385,6 +2385,7 @@ export default {
return this.vocabTrainerStats[key];
},
normalizeRepeatQueue(queue = []) {
const repeatIntervals = this.getRepeatIntervals();
if (!Array.isArray(queue)) {
return [];
}
@@ -2392,37 +2393,56 @@ export default {
.map((entry) => ({
key: String(entry?.key || '').trim(),
dueAfter: Math.max(0, Number(entry?.dueAfter) || 0),
stageIndex: Math.max(0, Math.min(VOCAB_REPEAT_INTERVALS.length - 1, Number(entry?.stageIndex) || 0))
stageIndex: Math.max(0, Math.min(repeatIntervals.length - 1, Number(entry?.stageIndex) || 0))
}))
.filter((entry) => entry.key);
},
getRepeatIntervals() {
const availableCount = new Set(
[...this.trainableLessonVocab, ...this.vocabTrainerMixedPool].map((vocab) => this.getVocabKey(vocab))
).size;
const maxSpacing = Math.max(1, Math.min(4, availableCount - 1));
if (maxSpacing <= 1) {
return [1, 1, 1];
}
if (maxSpacing === 2) {
return [1, 1, 2];
}
if (maxSpacing === 3) {
return [1, 2, 3];
}
return VOCAB_REPEAT_INTERVALS;
},
queueFailedVocab(vocab) {
const repeatIntervals = this.getRepeatIntervals();
const key = this.getVocabKey(vocab);
const existing = this.vocabTrainerRepeatQueue.find((entry) => entry.key === key);
if (existing) {
existing.dueAfter = VOCAB_REPEAT_INTERVALS[0];
existing.dueAfter = repeatIntervals[0];
existing.stageIndex = 0;
return;
}
this.vocabTrainerRepeatQueue.push({
key,
dueAfter: VOCAB_REPEAT_INTERVALS[0],
dueAfter: repeatIntervals[0],
stageIndex: 0
});
},
resolveRepeatedVocab(vocab) {
const repeatIntervals = this.getRepeatIntervals();
const key = this.getVocabKey(vocab);
const entryIndex = this.vocabTrainerRepeatQueue.findIndex((entry) => entry.key === key && entry.dueAfter <= 0);
if (entryIndex === -1) {
return;
}
const entry = this.vocabTrainerRepeatQueue[entryIndex];
if (entry.stageIndex >= VOCAB_REPEAT_INTERVALS.length - 1) {
if (entry.stageIndex >= repeatIntervals.length - 1) {
this.vocabTrainerRepeatQueue.splice(entryIndex, 1);
return;
}
entry.stageIndex += 1;
entry.dueAfter = VOCAB_REPEAT_INTERVALS[entry.stageIndex];
entry.dueAfter = repeatIntervals[entry.stageIndex];
},
advanceRepeatQueue(completedKey = '') {
this.vocabTrainerRepeatQueue = this.vocabTrainerRepeatQueue