feat(vocab-lesson): enhance exercise navigation and randomization logic
All checks were successful
Deploy to production / deploy (push) Successful in 2m57s
All checks were successful
Deploy to production / deploy (push) Successful in 2m57s
- Improved the exercise progression logic to automatically advance only on correct answers, ensuring better user feedback during learning. - Added a new method to shuffle multiple-choice options display order when distractor replacement is not applicable, enhancing the exercise experience. - Updated the build process for randomized options to include both randomization from a pool and display order shuffling, improving overall engagement and learning outcomes.
This commit is contained in:
@@ -2031,7 +2031,15 @@ export default {
|
|||||||
if (this.sequentialPanelActive) {
|
if (this.sequentialPanelActive) {
|
||||||
const list = this.scrambledChapterExamExercises;
|
const list = this.scrambledChapterExamExercises;
|
||||||
const idx = list.findIndex((e) => e.id === exerciseId);
|
const idx = list.findIndex((e) => e.id === exerciseId);
|
||||||
if (idx >= 0 && idx < list.length - 1 && this.exerciseResults[exerciseId]) {
|
const result = this.exerciseResults[exerciseId];
|
||||||
|
// Nur bei richtiger Antwort automatisch weiter: Bei Fehler bleibt die Karte sichtbar,
|
||||||
|
// damit „Falsch“ und die Musterlösung angezeigt werden; Weiter geht es per Nav-Button.
|
||||||
|
if (
|
||||||
|
idx >= 0
|
||||||
|
&& idx < list.length - 1
|
||||||
|
&& result
|
||||||
|
&& result.correct
|
||||||
|
) {
|
||||||
this.exerciseSequentialIndex = idx + 1;
|
this.exerciseSequentialIndex = idx + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2630,15 +2638,38 @@ export default {
|
|||||||
const all = this._shuffleArray([...correctTexts, ...picked]);
|
const all = this._shuffleArray([...correctTexts, ...picked]);
|
||||||
return { options: all, useTextAnswer: true };
|
return { options: all, useTextAnswer: true };
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Wenn keine Distraktor-Ersetzung läuft (z. B. answerLanguage fehlt), nur die gegebenen
|
||||||
|
* Optionen mischen. Richtige Antwort bleibt über Optionstext prüfbar (useTextAnswer).
|
||||||
|
*/
|
||||||
|
shuffleMcOptionsDisplayOrder(exercise) {
|
||||||
|
const q = this.getQuestionData(exercise);
|
||||||
|
if (!q || q.type !== 'multiple_choice' || q.randomizeDistractors === false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const options = q.options || [];
|
||||||
|
if (options.length < 2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
options: this._shuffleArray(options),
|
||||||
|
useTextAnswer: true
|
||||||
|
};
|
||||||
|
},
|
||||||
buildMcRandomizedOptions() {
|
buildMcRandomizedOptions() {
|
||||||
this.mcRandomizedOptions = {};
|
this.mcRandomizedOptions = {};
|
||||||
const exercises = this.effectiveExercises;
|
const exercises = this.effectiveExercises;
|
||||||
if (!exercises) return;
|
if (!exercises) return;
|
||||||
exercises.forEach((ex) => {
|
exercises.forEach((ex) => {
|
||||||
if (this.getExerciseType(ex) !== 'multiple_choice') return;
|
if (this.getExerciseType(ex) !== 'multiple_choice') return;
|
||||||
const built = this.randomizeMcOptionsIfPossible(ex);
|
const fromPool = this.randomizeMcOptionsIfPossible(ex);
|
||||||
if (built) {
|
if (fromPool) {
|
||||||
this.mcRandomizedOptions[ex.id] = built;
|
this.mcRandomizedOptions[ex.id] = fromPool;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const orderOnly = this.shuffleMcOptionsDisplayOrder(ex);
|
||||||
|
if (orderOnly) {
|
||||||
|
this.mcRandomizedOptions[ex.id] = orderOnly;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user