import React, { useEffect } from 'react'; import { useUIStore } from '../../stores/uiStore'; import { useVoiceStore } from '../../stores/voiceStore'; import { useLocation } from 'react-router-dom'; import { MobileScreenStack } from './MobileScreenStack'; import { MobileBottomNav } from './MobileBottomNav'; import { useSwipeGesture } from '../../hooks/useSwipeGesture'; // Screen components — imported as they are created in subsequent tasks. // Inline placeholders are used until the real components exist. const PlaceholderScreen = ({ label }: { label: string }) => (
{label}
); import { MobileSpacesScreen } from './MobileSpacesScreen'; // These will be replaced with real imports as each task is completed: import { MobileDmsScreen } from './MobileDmsScreen'; import { MobileYouScreen } from './MobileYouScreen'; import { MobileChatScreen } from './MobileChatScreen'; import { MobileSettingsScreen } from './MobileSettingsScreen'; import { MobileVoiceMiniBar } from './MobileVoiceMiniBar'; const MobileVoiceFullScreen = () => ; const screenMap: Record) => React.ReactNode> = { 'channel-chat': (params) => , 'friends': () => , 'settings': () => , 'settings-account': () => , 'settings-voice': () => , 'settings-privacy': () => , 'settings-connections': () => , 'settings-instance': () => , 'members': () => , 'voice-full': () => , 'explore': () => , 'user-profile': () => , }; export function MobileShell() { const mobileScreen = useUIStore((s) => s.mobileScreen); const popMobileScreen = useUIStore((s) => s.popMobileScreen); const pushMobileScreen = useUIStore((s) => s.pushMobileScreen); const mobileStack = useUIStore((s) => s.mobileStack); const currentVoiceChannelId = useVoiceStore((s) => s.currentVoiceChannelId); const location = useLocation(); // Edge swipe back gesture useSwipeGesture({ onSwipeRight: () => { if (mobileStack.length > 0) { popMobileScreen(); } }, enabled: mobileStack.length > 0, }); // Reconstruct mobile stack from URL on mount (deep link / refresh support) useEffect(() => { const path = location.pathname; const match = path.match(/^\/channels\/([^/]+)\/([^/]+)$/); if (match && mobileStack.length === 0) { const [, spaceId, channelId] = match; if (spaceId === '@me') { pushMobileScreen('channel-chat', { channelId, spaceId: '@me' }); } else { pushMobileScreen('channel-chat', { channelId, spaceId }); } } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Only on mount // Sync browser back button with mobile stack useEffect(() => { const handlePopState = () => { if (useUIStore.getState().mobileStack.length > 0) { popMobileScreen(); } }; window.addEventListener('popstate', handlePopState); return () => window.removeEventListener('popstate', handlePopState); }, [popMobileScreen]); const rootScreens: Record = { spaces: , dms: , you: , }; return (
{/* Voice mini-bar — shown when in a voice call */} {currentVoiceChannelId && } {/* Bottom nav — MobileBottomNav hides itself when stack is non-empty */}
); }