Feat: festes Avatar-VRM (das eine Modell) + Avatar-Picker entfernt
Avatar fest auf /avatar.vrm (frontend/public/avatar.vrm → dist). Galerie/Upload/URL raus; AvatarPicker → reine VoiceControls (nur Stimme). vrmStore.ts gelöscht. avatar.vrm ist gitignored (23 MB, lizenz-/redistributionssensibel) — liegt auf der Box, nicht in git. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react"
|
||||
import { useEffect, useRef } from "react"
|
||||
import { Mic, RotateCcw, Loader2, Volume2 } from "lucide-react"
|
||||
import { Avatar3D } from "@/components/voice/Avatar3D"
|
||||
import { AvatarPicker, DEFAULT_AVATAR } from "@/components/voice/AvatarPicker"
|
||||
import { VoiceControls } from "@/components/voice/AvatarPicker"
|
||||
import { useVoiceAgent } from "@/lib/voice/useVoiceAgent"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
// Fester Avatar (das eine, gewählte VRM). Liegt unter frontend/public/avatar.vrm → /avatar.vrm.
|
||||
const FIXED_AVATAR = "/avatar.vrm"
|
||||
|
||||
const STATUS_LABEL: Record<string, string> = {
|
||||
idle: "Bereit — halte zum Sprechen",
|
||||
listening: "Höre zu …",
|
||||
@@ -15,14 +18,10 @@ const STATUS_LABEL: Record<string, string> = {
|
||||
}
|
||||
|
||||
export function VoiceView() {
|
||||
const [avatarUrl, setAvatarUrl] = useState(
|
||||
() => localStorage.getItem("mc_voice_avatar_url") || DEFAULT_AVATAR,
|
||||
)
|
||||
const { status, messages, error, recording, audioLevel, emotion, pressStart, pressEnd, reset } =
|
||||
useVoiceAgent()
|
||||
|
||||
const holding = useRef(false)
|
||||
const onAvatarChange = useCallback((url: string) => setAvatarUrl(url), [])
|
||||
|
||||
// Push-to-talk per Leertaste (solange der Sprechen-Tab fokussiert ist und kein Eingabefeld aktiv).
|
||||
useEffect(() => {
|
||||
@@ -49,7 +48,7 @@ export function VoiceView() {
|
||||
{/* Avatar-Bühne */}
|
||||
<div className="relative flex min-w-0 flex-1 flex-col rounded-xl border border-border/40 bg-card/30 overflow-hidden">
|
||||
<div className="flex-1 min-h-0">
|
||||
<Avatar3D url={avatarUrl} audioLevel={audioLevel} emotion={emotion} />
|
||||
<Avatar3D url={FIXED_AVATAR} audioLevel={audioLevel} emotion={emotion} />
|
||||
</div>
|
||||
|
||||
{/* Status + Push-to-talk */}
|
||||
@@ -85,8 +84,8 @@ export function VoiceView() {
|
||||
|
||||
{/* Seitenspalte: Einstellungen + Transcript */}
|
||||
<div className="flex w-80 shrink-0 flex-col gap-4">
|
||||
<div className="rounded-xl border border-border/40 bg-card/40 p-4 overflow-y-auto scrollbar-thin max-h-[55%]">
|
||||
<AvatarPicker avatarUrl={avatarUrl} onAvatarChange={onAvatarChange} />
|
||||
<div className="rounded-xl border border-border/40 bg-card/40 p-4">
|
||||
<VoiceControls />
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-0 flex-1 flex-col rounded-xl border border-border/40 bg-card/40">
|
||||
|
||||
Reference in New Issue
Block a user