{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "voice-chat-02", "description": "Voice chat 2", "dependencies": [ "@elevenlabs/react", "framer-motion" ], "registryDependencies": [ "https://ui.elevenlabs.io/r/orb.json", "https://ui.elevenlabs.io/r/shimmering-text.json", "button", "card" ], "files": [ { "path": "blocks/voice-chat-02/page.tsx", "content": "\"use client\"\n\nimport { useCallback, useState } from \"react\"\nimport {\n ConversationProvider,\n useConversationControls,\n useConversationStatus,\n} from \"@elevenlabs/react\"\nimport { AnimatePresence, motion } from \"framer-motion\"\nimport { Loader2Icon, PhoneIcon, PhoneOffIcon } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { Card } from \"@/components/ui/card\"\nimport { Orb } from \"@/components/ui/orb\"\nimport { ShimmeringText } from \"@/components/ui/shimmering-text\"\n\nconst DEFAULT_AGENT = {\n agentId: process.env.NEXT_PUBLIC_ELEVENLABS_AGENT_ID!,\n name: \"Customer Support\",\n description: \"Tap to start voice chat\",\n}\n\nexport default function Page() {\n return (\n \n \n \n )\n}\n\nexport function VoiceChat02() {\n const { status } = useConversationStatus()\n const { startSession, endSession, getInputVolume, getOutputVolume } =\n useConversationControls()\n const [errorMessage, setErrorMessage] = useState(null)\n\n const startConversation = useCallback(async () => {\n try {\n setErrorMessage(null)\n await navigator.mediaDevices.getUserMedia({ audio: true })\n startSession({\n agentId: DEFAULT_AGENT.agentId,\n connectionType: \"webrtc\",\n })\n } catch (error) {\n console.error(\"Error starting conversation:\", error)\n if (error instanceof DOMException && error.name === \"NotAllowedError\") {\n setErrorMessage(\"Please enable microphone permissions in your browser.\")\n }\n }\n }, [startSession])\n\n const handleCall = useCallback(() => {\n if (status === \"disconnected\" || status === \"error\") {\n startConversation()\n } else if (status === \"connected\") {\n endSession()\n }\n }, [status, endSession, startConversation])\n\n const isCallActive = status === \"connected\"\n const isTransitioning = status === \"connecting\"\n\n const scaledInputVolume = useCallback(() => {\n try {\n const rawValue = getInputVolume() ?? 0\n return Math.min(1.0, Math.pow(rawValue, 0.5) * 2.5)\n } catch {\n return 0\n }\n }, [getInputVolume])\n\n const scaledOutputVolume = useCallback(() => {\n try {\n const rawValue = getOutputVolume() ?? 0\n return Math.min(1.0, Math.pow(rawValue, 0.5) * 2.5)\n } catch {\n return 0\n }\n }, [getOutputVolume])\n\n return (\n \n
\n
\n
\n
\n \n
\n
\n
\n\n
\n

{DEFAULT_AGENT.name}

\n \n {errorMessage ? (\n \n {errorMessage}\n \n ) : status === \"disconnected\" || status === \"error\" ? (\n \n {DEFAULT_AGENT.description}\n \n ) : (\n \n \n \n {isTransitioning ? (\n \n ) : (\n Connected\n )}\n \n \n )}\n \n
\n\n \n \n {isTransitioning ? (\n \n \n \n ) : isCallActive ? (\n \n \n \n ) : (\n \n \n \n )}\n \n \n
\n
\n )\n}\n", "type": "registry:page", "target": "app/voice-chat/page.tsx" } ], "meta": { "iframeHeight": "600px", "container": "w-full bg-surface min-h-svh flex px-4 py-12 items-center md:py-20 justify-center min-w-0", "mobile": "component" }, "categories": [ "agents" ], "type": "registry:block" }