import React, { useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { ServerSidebar } from './ServerSidebar'; import { ChannelSidebar } from './ChannelSidebar'; import { MainContent } from './MainContent'; import { RightPanel } from './RightPanel'; import { MobileNav } from './MobileNav'; import { ImagePreview } from '../chat/ImagePreview'; import { CreateServerModal } from '../modals/CreateServer'; import { JoinServerModal } from '../modals/JoinServer'; import { CreateChannelModal } from '../modals/CreateChannel'; import { InviteModal } from '../modals/InviteModal'; import { UserSettingsModal } from '../modals/UserSettings'; import { ServerSettingsModal } from '../modals/ServerSettings'; import { ChannelSettingsModal } from '../modals/ChannelSettingsModal'; import { NewDmModal } from '../modals/NewDmModal'; import { AddDmMemberModal } from '../modals/AddDmMemberModal'; import { IncomingCallModal } from '../voice/IncomingCallModal'; import { PictureInPicture } from '../voice/PictureInPicture'; import { SoundController } from '../voice/SoundController'; import { GlobalAudioRenderer } from '../voice/GlobalAudioRenderer'; import { UserProfilePopout } from '../ui/UserProfilePopout'; import { ToastContainer } from '../ui/ToastContainer'; import { useAuth } from '../../hooks/useAuth'; import { useWebSocket } from '../../hooks/useWebSocket'; import { useFederationToasts } from '../../hooks/useFederationToasts'; import { useLiveKit } from '../../hooks/useLiveKit'; import { useServerStore } from '../../stores/serverStore'; import { useChatStore } from '../../stores/chatStore'; import { useUIStore } from '../../stores/uiStore'; import { useVoiceStore } from '../../stores/voiceStore'; import { AudioManager } from '../../audio/AudioManager'; export function AppLayout() { const { serverId, channelId, inviteCode } = useParams<{ serverId?: string; channelId?: string; inviteCode?: string }>(); const navigate = useNavigate(); // Global interaction handler to resume AudioContext useEffect(() => { const resume = () => { AudioManager.getInstance().resumeContext().then(() => { window.removeEventListener('click', resume); window.removeEventListener('keydown', resume); window.removeEventListener('touchstart', resume); }); }; window.addEventListener('click', resume); window.addEventListener('keydown', resume); window.addEventListener('touchstart', resume); return () => { window.removeEventListener('click', resume); window.removeEventListener('keydown', resume); window.removeEventListener('touchstart', resume); }; }, []); // MutationObserver: neutralize rogue LiveKit