feat: Geräte-TTS, native Stimmen, Favicon, Auth-Gate, UI-Fixes
Web-UI / TTS:
- Geräte-TTS ("📱 Gerät"): Antwort wird on-device vorgelesen (Web Speech
API), Server sendet nur Text (text_only) -> spart Bandbreite/Kosten.
Mobil-Default, geräte-lokale Speicherung, iOS-Autoplay-Freischaltung.
- Vorlese-Symbol (🔊) je Bubble: Hybrid-Replay (Assistent-PCM gecacht,
Eingabe via /api/speak); SVG-Icon mit kontrastreicher Farbe.
- Kombiniertes Sprachmenü (Flex + feste Sprachen) statt separatem Modus-Menü.
- "Neues Gespräch"-Button (frische Session gegen Sprach-Trägheit).
- Dark-Mode: lesbare <option>-Popups (Kontrast-Fix).
- Favicon (SVG + PNG-Fallbacks) aus mund.png.
TTS-Backend:
- Sprache wird an alle TTS-Provider durchgereicht; Piper-Stimme folgt der
Sprache; Chatterbox mehrsprachig + cross-lingual.
- Native Referenz-Stimmen je Sprache (config/voices/<lang>.wav, FLEURS CC-BY),
loudness-normalisiert.
LLM-Sprache:
- Antwort folgt zuverlässig der gewählten Sprache (verstärkte Anweisung +
Erinnerung an der letzten Nutzer-Nachricht gegen History-Trägheit).
Admin / Auth:
- Wörterbuch: alle 8 Sprachen, Zeilen editierbar, alphabetische Sortierung.
- Web-UI hinter Auth-Gate (Redirect auf SSO_LOGIN_URL / 401); Favicons offen.
- Log-Tab: Hinweis, wenn der systemd-Dienst nicht aktiv ist.
- Einstellungen: Hinweis "pro Nutzer überschreibbar" bei Sprache/Modus/Qualität.
Doku (BEDIENUNGSANLEITUNG.md): Geräte-TTS §6.5.0, Fix/Flex §6.6, native
Stimmen §6.5.3, llama.cpp<->Ollama-Wechsel §4.7, Auth/SSO §7.4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
dc8ac80505
commit
878bf785dd
51 changed files with 985 additions and 202 deletions
|
|
@ -4,8 +4,17 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
<title>Voice Assistant</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg?v=1" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png?v=1" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png?v=1" />
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>tailwind.config = { darkMode: "class" };</script>
|
||||
<style>
|
||||
/* Dropdown-Popup (<option>) hat sonst Browser-Default-Weiß -> im Dark-Mode
|
||||
helle Schrift auf hellem Grund = unlesbar. Farben explizit setzen. */
|
||||
select option { background-color: #ffffff; color: #1e293b; } /* slate-800 */
|
||||
.dark select option { background-color: #1e293b; color: #f1f5f9; } /* slate-100 */
|
||||
</style>
|
||||
<script>
|
||||
(function () {
|
||||
try {
|
||||
|
|
@ -137,6 +146,12 @@
|
|||
class="text-sm rounded-lg border border-slate-300 dark:border-slate-600 bg-transparent px-2 py-1.5">
|
||||
<option value="de">Deutsch (de)</option>
|
||||
<option value="en">Englisch (en)</option>
|
||||
<option value="fr">Französisch (fr)</option>
|
||||
<option value="es">Spanisch (es)</option>
|
||||
<option value="it">Italienisch (it)</option>
|
||||
<option value="nl">Niederländisch (nl)</option>
|
||||
<option value="ru">Russisch (ru)</option>
|
||||
<option value="zh">Chinesisch (zh)</option>
|
||||
</select>
|
||||
<button id="load-words"
|
||||
class="rounded-lg border border-slate-300 dark:border-slate-600 text-sm px-3 py-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors">Aktualisieren</button>
|
||||
|
|
@ -185,14 +200,31 @@
|
|||
|
||||
|
||||
<!-- ═══════════════════ CHAT INTERFACE ═══════════════════ -->
|
||||
<header class="shrink-0 h-14 flex items-center gap-3 px-4 border-b border-slate-200 dark:border-slate-700 bg-white/80 dark:bg-slate-800/80 backdrop-blur">
|
||||
<header class="shrink-0 h-14 flex items-center gap-2 px-3 border-b border-slate-200 dark:border-slate-700 bg-white/80 dark:bg-slate-800/80 backdrop-blur">
|
||||
<h1 class="flex-1 truncate font-semibold text-base">Voice Assistant</h1>
|
||||
<select id="tts" title="Stimme"
|
||||
<select id="lang-sel" title="Sprache — feste Sprache (Eingabe wird übersetzt) oder 🔄 Flex (folgt automatisch der gesprochenen Sprache)"
|
||||
class="text-sm rounded-lg border border-slate-300 dark:border-slate-600 bg-transparent px-2 py-1.5">
|
||||
<option value="">Schnell</option>
|
||||
<option value="chatterbox">Hohe Qualität</option>
|
||||
<option value="flex">🔄 Flex</option>
|
||||
<option value="de">🇩🇪 DE</option>
|
||||
<option value="en">🇬🇧 EN</option>
|
||||
<option value="fr">🇫🇷 FR</option>
|
||||
<option value="es">🇪🇸 ES</option>
|
||||
<option value="it">🇮🇹 IT</option>
|
||||
<option value="nl">🇳🇱 NL</option>
|
||||
<option value="ru">🇷🇺 RU</option>
|
||||
<option value="zh">🇨🇳 ZH</option>
|
||||
</select>
|
||||
<select id="tts" title="Sprachqualität"
|
||||
class="text-sm rounded-lg border border-slate-300 dark:border-slate-600 bg-transparent px-2 py-1.5">
|
||||
<option value="device">📱 Gerät</option>
|
||||
<option value="piper">Schnell</option>
|
||||
<option value="chatterbox">Hoch</option>
|
||||
<option value="openrouter">Cloud</option>
|
||||
</select>
|
||||
<button id="new-chat" title="Neues Gespräch (Verlauf zurücksetzen)"
|
||||
class="h-9 w-9 grid place-items-center rounded-lg border border-slate-300 dark:border-slate-600 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" class="w-5 h-5"><path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"/></svg>
|
||||
</button>
|
||||
<button id="admin-toggle" title="Admin"
|
||||
class="hidden h-9 w-9 grid place-items-center rounded-lg border border-slate-300 dark:border-slate-600 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors">⚙️</button>
|
||||
<button id="theme-toggle" title="Tag/Nacht"
|
||||
|
|
@ -218,6 +250,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=19"></script>
|
||||
<script src="/app.js?v=27"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue