Feat: Chat-Verbesserungen — echte Umlaute, TTS-Filter, Lautstärke-Regler, Sprechblasen
- Umlaute: System-Prompt erzwingt echte ä/ö/ü/ß (Hermes spiegelte bei Technik den ASCII-Hint). - TTS-Filter: cleanForTTS entfernt URLs/Markdown/Code/Emojis vor der Sprachausgabe (Anzeige bleibt). - Lautstärke: GainNode in AudioQueue + Regler (Default 60%, live); Probe-hören respektiert ihn. (Bugfix: Number(null)===0 → wäre sonst stumm gewesen.) - Chat: Sprechblasen (User rechts / Hermes links), Zeilenumbrüche, Auto-Scroll, Tipp-Indikator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -17,8 +17,20 @@ export function VoiceControls() {
|
||||
const [engine, setEngine] = useState(localStorage.getItem("mc_voice_engine") || "elevenlabs")
|
||||
const [voice, setVoice] = useState(localStorage.getItem("mc_voice_voice") || "")
|
||||
const [previewing, setPreviewing] = useState(false)
|
||||
const [volume, setVolume] = useState(() => {
|
||||
const raw = localStorage.getItem("mc_voice_volume")
|
||||
if (raw === null || raw === "") return 0.6 // Number(null)===0 → sonst aus Versehen stumm
|
||||
const v = Number(raw)
|
||||
return Number.isNaN(v) ? 0.6 : v
|
||||
})
|
||||
const previewAudio = useRef<HTMLAudioElement | null>(null)
|
||||
|
||||
const onVolume = (v: number) => {
|
||||
setVolume(v)
|
||||
localStorage.setItem("mc_voice_volume", String(v))
|
||||
window.dispatchEvent(new CustomEvent("mc-voice-volume", { detail: v }))
|
||||
}
|
||||
|
||||
const saveVoice = (eng: string, v: string) => {
|
||||
setEngine(eng); setVoice(v)
|
||||
localStorage.setItem("mc_voice_engine", eng)
|
||||
@@ -55,6 +67,7 @@ export function VoiceControls() {
|
||||
const url = URL.createObjectURL(await r.blob())
|
||||
previewAudio.current?.pause()
|
||||
const a = new Audio(url)
|
||||
a.volume = Math.min(1, volume) // Regler auch für die Probe respektieren
|
||||
previewAudio.current = a
|
||||
a.onended = () => URL.revokeObjectURL(url)
|
||||
await a.play()
|
||||
@@ -114,6 +127,17 @@ export function VoiceControls() {
|
||||
{previewing ? <Loader2 className="h-3.5 w-3.5 animate-spin" /> : <Volume2 className="h-3.5 w-3.5" />}
|
||||
{previewing ? "Spielt …" : "Probe hören"}
|
||||
</button>
|
||||
{/* Lautstärke */}
|
||||
<div className="flex items-center gap-2 pt-0.5">
|
||||
<Volume2 className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
|
||||
<input
|
||||
type="range" min={0} max={1.2} step={0.05} value={volume}
|
||||
onChange={(e) => onVolume(Number(e.target.value))}
|
||||
className="h-1 flex-1 cursor-pointer accent-primary"
|
||||
title="Lautstärke"
|
||||
/>
|
||||
<span className="w-9 text-right text-[11px] tabular-nums text-muted-foreground">{Math.round(volume * 100)}%</span>
|
||||
</div>
|
||||
{elKeyMissing && (
|
||||
<p className="text-[11px] text-amber-300">
|
||||
Keine ElevenLabs-Stimmen — Key in <code>~/.hermes/.env</code> fehlt, oder keine eigene Stimme angelegt.
|
||||
|
||||
Reference in New Issue
Block a user