Enhance speech input handling in VocabLessonView: Introduce fallback instructions and placeholders for unsupported speech recognition in English, German, and Spanish. Update exercise instructions to dynamically display fallback options, improving user experience for speech-related exercises.
This commit is contained in:
@@ -437,6 +437,8 @@
|
|||||||
"recordingError": "Aufnahme-Fehler",
|
"recordingError": "Aufnahme-Fehler",
|
||||||
"recognizedText": "Erkannter Text",
|
"recognizedText": "Erkannter Text",
|
||||||
"speechRecognitionNotSupported": "Speech Recognition wird von diesem Browser nicht unterstützt. Bitte verwende Chrome oder Edge.",
|
"speechRecognitionNotSupported": "Speech Recognition wird von diesem Browser nicht unterstützt. Bitte verwende Chrome oder Edge.",
|
||||||
|
"speakingFallbackInstruction": "Dein Browser unterstützt hier keine Spracheingabe. Schreibe deine gesprochene Antwort stattdessen als Text auf und prüfe sie dann normal.",
|
||||||
|
"speakingFallbackPlaceholder": "Schreibe hier, was du sagen würdest ...",
|
||||||
"keywords": "Schlüsselwörter",
|
"keywords": "Schlüsselwörter",
|
||||||
"switchBackToMultipleChoice": "Zurück zu Multiple Choice",
|
"switchBackToMultipleChoice": "Zurück zu Multiple Choice",
|
||||||
"languageAssistantEyebrow": "Sprachassistent",
|
"languageAssistantEyebrow": "Sprachassistent",
|
||||||
|
|||||||
@@ -437,6 +437,8 @@
|
|||||||
"recordingError": "Recording error",
|
"recordingError": "Recording error",
|
||||||
"recognizedText": "Recognized Text",
|
"recognizedText": "Recognized Text",
|
||||||
"speechRecognitionNotSupported": "Speech Recognition is not supported by this browser. Please use Chrome or Edge.",
|
"speechRecognitionNotSupported": "Speech Recognition is not supported by this browser. Please use Chrome or Edge.",
|
||||||
|
"speakingFallbackInstruction": "Your browser does not support speech input here. Write down what you would say instead and check it normally.",
|
||||||
|
"speakingFallbackPlaceholder": "Write what you would say here ...",
|
||||||
"keywords": "Keywords",
|
"keywords": "Keywords",
|
||||||
"switchBackToMultipleChoice": "Switch back to Multiple Choice",
|
"switchBackToMultipleChoice": "Switch back to Multiple Choice",
|
||||||
"languageAssistantEyebrow": "Language assistant",
|
"languageAssistantEyebrow": "Language assistant",
|
||||||
|
|||||||
@@ -434,6 +434,8 @@
|
|||||||
"recordingError": "Error de grabación",
|
"recordingError": "Error de grabación",
|
||||||
"recognizedText": "Texto reconocido",
|
"recognizedText": "Texto reconocido",
|
||||||
"speechRecognitionNotSupported": "El reconocimiento de voz no es compatible con este navegador. Usa Chrome o Edge.",
|
"speechRecognitionNotSupported": "El reconocimiento de voz no es compatible con este navegador. Usa Chrome o Edge.",
|
||||||
|
"speakingFallbackInstruction": "Tu navegador no admite entrada de voz aquí. Escribe en su lugar lo que dirías y compruébalo normalmente.",
|
||||||
|
"speakingFallbackPlaceholder": "Escribe aquí lo que dirías ...",
|
||||||
"keywords": "Palabras clave",
|
"keywords": "Palabras clave",
|
||||||
"switchBackToMultipleChoice": "Volver a opción múltiple",
|
"switchBackToMultipleChoice": "Volver a opción múltiple",
|
||||||
"languageAssistantEyebrow": "Asistente de idiomas",
|
"languageAssistantEyebrow": "Asistente de idiomas",
|
||||||
|
|||||||
@@ -478,8 +478,10 @@
|
|||||||
<!-- Reading Aloud Übung -->
|
<!-- Reading Aloud Übung -->
|
||||||
<div v-else-if="getExerciseType(exercise) === 'reading_aloud'" class="reading-aloud-exercise">
|
<div v-else-if="getExerciseType(exercise) === 'reading_aloud'" class="reading-aloud-exercise">
|
||||||
<p class="exercise-question">{{ getQuestionText(exercise) }}</p>
|
<p class="exercise-question">{{ getQuestionText(exercise) }}</p>
|
||||||
<p class="exercise-instruction">{{ $t('socialnetwork.vocab.courses.readingAloudInstruction') }}</p>
|
<p class="exercise-instruction">
|
||||||
<div class="reading-aloud-controls">
|
{{ isSpeechRecognitionSupported ? $t('socialnetwork.vocab.courses.readingAloudInstruction') : $t('socialnetwork.vocab.courses.speakingFallbackInstruction') }}
|
||||||
|
</p>
|
||||||
|
<div v-if="isSpeechRecognitionSupported" class="reading-aloud-controls">
|
||||||
<button
|
<button
|
||||||
v-if="!isRecording(exercise.id)"
|
v-if="!isRecording(exercise.id)"
|
||||||
@click="startReadingAloud(exercise.id)"
|
@click="startReadingAloud(exercise.id)"
|
||||||
@@ -496,6 +498,13 @@
|
|||||||
{{ $t('socialnetwork.vocab.courses.stopRecording') }}
|
{{ $t('socialnetwork.vocab.courses.stopRecording') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="speech-fallback">
|
||||||
|
<textarea
|
||||||
|
v-model="exerciseAnswers[exercise.id]"
|
||||||
|
:placeholder="$t('socialnetwork.vocab.courses.speakingFallbackPlaceholder')"
|
||||||
|
class="response-textarea"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div v-if="recordingStatus[exercise.id]" class="recording-status" :class="{ 'recording': isRecording(exercise.id) }">
|
<div v-if="recordingStatus[exercise.id]" class="recording-status" :class="{ 'recording': isRecording(exercise.id) }">
|
||||||
<span v-if="isRecording(exercise.id)">{{ $t('socialnetwork.vocab.courses.recording') }}...</span>
|
<span v-if="isRecording(exercise.id)">{{ $t('socialnetwork.vocab.courses.recording') }}...</span>
|
||||||
<span v-else>{{ recordingStatus[exercise.id] }}</span>
|
<span v-else>{{ recordingStatus[exercise.id] }}</span>
|
||||||
@@ -505,7 +514,7 @@
|
|||||||
<p>{{ recognizedText[exercise.id] }}</p>
|
<p>{{ recognizedText[exercise.id] }}</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
v-if="recognizedText[exercise.id] && !isRecording(exercise.id)"
|
v-if="(recognizedText[exercise.id] && !isRecording(exercise.id)) || (!isSpeechRecognitionSupported && exerciseAnswers[exercise.id])"
|
||||||
@click="checkAnswer(exercise.id)"
|
@click="checkAnswer(exercise.id)"
|
||||||
class="btn-check"
|
class="btn-check"
|
||||||
>
|
>
|
||||||
@@ -526,12 +535,14 @@
|
|||||||
<!-- Speaking From Memory Übung -->
|
<!-- Speaking From Memory Übung -->
|
||||||
<div v-else-if="getExerciseType(exercise) === 'speaking_from_memory'" class="speaking-from-memory-exercise">
|
<div v-else-if="getExerciseType(exercise) === 'speaking_from_memory'" class="speaking-from-memory-exercise">
|
||||||
<p class="exercise-question">{{ getQuestionText(exercise) }}</p>
|
<p class="exercise-question">{{ getQuestionText(exercise) }}</p>
|
||||||
<p class="exercise-instruction">{{ $t('socialnetwork.vocab.courses.speakingFromMemoryInstruction') }}</p>
|
<p class="exercise-instruction">
|
||||||
|
{{ isSpeechRecognitionSupported ? $t('socialnetwork.vocab.courses.speakingFromMemoryInstruction') : $t('socialnetwork.vocab.courses.speakingFallbackInstruction') }}
|
||||||
|
</p>
|
||||||
<div v-if="getQuestionData(exercise)?.keywords" class="keywords-hint">
|
<div v-if="getQuestionData(exercise)?.keywords" class="keywords-hint">
|
||||||
<strong>{{ $t('socialnetwork.vocab.courses.keywords') }}:</strong>
|
<strong>{{ $t('socialnetwork.vocab.courses.keywords') }}:</strong>
|
||||||
<span v-for="(keyword, idx) in getQuestionData(exercise).keywords" :key="idx" class="keyword-tag">{{ keyword }}</span>
|
<span v-for="(keyword, idx) in getQuestionData(exercise).keywords" :key="idx" class="keyword-tag">{{ keyword }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="speaking-controls">
|
<div v-if="isSpeechRecognitionSupported" class="speaking-controls">
|
||||||
<button
|
<button
|
||||||
v-if="!isRecording(exercise.id)"
|
v-if="!isRecording(exercise.id)"
|
||||||
@click="startSpeakingFromMemory(exercise.id)"
|
@click="startSpeakingFromMemory(exercise.id)"
|
||||||
@@ -548,6 +559,13 @@
|
|||||||
{{ $t('socialnetwork.vocab.courses.stopRecording') }}
|
{{ $t('socialnetwork.vocab.courses.stopRecording') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="speech-fallback">
|
||||||
|
<textarea
|
||||||
|
v-model="exerciseAnswers[exercise.id]"
|
||||||
|
:placeholder="$t('socialnetwork.vocab.courses.speakingFallbackPlaceholder')"
|
||||||
|
class="response-textarea"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div v-if="recordingStatus[exercise.id]" class="recording-status" :class="{ 'recording': isRecording(exercise.id) }">
|
<div v-if="recordingStatus[exercise.id]" class="recording-status" :class="{ 'recording': isRecording(exercise.id) }">
|
||||||
<span v-if="isRecording(exercise.id)">{{ $t('socialnetwork.vocab.courses.recording') }}...</span>
|
<span v-if="isRecording(exercise.id)">{{ $t('socialnetwork.vocab.courses.recording') }}...</span>
|
||||||
<span v-else>{{ recordingStatus[exercise.id] }}</span>
|
<span v-else>{{ recordingStatus[exercise.id] }}</span>
|
||||||
@@ -557,7 +575,7 @@
|
|||||||
<p>{{ recognizedText[exercise.id] }}</p>
|
<p>{{ recognizedText[exercise.id] }}</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
v-if="recognizedText[exercise.id] && !isRecording(exercise.id)"
|
v-if="(recognizedText[exercise.id] && !isRecording(exercise.id)) || (!isSpeechRecognitionSupported && exerciseAnswers[exercise.id])"
|
||||||
@click="checkAnswer(exercise.id)"
|
@click="checkAnswer(exercise.id)"
|
||||||
class="btn-check"
|
class="btn-check"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user