"use client"; import { Cable, Mic, PhoneOff, Radio, ShieldCheck, ShieldOff, Volume2, } from "lucide-react"; import { useEffect, useState } from "react"; import { useAmbient } from "@/components/ambient/ambient-context"; import { Button, GlassPanel, toast } from "@/components/primitives"; import { ErrorState, PageTransition, SectionHeader, SkeletonPanel, } from "@/components/shared"; import { GuildChannelPicker } from "@/components/shared/guild-picker"; import { VoiceStage } from "@/components/voice/voice-stage"; import { useMicTransmit, useSpeakers, useVoiceConnect, useVoiceDisconnect, useVoiceListen, useVoiceStatus, } from "@/hooks"; import { useStaggerReveal } from "@/hooks/use-gsap-animation"; import type { Guild, VoiceStatus } from "@/lib/types"; import { useWebSocket } from "@/lib/ws/context"; export function VoiceView({ initialStatus, initialGuilds, }: { initialStatus?: VoiceStatus; initialGuilds?: Guild[]; }) { const ws = useWebSocket(); const { data: status, isLoading, error, mutate, } = useVoiceStatus(initialStatus); const connect = useVoiceConnect(); const disconnect = useVoiceDisconnect(); const mic = useMicTransmit(ws); const listen = useVoiceListen(ws); const { speakers, subscribe } = useSpeakers(initialStatus?.activeSpeakers); const ambient = useAmbient(); const [guildId, setGuildId] = useState( initialStatus?.activeGuildId ?? initialGuilds?.[0]?.id ?? null, ); const [channelId, setChannelId] = useState( initialStatus?.activeChannelId ?? null, ); const [micVol, setMicVol] = useState(100); const [listenVol, setListenVol] = useState(75); const [micActive, setMicActive] = useState(false); const [listenActive, setListenActive] = useState(false); const toggleMic = async () => { const next = !micActive; try { await mic.mutateAsync(next); setMicActive(next); toast({ title: next ? "Mic activated" : "Mic deactivated", tone: next ? "signal" : "neutral", }); } catch (e) { // MicAccessError from mic-transmit.ts has specific reasons const msg = e instanceof Error ? e.message : String(e); const isPermDenied = msg.includes("denied") || msg.includes("Permission"); const isNoMic = msg.includes("No microphone"); toast({ title: isPermDenied ? "Mic permission denied" : isNoMic ? "No microphone found" : "Mic toggle failed", description: msg, tone: "vermilion", }); } }; const toggleListen = () => { const next = !listenActive; listen.toggle(next); setListenActive(next); toast({ title: next ? "Monitor activated" : "Monitor deactivated", tone: next ? "signal" : "neutral", }); }; const containerRef = useStaggerReveal(".voice-tile", { stagger: 0.04, y: 8, dependencies: [status], }); useEffect(() => { const unsub = subscribe(ws); return unsub; }, [subscribe, ws]); useEffect(() => { if (status?.connected) ambient.set("signal", 0.45, "voice active"); else ambient.set("vermilion", 0.25, "voice disconnected"); }, [status?.connected, ambient]); if (error && !status) return void mutate()} />; if (!status && isLoading) return (
); const connected = status?.connected ?? false; const onConnect = async () => { if (!guildId || !channelId) { toast({ title: "Select target channel", tone: "vermilion" }); return; } try { await connect.mutateAsync({ guildId, channelId }); toast({ title: "Connected to voice channel", tone: "signal" }); } catch (e) { toast({ title: "Connection failed", description: String(e), tone: "vermilion", }); } }; const onDisconnect = async () => { try { await disconnect.mutateAsync(); toast({ title: "Disconnected from voice", tone: "neutral" }); } catch (e) { toast({ title: "Disconnect failed", description: String(e), tone: "vermilion", }); } }; return (
{/* Precision Sub-Header Bar */}

Voice Spectrum & Stage Controls

STAGE: {connected ? "LIVE_BRIDGE" : "OFFLINE"}
{/* Channel Router Stage */}
{ setGuildId(g); setChannelId(c); }} mode="voice" />
{connected ? ( ) : ( )}
{/* Connected Bridges — multi-guild voice bridge roster */} {status?.connections?.length ?? (connected ? 1 : 0)} ACTIVE } />
{status?.connections && status.connections.length > 0 ? (
{status.connections.map((conn) => { const isActive = conn.guildId === status.activeGuildId && conn.channelId === status.activeChannelId; return (
{conn.channelName || "#" + conn.channelId.slice(0, 8)}
G:{conn.guildId.slice(0, 8)} · C: {conn.channelId.slice(0, 8)} {isActive && ( ACTIVE )}
{new Date(conn.connectedAt).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", })}
); })}
) : connected ? (
{status?.activeChannelName || "Voice channel"}
Active bridge · G: {(status?.activeGuildId ?? guildId ?? "").slice(0, 8)}
ACTIVE
) : (
No active voice bridges
)}
{/* Voice Stage Grid */}
{/* Mic Toggle */}
{micVol}%
{ const v = Number(e.target.value); setMicVol(v); mic.setVolume(v / 100); }} className="mt-2 h-1.5 w-full appearance-none rounded-full bg-surface-2 accent-signal" /> {/* Live mic level meter */} {micActive && (
)} {/* Noise Suppression Toggle */}
{micActive && ( {mic.noiseSuppression ? "noise gated" : "raw audio"} )}
{/* Listen Toggle */}
{listenVol}%
{ const v = Number(e.target.value); setListenVol(v); listen.setVolume(v / 100); }} className="mt-2 h-1.5 w-full appearance-none rounded-full bg-surface-2 accent-success" /> {/* Per-speaker level meters */} {listenActive && listen.levels.size > 0 && (
{Array.from(listen.levels.entries()).map( ([hash, level]) => (
#{hash.toString(16).slice(-3)}
), )}
)}
CODEC: OPUS 48KHZ · LOW_LATENCY {mic.noiseSuppression ? " · NS_ACTIVE" : ""}
); }