import { useVoiceStore } from '../stores/voice.ts'; import { useAuthStore } from '../stores/auth.ts'; import { usePermissions } from '../lib/usePermissions.ts'; import { useChannelStore } from '../stores/channel.ts'; import { useVoicePresenceStore } from '../stores/voicePresence.ts'; import { api } from '../lib/api.ts'; interface VoiceChannelProps { channelId: string; channelName: string; } export function VoiceChannel({ channelId, channelName }: VoiceChannelProps) { const currentRoom = useVoiceStore((state) => state.currentRoom); const isConnected = useVoiceStore((state) => state.isConnected); const joinVoice = useVoiceStore((state) => state.joinVoice); const liveParticipants = useVoiceStore((state) => state.participants); const presenceParticipants = useVoicePresenceStore((s) => s.getParticipants(channelId)); const currentUserId = useAuthStore((state) => state.user?.id); const activeChannelId = useChannelStore((s) => s.activeChannelId); const channelsByServer = useChannelStore((s) => s.channelsByServer); const serverId = activeChannelId ? Object.entries(channelsByServer).find(([_, channels]) => channels.some(c => c.id === activeChannelId))?.[0] : null; const { canMute } = usePermissions(serverId || null); const handleMute = async (identity: string) => { if (!currentRoom) return; try { await api.post(`/voice/rooms/${currentRoom}/participants/${identity}/mute`); } catch (err) { console.error('Failed to mute participant:', err); } }; const whisperTo = (identity: string, username: string) => { useVoiceStore.getState().whisperTo(identity, username); }; const isActive = currentRoom === channelId; // Use live participants when in the room, otherwise fall back to presence const displayParticipants = isActive && isConnected ? liveParticipants.map(p => ({ userId: p.identity, username: p.username, isMuted: p.isMuted, isSpeaking: p.isSpeaking, hasVideo: p.hasVideo, isScreenSharing: p.isScreenSharing })) : presenceParticipants.map(p => ({ userId: p.userId, username: p.username, isMuted: true, isSpeaking: false, hasVideo: false, isScreenSharing: false })); const handleClick = () => { if (!isActive) { console.log("[VoiceChannel] joining voice:", channelId, channelName); joinVoice(channelId, channelName).catch((err) => { console.error("[VoiceChannel] joinVoice failed:", err); }); } }; const error = useVoiceStore((state) => state.error); return (