import React, { useEffect, useRef, useState, useCallback } from 'react'; import { useLocation } from 'react-router-dom'; import { useSpaceStore } from '../../stores/spaceStore'; import { useChatStore } from '../../stores/chatStore'; import { useUIStore } from '../../stores/uiStore'; import { useAuthStore } from '../../stores/authStore'; import { MessageList } from '../chat/MessageList'; import { MessageInput } from '../chat/MessageInput'; import { VoiceGrid } from '../voice/VoiceGrid'; import { VoiceControlBar } from '../voice/VoiceControlBar'; import { VoiceChatPanel } from '../voice/VoiceChatPanel'; import { FriendsPage } from '../chat/FriendsPage'; import { ExplorePage } from '../chat/ExplorePage'; import { Avatar } from '../ui/Avatar'; import { useVoiceStore } from '../../stores/voiceStore'; import { wsSend } from '../../hooks/useWebSocket'; import { MemberListToggleButton } from './MemberListToggleButton'; import { isSelf } from '../../utils/identity'; import { joinVoiceChannel } from '../../utils/voice'; export function MainContent() { // 1. ALL HOOKS AT THE TOP const channels = useSpaceStore((s) => s.channels); const currentChannelId = useChatStore((s) => s.currentChannelId); const currentSpaceId = useSpaceStore((s) => s.currentSpaceId); const voiceChatOpen = useUIStore((s) => s.voiceChatOpen); const voiceFullscreen = useUIStore((s) => s.voiceFullscreen); const setVoiceFullscreen = useUIStore((s) => s.setVoiceFullscreen); const participants = useVoiceStore((s) => s.participants); const currentVoiceChannelId = useVoiceStore((s) => s.currentVoiceChannelId); const isLiveKitConnected = useVoiceStore((s) => s.isLiveKitConnected); const connectionError = useVoiceStore((s) => s.connectionError); const showDms = useUIStore((s) => s.showDms); const location = useLocation(); const isExplorePage = location.pathname === '/explore'; const activeDmCall = useVoiceStore((s) => s.activeDmCall); const outgoingCall = useVoiceStore((s) => s.outgoingCall); const dmChannels = useSpaceStore((s) => s.dmChannels); const authUser = useAuthStore((s) => s.user); const openModal = useUIStore((s) => s.openModal); const voiceContainerRef = useRef(null); // Handle actual browser fullscreen API useEffect(() => { const handleFullscreenChange = () => { setVoiceFullscreen(!!document.fullscreenElement); }; document.addEventListener('fullscreenchange', handleFullscreenChange); return () => document.removeEventListener('fullscreenchange', handleFullscreenChange); }, [setVoiceFullscreen]); useEffect(() => { if (voiceFullscreen && voiceContainerRef.current && !document.fullscreenElement) { voiceContainerRef.current.requestFullscreen().catch(err => { console.error('Error attempting to enable full-screen mode:', err); }); } else if (!voiceFullscreen && document.fullscreenElement) { document.exitFullscreen().catch(() => {}); } }, [voiceFullscreen]); // 2. LOGIC AND EARLY RETURNS const channel = channels.find(c => c.id === currentChannelId); const isVoiceChannel = channel?.type === 'voice' || channel?.type === 'video'; if (showDms || isExplorePage || !currentSpaceId) { if (!currentChannelId) { if (isExplorePage) return ; return ; } const dmChannel = dmChannels.find(dm => dm.id === currentChannelId); const otherMembers = dmChannel?.members.filter(m => !isSelf(m, authUser)) ?? []; const isGroupDm = (dmChannel?.members.length ?? 0) > 2; const dmName = isGroupDm ? otherMembers.map(m => m.displayName ?? m.username).join(', ') : otherMembers[0]?.displayName ?? otherMembers[0]?.username ?? 'Direct Message'; const isInDmCall = activeDmCall?.dmChannelId === currentChannelId; const isCallingThisDm = outgoingCall?.dmChannelId === currentChannelId; const handleStartVoiceCall = () => { if (!currentChannelId) return; useVoiceStore.getState().setOutgoingCall({ dmChannelId: currentChannelId }); wsSend({ type: 'dm_call_start', dmChannelId: currentChannelId }); }; const handleCancelCall = () => { if (!currentChannelId) return; useVoiceStore.getState().setOutgoingCall(null); wsSend({ type: 'dm_call_end', dmChannelId: currentChannelId }); }; if (isInDmCall) { return (
{dmName} {connectionError ? ( Connection Failed ) : isLiveKitConnected ? ( <> Connected {participants.length} in call ) : ( Connecting... )}
{voiceChatOpen && !voiceFullscreen && ( )}
); } return (
{isCallingThisDm && (
Calling {dmName}...
)}
{dmName} {isGroupDm && ( ({dmChannel?.members.length} Members) )}
); } if (!currentChannelId || !channel) { return (
Select a channel

Select a text or voice channel to get started

); } if (isVoiceChannel) { const isInThisChannel = currentVoiceChannelId === currentChannelId; if (!isInThisChannel) { return (
{channel.name}

{channel.name}

No one is currently in this voice channel.

); } return (
{channel.name} {connectionError ? ( Connection Failed ) : isLiveKitConnected ? ( <> Connected {participants.length} connected ) : ( Connecting... )}
{voiceChatOpen && !voiceFullscreen && ( )}
); } return (
# {channel.name} {channel.topic && ( <>
{channel.topic} )}
); }