From e28ed7bdb5d9871b43e83193f600141808cfc034 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 20 Apr 2026 08:48:39 +0200 Subject: [PATCH] feat(VocabService, VocabPracticeDialog, VocabLessonView): enhance vocabulary training logic and UI feedback - Introduced methods for improved text analysis and validation in VocabService, including `_wordCount` and `_looksLikeFragmentMismatch`, to better assess learning and reference pairs. - Updated VocabPracticeDialog to display submitted answers and correct solutions, enhancing user feedback during practice sessions. - Enhanced VocabLessonView to ensure only trainable vocabulary pairs are processed, improving the quality of vocabulary training. - Added localization entries for new UI elements in both English and German, ensuring clarity in user interactions. --- backend/services/vocabService.js | 26 +++++++ .../socialnetwork/VocabPracticeDialog.vue | 75 +++++++++++++++++-- .../src/i18n/locales/de/socialnetwork.json | 2 + .../src/i18n/locales/en/socialnetwork.json | 2 + frontend/src/views/social/VocabLessonView.vue | 34 ++++++++- 5 files changed, 130 insertions(+), 9 deletions(-) diff --git a/backend/services/vocabService.js b/backend/services/vocabService.js index 8ecf39e..d67d6c4 100644 --- a/backend/services/vocabService.js +++ b/backend/services/vocabService.js @@ -92,9 +92,35 @@ export default class VocabService { return false; } + if (this._looksLikeFragmentMismatch(learning, reference)) { + return false; + } + return !this._isInstructionLikeText(learning) && !this._isInstructionLikeText(reference); } + _wordCount(value) { + return String(value || '') + .trim() + .replace(/[\p{P}\p{S}]+/gu, ' ') + .split(/\s+/) + .filter(Boolean) + .length; + } + + _looksLikeFragmentMismatch(left, right) { + const leftWords = this._wordCount(left); + const rightWords = this._wordCount(right); + const leftText = String(left || '').trim(); + const rightText = String(right || '').trim(); + const leftLooksSentence = leftWords >= 3 || /[?!.].+\S/.test(leftText); + const rightLooksSentence = rightWords >= 3 || /[?!.].+\S/.test(rightText); + const leftLooksShortFragment = leftWords <= 1 && leftText.length <= 12; + const rightLooksShortFragment = rightWords <= 1 && rightText.length <= 12; + + return (leftLooksShortFragment && rightLooksSentence) || (rightLooksShortFragment && leftLooksSentence); + } + _calculateSrsSchedule(item, { correct, rating = null } = {}) { const now = new Date(); const previousStage = Math.max(0, Number(item?.stage) || 0); diff --git a/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue b/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue index 8f563e2..694b777 100644 --- a/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue +++ b/frontend/src/dialogues/socialnetwork/VocabPracticeDialog.vue @@ -42,15 +42,20 @@
{{ $t('socialnetwork.vocab.practice.correct') }}
{{ $t('socialnetwork.vocab.practice.wrong') }} -
-
{{ $t('socialnetwork.vocab.practice.acceptable') }}
-
    -
  • {{ a }}
  • -
-
+
+ +
{{ $t('socialnetwork.vocab.practice.correctSolutions') }}
+ +
+
{{ $t('socialnetwork.vocab.practice.srsRateTitle') }}