refactor(ui): Geräte-STT entfernt + Menü-Redesign (schlanke Kopfzeile + ⋮-Sheet)
Geräte-STT (Web Speech API) entfernt — auf Android nur Cloud, Qualität < Whisper, verwirrend. STT läuft jetzt überall serverseitig (Whisper). Geräte-TTS bleibt. - Backend: allow_cloud_stt (config/runtime_config/api me) + Tests entfernt. - Frontend: SpeechRecognition-Code, STT-Dropdown, "Lokal"-Button raus. Menü-Redesign (verständlicher + passt auf Handys): - Kopfzeile schlank: Mund-Icon + Titel + Sprache + ⋮-Menübutton (kein Überlauf mehr). - ⋮ öffnet ein Einstellungs-Sheet: Ton als 3 Presets (📱 Im Gerät / ☁ Server / ✨ Beste Qualität) statt zweier kryptischer "Gerät"-Dropdowns; Neues Gespräch; Tag-/Nachtmodus; Konto (Identität, Admin, Abmelden). - #tts bleibt als verborgenes Quell-Select -> bestehende TTS-Logik unverändert. - Doku §5.1.2 neu, §6.3 STT-Hinweis. 167 grün. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
f74d2fadb2
commit
3f6bf53a7f
7 changed files with 161 additions and 254 deletions
|
|
@ -201,8 +201,9 @@
|
|||
|
||||
<!-- ═══════════════════ CHAT INTERFACE ═══════════════════ -->
|
||||
<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">
|
||||
<img src="/favicon.svg?v=1" alt="" class="w-7 h-7 shrink-0" />
|
||||
<h1 class="flex-1 truncate font-semibold text-base">Voice Assistant</h1>
|
||||
<select id="lang-sel" title="Sprache — feste Sprache (Eingabe wird übersetzt) oder 🔄 Flex (folgt automatisch der gesprochenen Sprache)"
|
||||
<select id="lang-sel" title="Sprache — feste Sprache oder 🔄 Flex (folgt 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="flex">🔄 Flex</option>
|
||||
<option value="de">🇩🇪 DE</option>
|
||||
|
|
@ -214,33 +215,75 @@
|
|||
<option value="ru">🇷🇺 RU</option>
|
||||
<option value="zh">🇨🇳 ZH</option>
|
||||
</select>
|
||||
<select id="tts" title="Sprachausgabe (TTS)"
|
||||
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>
|
||||
<select id="stt-sel" title="Spracherkennung (STT)"
|
||||
class="hidden 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="server">☁ Server</option>
|
||||
</select>
|
||||
<button id="all-local" title="Alles lokal: Spracherkennung + Vorlesen im Gerät (nur Text wird gesendet)"
|
||||
class="hidden text-sm rounded-lg border border-slate-300 dark:border-slate-600 bg-transparent px-2 py-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors whitespace-nowrap">📴 Lokal</button>
|
||||
<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"
|
||||
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">🌙</button>
|
||||
<button id="menu-toggle" title="Menü" aria-label="Menü"
|
||||
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 text-xl leading-none transition-colors">⋮</button>
|
||||
</header>
|
||||
|
||||
<div class="shrink-0 flex items-center justify-between px-4 py-1 text-xs text-slate-500 dark:text-slate-400 border-b border-slate-200 dark:border-slate-700">
|
||||
<span id="identity">lade …</span>
|
||||
<a id="logout" class="hidden hover:underline" href="#">Abmelden</a>
|
||||
<!-- Verstecktes Quell-Select: speist die Ton-Presets (bewahrt die bestehende Logik) -->
|
||||
<select id="tts" class="hidden">
|
||||
<option value="device">Im Gerät</option>
|
||||
<option value="piper">Server</option>
|
||||
<option value="chatterbox">Beste Qualität</option>
|
||||
<option value="openrouter">Cloud</option>
|
||||
</select>
|
||||
|
||||
<!-- ═══════════════════ EINSTELLUNGS-SHEET ═══════════════════ -->
|
||||
<div id="settings-backdrop" class="hidden fixed inset-0 z-40 bg-black/30"></div>
|
||||
<div id="settings-sheet"
|
||||
class="hidden fixed top-14 right-2 z-50 w-[min(20rem,calc(100vw-1rem))] max-h-[80vh] overflow-y-auto
|
||||
rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 shadow-xl p-3 space-y-3">
|
||||
|
||||
<!-- Vorlesen (TTS-Presets) -->
|
||||
<div>
|
||||
<p class="text-xs font-semibold uppercase tracking-wide text-slate-500 dark:text-slate-400 mb-1.5 px-1">Vorlesen</p>
|
||||
<div class="space-y-1.5">
|
||||
<button type="button" data-tts="device"
|
||||
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">Im Gerät</span>
|
||||
<span class="block text-xs text-slate-500 dark:text-slate-400">Das Gerät liest vor · spart Daten</span></span>
|
||||
<span class="check text-blue-600 dark:text-blue-400 font-bold opacity-0">✓</span>
|
||||
</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="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="check text-blue-600 dark:text-blue-400 font-bold opacity-0">✓</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Aktionen -->
|
||||
<div class="border-t border-slate-100 dark:border-slate-700 pt-2 space-y-1">
|
||||
<button id="new-chat" type="button"
|
||||
class="w-full flex items-center gap-3 rounded-lg px-3 py-2 text-sm hover:bg-slate-50 dark:hover:bg-slate-700/50 text-left transition-colors">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" class="w-5 h-5 shrink-0"><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>
|
||||
Neues Gespräch
|
||||
</button>
|
||||
<button id="theme-toggle" type="button"
|
||||
class="w-full flex items-center gap-3 rounded-lg px-3 py-2 text-sm hover:bg-slate-50 dark:hover:bg-slate-700/50 text-left transition-colors">
|
||||
<span id="theme-icon" class="w-5 text-center shrink-0">🌙</span>
|
||||
<span>Tag-/Nachtmodus</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Konto -->
|
||||
<div class="border-t border-slate-100 dark:border-slate-700 pt-2">
|
||||
<p id="identity" class="text-xs text-slate-500 dark:text-slate-400 px-1 mb-1.5">lade …</p>
|
||||
<div class="flex items-center gap-2 px-1">
|
||||
<button id="admin-toggle" type="button"
|
||||
class="hidden text-xs rounded-lg border border-slate-300 dark:border-slate-600 px-2.5 py-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 transition-colors">⚙ Admin</button>
|
||||
<a id="logout" href="#" class="hidden text-xs text-blue-600 dark:text-blue-400 hover:underline ml-auto">Abmelden</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main id="messages" class="flex-1 overflow-y-auto px-4 py-4 space-y-3 w-full max-w-3xl mx-auto"></main>
|
||||
|
|
@ -257,6 +300,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=34"></script>
|
||||
<script src="/app.js?v=35"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue