import React from 'react';
import { useVoiceStore } from '../../stores/voiceStore';
import { useAuthStore } from '../../stores/authStore';
const EMPTY_VOICE_USERS: string[] = [];
import { useServerStore } from '../../stores/serverStore';
import { Avatar } from '../ui/Avatar';
interface VoiceChannelProps {
channelId: string;
channelName: string;
onClick: () => void;
}
export function VoiceChannel({ channelId, channelName, onClick }: VoiceChannelProps) {
const voiceUsers = useVoiceStore((s) => s.voiceUsers.get(channelId)) ?? EMPTY_VOICE_USERS;
const currentVoiceChannel = useVoiceStore((s) => s.currentVoiceChannelId);
const participants = useVoiceStore((s) => s.participants);
const localIsDeafened = useVoiceStore((s) => s.isDeafened);
const localIsMuted = useVoiceStore((s) => s.isMuted);
const voiceUserStates = useVoiceStore((s) => s.voiceUserStates);
const currentUserId = useAuthStore((s) => s.user?.id);
const members = useServerStore((s) => s.members);
const isActive = currentVoiceChannel === channelId;
return (
{/* Connected users */}
{voiceUsers.length > 0 && (
{voiceUsers.map((userId) => {
const member = members.find(m => m.userId === userId);
const participant = participants.find(p => p.userId === userId);
const displayName = member?.user.displayName ?? member?.user.username ?? participant?.username ?? userId;
const avatar = member?.user.avatar ?? null;
const status = member?.user.status;
// Resolve status: for local user use store directly, for remote users
// try LiveKit participant first, then fall back to WebSocket voiceUserStates
const wsStatus = voiceUserStates.get(userId);
const isParticipantDeafened = userId === currentUserId
? localIsDeafened
: (participant?.isDeafened ?? wsStatus?.isDeafened ?? false);
const isMuted = userId === currentUserId
? localIsMuted
: (participant?.isMuted ?? wsStatus?.isMuted ?? false);
const hasCamera = participant?.isCameraOn ?? wsStatus?.isCameraOn ?? false;
const isScreenSharing = participant?.isScreenSharing ?? wsStatus?.isScreenSharing ?? false;
return (
{displayName}
{/* Status badges */}
{isMuted && (
)}
{isParticipantDeafened && (
)}
{hasCamera && (
)}
{isScreenSharing && (
LIVE
)}
);
})}
)}
);
}