From 7b907ea683510ddf230d79fdd97a128ce7823b0e Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 17 Apr 2026 11:41:46 +0200 Subject: [PATCH] feat(VocabLessonView): improve lesson reset behavior and normalize vocabulary handling - 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. --- frontend/src/views/social/VocabLessonView.vue | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/frontend/src/views/social/VocabLessonView.vue b/frontend/src/views/social/VocabLessonView.vue index 1e3d5ac..63cdc41 100644 --- a/frontend/src/views/social/VocabLessonView.vue +++ b/frontend/src/views/social/VocabLessonView.vue @@ -1773,6 +1773,13 @@ export default { try { await apiClient.delete(`/api/vocab/lessons/${this.lessonId}/progress`); 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'); await this.loadLesson(); } catch (e) { @@ -1913,6 +1920,9 @@ export default { : localFallbackState; 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; return; } @@ -3599,8 +3609,22 @@ export default { .trim(); return normalized.replace(/\s+/g, ''); }, - normalizeVocab(s) { - return this.normalizeComparableText(s); + stripTrailingParentheticalNotes(value) { + 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) { if (!this.currentVocabQuestion?.vocab || !this.courseId) { @@ -3631,9 +3655,14 @@ export default { 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]) - .map(answer => this.normalizeVocab(answer)); + .map(answer => this.normalizeVocab(answer, { + ignoreTrailingParentheticalNotes: useTypingNormalization + })); this.vocabTrainerLastCorrect = normalizedCorrectAnswers.includes(normalizedUser); // Update Stats