import React, { useEffect, useRef } from 'react'; import { VoiceUser } from './VoiceUser'; import { useVoiceStore } from '../../stores/voiceStore'; import type { ParticipantInfo } from '../../hooks/useLiveKit'; interface VoiceGridProps { participants: ParticipantInfo[]; } export function VoiceGrid({ participants }: VoiceGridProps) { const focusedParticipantId = useVoiceStore((s) => s.focusedParticipantId); const setFocusedParticipant = useVoiceStore((s) => s.setFocusedParticipant); const prevScreenSharerRef = useRef(null); // Auto-focus when someone starts screen sharing useEffect(() => { const screenSharer = participants.find( (p) => p.screenTrack?.readyState === 'live', ); const screenSharerId = screenSharer?.identity ?? null; if (screenSharerId && screenSharerId !== prevScreenSharerRef.current) { // New screen share started — auto-focus setFocusedParticipant(screenSharerId); } else if (!screenSharerId && prevScreenSharerRef.current) { // Screen share ended — unfocus if we were focused on the sharer if (focusedParticipantId === prevScreenSharerRef.current) { setFocusedParticipant(null); } } prevScreenSharerRef.current = screenSharerId; }, [participants, focusedParticipantId, setFocusedParticipant]); if (participants.length === 0) { return (

Waiting for others to join...

); } const focusedParticipant = focusedParticipantId ? participants.find((p) => p.identity === focusedParticipantId) : null; // Focus mode: one large tile + sidebar strip if (focusedParticipant) { const otherParticipants = participants.filter( (p) => p.identity !== focusedParticipantId, ); return (
{/* Main focused view */}
{/* Back to grid button */}
{/* Side strip of other participants */} {otherParticipants.length > 0 && (
{otherParticipants.map((p) => (
setFocusedParticipant(p.identity)} className="cursor-pointer hover:opacity-80 transition-opacity" >
))}
)}
); } // Default grid mode const gridClass = (() => { if (participants.length === 1) return 'grid-cols-1 max-w-2xl mx-auto'; if (participants.length === 2) return 'grid-cols-2 max-w-4xl mx-auto'; if (participants.length <= 4) return 'grid-cols-2'; if (participants.length <= 9) return 'grid-cols-3'; return 'grid-cols-4'; })(); return (
{participants.map((p) => (
setFocusedParticipant(p.identity)} className="cursor-pointer hover:opacity-90 transition-opacity" >
))}
); }