diff --git a/app/pages/classroom.vue b/app/pages/classroom.vue index 8e5800d..645be1a 100644 --- a/app/pages/classroom.vue +++ b/app/pages/classroom.vue @@ -1328,11 +1328,11 @@ mdi-alert-circle-outline
-

Sprachserver aktuell nicht erreichbar

-

Server-TTS ist gerade überlastet

+

Voice service is temporarily unavailable

+

Online voice is busy right now

- Unser Sprachserver ist aktuell wegen zu hoher Auslastung nicht erreichbar. Es kann ein bisschen dauern, - bis dieses Feature wieder verfügbar ist. Du kannst solange Browser TTS nutzen. + Our online voice server is currently under heavy load and cannot be reached. It may take a little while + until this feature is available again. You can use the voice built into your browser in the meantime.

@@ -1343,14 +1343,42 @@ @click="enableBrowserTtsFromWarning" > mdi-volume-high - Browser TTS nutzen + Use browser voice

- Dein Browser meldet aktuell keine Web-Speech-Unterstützung. + Your browser does not report built-in voice support right now. +

+ + + + +
+
+ mdi-cloud-check-outline +
+
+

Better voice available

+

Use the online voice?

+

+ You are currently using the voice built into your browser. The online voice service is available and usually + sounds clearer and more natural for ATC practice. +

+
+
+ + +
+

+ You can change this later in Settings under Browser TTS.

@@ -2744,6 +2772,7 @@ const referenceOpen = ref(false) const toast = ref({show: false, text: ''}) const showSettings = ref(false) const showSpeechServerWarning = ref(false) +const showOnlineTtsSuggestion = ref(false) const api = useApi() const isClient = typeof window !== 'undefined' const auth = useAuthStore() @@ -2812,7 +2841,9 @@ function persistLocalAtcSettings(config: LearnConfig) { async function checkSpeechServerAvailability() { try { const health = await api.get('/api/classroom/speech-server-health') + const hasOnlineTts = Boolean(health.configured && health.reachable) showSpeechServerWarning.value = Boolean(health.configured && !health.reachable) + showOnlineTtsSuggestion.value = Boolean(hasOnlineTts && cfg.value.tts) } catch (error) { console.error('Failed to check speech server availability', error) } @@ -2823,6 +2854,11 @@ function enableBrowserTtsFromWarning() { showSpeechServerWarning.value = false } +function enableOnlineTtsFromSuggestion() { + cfg.value.tts = false + showOnlineTtsSuggestion.value = false +} + function loadLocalAtcSettings(): LearnConfigPatch | null { if (!isClient) return null const key = getAtcSettingsStorageKey() @@ -6780,6 +6816,13 @@ onMounted(() => { box-shadow: 0 18px 36px rgba(245, 158, 11, .16); } +.speech-server-icon.is-online { + color: var(--accent); + background: color-mix(in srgb, var(--accent) 18%, transparent); + border-color: color-mix(in srgb, var(--accent) 36%, transparent); + box-shadow: 0 18px 36px rgba(34, 211, 238, .16); +} + .speech-server-copy { margin-top: 10px; line-height: 1.6; @@ -6796,6 +6839,18 @@ onMounted(() => { justify-content: center; } +.speech-server-actions .btn.primary:not([disabled]):hover { + color: #051217; + background: linear-gradient( + 180deg, + color-mix(in srgb, var(--accent) 98%, white 10%), + color-mix(in srgb, var(--accent2) 78%, transparent) + ); + border-color: color-mix(in srgb, var(--accent) 70%, transparent); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), + 0 16px 30px color-mix(in srgb, var(--accent) 40%, transparent); +} + .sr-only { position: absolute; width: 1px;