ui(tts): Ton-Presets — Schnell (piper), Hohe Qualität (chatterbox), Cloud (openrouter) zurück

- Vorlesen-Presets wieder nach Tempo/Qualität benannt: 📱 Im Gerät ·  Schnell ·
   Hohe Qualität · ☁ Cloud. Cloud (OpenRouter) wieder als sichtbarer Knopf.
- syncPresetUI: exakte Markierung (openrouter hat eigenen Knopf, kein Sonderfall mehr).
- Doku §5.1.2 angepasst.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-21 01:10:51 +02:00
commit 7d30fe9e7c
3 changed files with 15 additions and 9 deletions

View file

@ -800,7 +800,7 @@ https://va.beispiel.de/ ← remote über Reverse-Proxy (alles, inkl. Mikr
| Element | Funktion |
|---------|----------|
| **Vorlesen** | Wie wird die Antwort vorgelesen? `📱 Im Gerät` = das Handy liest selbst vor (kein Server-Audio → spart Daten) · `☁ Server` = piper (lokal, zuverlässig) · `✨ Beste Qualität` = chatterbox (natürliche Stimme). „Im Gerät" erscheint nur, wo der Browser es unterstützt. |
| **Vorlesen** | Wie wird die Antwort vorgelesen? `📱 Im Gerät` = das Handy liest selbst vor (kein Server-Audio → spart Daten; fällt auf Server zurück, wenn der Browser keine Stimmen hat) · `⚡ Schnell` = piper (lokal) · `✨ Hohe Qualität` = chatterbox (natürliche Stimme) · `☁ Cloud` = OpenRouter (Internet nötig). „Im Gerät" erscheint nur, wo der Browser es unterstützt. |
| **✎ Neues Gespräch** | Frische Sitzung (Verlauf zurücksetzen) |
| **🌙 Tag-/Nachtmodus** | Heller/dunkler Modus; folgt sonst dem Betriebssystem |
| **Konto** | „Angemeldet als …", **⚙ Admin** (nur Admins → § 7.5), **Abmelden** |

View file

@ -164,8 +164,7 @@ function applyPlaybackChoice(serverProvider) {
function syncPresetUI() {
const val = ttsSel ? ttsSel.value : "";
document.querySelectorAll(".tts-preset").forEach((btn) => {
const active = btn.dataset.tts === val ||
(val === "openrouter" && btn.dataset.tts === "chatterbox"); // Cloud -> "Beste Qualität"
const active = btn.dataset.tts === val;
btn.classList.toggle("ring-2", active);
btn.classList.toggle("ring-blue-500", active);
btn.classList.toggle("border-blue-500", active);

View file

@ -260,16 +260,23 @@
</button>
<button type="button" data-tts="piper"
class="tts-preset w-full flex items-center gap-3 rounded-lg border border-slate-200 dark:border-slate-700 px-3 py-2 text-left hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors">
<span class="text-lg shrink-0"></span>
<span class="flex-1 min-w-0"><span class="block text-sm font-medium">Server</span>
<span class="block text-xs text-slate-500 dark:text-slate-400">Standard · zuverlässig</span></span>
<span class="text-lg shrink-0"></span>
<span class="flex-1 min-w-0"><span class="block text-sm font-medium">Schnell</span>
<span class="block text-xs text-slate-500 dark:text-slate-400">Piper · lokal, zuverlässig</span></span>
<span class="check text-blue-600 dark:text-blue-400 font-bold opacity-0"></span>
</button>
<button type="button" data-tts="chatterbox"
class="tts-preset w-full flex items-center gap-3 rounded-lg border border-slate-200 dark:border-slate-700 px-3 py-2 text-left hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors">
<span class="text-lg shrink-0"></span>
<span class="flex-1 min-w-0"><span class="block text-sm font-medium">Beste Qualität</span>
<span class="block text-xs text-slate-500 dark:text-slate-400">Natürliche Stimme</span></span>
<span class="flex-1 min-w-0"><span class="block text-sm font-medium">Hohe Qualität</span>
<span class="block text-xs text-slate-500 dark:text-slate-400">Chatterbox · natürliche Stimme</span></span>
<span class="check text-blue-600 dark:text-blue-400 font-bold opacity-0"></span>
</button>
<button type="button" data-tts="openrouter"
class="tts-preset w-full flex items-center gap-3 rounded-lg border border-slate-200 dark:border-slate-700 px-3 py-2 text-left hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors">
<span class="text-lg shrink-0"></span>
<span class="flex-1 min-w-0"><span class="block text-sm font-medium">Cloud</span>
<span class="block text-xs text-slate-500 dark:text-slate-400">OpenRouter · benötigt Internet</span></span>
<span class="check text-blue-600 dark:text-blue-400 font-bold opacity-0"></span>
</button>
</div>
@ -318,6 +325,6 @@
<div id="status" class="w-full max-w-3xl mx-auto mt-1 min-h-[1rem] text-xs text-slate-500 dark:text-slate-400"></div>
</footer>
<script src="/app.js?v=39"></script>
<script src="/app.js?v=40"></script>
</body>
</html>