feat(VocabLessonView): improve lesson reset behavior and normalize vocabulary handling
Some checks failed
Deploy to production / deploy (push) Has been cancelled

- Updated lesson reset functionality to ensure users start in the 'learn' tab after resetting progress.
- Enhanced vocabulary normalization by adding a method to strip trailing parenthetical notes, improving text consistency.
- Adjusted normalization logic to conditionally ignore trailing notes based on user input mode, enhancing user experience during vocabulary training.
This commit is contained in:
Torsten Schulz (local)
2026-04-17 11:41:46 +02:00
parent e96c37aac5
commit 7b907ea683

View File

@@ -1773,6 +1773,13 @@ export default {
try { try {
await apiClient.delete(`/api/vocab/lessons/${this.lessonId}/progress`); await apiClient.delete(`/api/vocab/lessons/${this.lessonId}/progress`);
this.clearLocalLessonStateCache(); this.clearLocalLessonStateCache();
// Nach dem Reset soll der Nutzer wieder im Üben-/Lernen-Tab starten.
this.activeTab = 'learn';
if (this.$route?.query?.tab && this.$route.query.tab !== 'learn') {
this.$router.replace({
query: { ...this.$route.query, tab: 'learn' }
});
}
this.$root?.$refs?.messageDialog?.open?.('tr:socialnetwork.vocab.courses.resetLessonProgressSuccess'); this.$root?.$refs?.messageDialog?.open?.('tr:socialnetwork.vocab.courses.resetLessonProgressSuccess');
await this.loadLesson(); await this.loadLesson();
} catch (e) { } catch (e) {
@@ -1913,6 +1920,9 @@ export default {
: localFallbackState; : localFallbackState;
if (!parsedState || parsedState.version !== LESSON_STATE_VERSION) { if (!parsedState || parsedState.version !== LESSON_STATE_VERSION) {
// Ohne gespeicherten Zustand soll eine Lektion immer im Üben-/Lernen-Flow starten,
// sonst bleibt z.B. der Kapitel-Prüfungs-Tab "kleben" (u.a. nach Reset).
this.activeTab = 'learn';
this.lessonStatePersistenceReady = true; this.lessonStatePersistenceReady = true;
return; return;
} }
@@ -3599,8 +3609,22 @@ export default {
.trim(); .trim();
return normalized.replace(/\s+/g, ''); return normalized.replace(/\s+/g, '');
}, },
normalizeVocab(s) { stripTrailingParentheticalNotes(value) {
return this.normalizeComparableText(s); let text = String(value || '').trim();
// Entfernt didaktische Zusätze am Ende, unabhängig vom konkreten Inhalt,
// z. B. "(...)", "[...]" oder vollbreite Klammern "...".
const trailingNoteRegex = /\s*(\([^()]*\)|\[[^\[\]]*\]|[^]*)\s*$/;
while (trailingNoteRegex.test(text)) {
text = text.replace(trailingNoteRegex, '').trim();
}
return text;
},
normalizeVocab(s, options = {}) {
const { ignoreTrailingParentheticalNotes = false } = options;
const source = ignoreTrailingParentheticalNotes
? this.stripTrailingParentheticalNotes(s)
: s;
return this.normalizeComparableText(source);
}, },
reportSrsReviewForCurrentQuestion(isCorrect) { reportSrsReviewForCurrentQuestion(isCorrect) {
if (!this.currentVocabQuestion?.vocab || !this.courseId) { if (!this.currentVocabQuestion?.vocab || !this.courseId) {
@@ -3631,9 +3655,14 @@ export default {
userAnswer = this.vocabTrainerAnswer; userAnswer = this.vocabTrainerAnswer;
} }
const normalizedUser = this.normalizeVocab(userAnswer); const useTypingNormalization = this.vocabTrainerMode === 'typing';
const normalizedUser = this.normalizeVocab(userAnswer, {
ignoreTrailingParentheticalNotes: useTypingNormalization
});
const normalizedCorrectAnswers = (this.currentVocabQuestion.answers || [this.currentVocabQuestion.answer]) const normalizedCorrectAnswers = (this.currentVocabQuestion.answers || [this.currentVocabQuestion.answer])
.map(answer => this.normalizeVocab(answer)); .map(answer => this.normalizeVocab(answer, {
ignoreTrailingParentheticalNotes: useTypingNormalization
}));
this.vocabTrainerLastCorrect = normalizedCorrectAnswers.includes(normalizedUser); this.vocabTrainerLastCorrect = normalizedCorrectAnswers.includes(normalizedUser);
// Update Stats // Update Stats