feat(bisaya-course): restructure core patterns and enhance vocabulary preparation
All checks were successful
Deploy to production / deploy (push) Successful in 2m48s

- Updated core patterns in various scripts to use an object format with target phrases and glosses, improving clarity and usability for learners.
- Enhanced the VocabService to normalize core pattern entries, ensuring consistent handling of vocabulary data.
- Introduced new vocabulary preparation steps in the VocabLessonView, guiding users through active review processes before engaging with the vocabulary trainer.
- Added localization support for new vocabulary preparation hints and instructions in multiple languages, enhancing user experience across the application.
This commit is contained in:
Torsten Schulz (local)
2026-04-01 08:12:57 +02:00
parent 7e45049e94
commit 0c89c48e68
9 changed files with 312 additions and 59 deletions

View File

@@ -30,19 +30,46 @@ const GENERATED_BISAYA_DIDACTICS = {
...BISAYA_PHASE5_DIDACTICS
};
const GENERIC_DISTRACTOR_PATTERNS = Array.from(new Set(
Object.values(GENERATED_BISAYA_DIDACTICS)
.flatMap((entry) => Array.isArray(entry?.corePatterns) ? entry.corePatterns : [])
.map((pattern) => String(pattern || '').trim())
.filter(Boolean)
)).slice(0, 200);
function normalizeText(value) {
return String(value || '')
.trim()
.replace(/\s+/g, ' ');
}
function normalizeCorePatternEntry(entry) {
if (entry === null || entry === undefined || entry === '') {
return null;
}
if (typeof entry === 'object' && !Array.isArray(entry)) {
const target = normalizeText(entry.target ?? entry.ceb ?? entry.phrase ?? '');
const gloss = normalizeText(entry.gloss ?? entry.de ?? entry.translation ?? '');
if (!target) return null;
return { target, gloss };
}
const s = normalizeText(entry);
if (!s) return null;
const pipe = s.indexOf('|');
if (pipe !== -1) {
const target = normalizeText(s.slice(0, pipe));
const gloss = normalizeText(s.slice(pipe + 1));
if (!target) return null;
return { target, gloss };
}
return { target: s, gloss: '' };
}
function corePatternTarget(entry) {
const n = normalizeCorePatternEntry(entry);
return n ? n.target : '';
}
const GENERIC_DISTRACTOR_PATTERNS = Array.from(new Set(
Object.values(GENERATED_BISAYA_DIDACTICS)
.flatMap((entry) => Array.isArray(entry?.corePatterns) ? entry.corePatterns : [])
.map((pattern) => corePatternTarget(pattern))
.filter(Boolean)
)).slice(0, 200);
function simpleHash(value) {
return Array.from(String(value || '')).reduce((sum, char) => sum + char.charCodeAt(0), 0);
}
@@ -63,7 +90,9 @@ function getLessonDidactics(lesson) {
return {
learningGoals,
corePatterns: corePatterns.map((entry) => normalizeText(entry)).filter(Boolean),
corePatterns: corePatterns
.map((entry) => normalizeCorePatternEntry(entry))
.filter(Boolean),
grammarFocus,
speakingPrompts,
practicalTasks
@@ -323,10 +352,10 @@ function generateExercisesFromDidactics(lesson) {
return [];
}
const patternA = corePatterns[0];
const patternB = corePatterns[1] || corePatterns[0];
const patternA = corePatternTarget(corePatterns[0]);
const patternB = corePatternTarget(corePatterns[1] || corePatterns[0]);
const lessonPool = Array.from(new Set([
...corePatterns,
...corePatterns.map((p) => corePatternTarget(p)),
...GENERIC_DISTRACTOR_PATTERNS
]));
let generated = [];