import React from 'react'; import { useUIStore } from '../../stores/uiStore'; import { useChatStore } from '../../stores/chatStore'; import { useAuthStore } from '../../stores/authStore'; import { useSocialStore } from '../../stores/socialStore'; import { useSpaceStore } from '../../stores/spaceStore'; import { useNavigate } from 'react-router-dom'; export function MobileBottomNav() { const mobileScreen = useUIStore((s) => s.mobileScreen); const mobileStack = useUIStore((s) => s.mobileStack); const setMobileTab = useUIStore((s) => s.setMobileTab); const navigate = useNavigate(); // Badge data const unreadChannels = useChatStore((s) => s.unreadChannels); const voiceChannelIds = useSpaceStore((s) => s.voiceChannelIds); const dmChannels = useSpaceStore((s) => s.dmChannels); const readStates = useChatStore((s) => s.readStates); const requests = useSocialStore((s) => s.requests); const authUser = useAuthStore((s) => s.user); // Hide when any screen is pushed (chat, settings, friends, etc.) if (mobileStack.length > 0) return null; // Compute unread DM count const unreadDmCount = dmChannels.filter((dm) => { const lastMsgId = dm.lastMessage?.id; const readState = readStates.get(dm.id); return lastMsgId && (!readState || readState < lastMsgId); }).length; // Compute whether any space has unread text channels const hasUnreadSpaces = Array.from(unreadChannels).some(chId => !voiceChannelIds.has(chId)); // Pending friend requests — filter for incoming only const pendingIncoming = requests.filter(r => r.status === 'pending' && r.fromId !== authUser?.id); const handleTab = (tab: 'spaces' | 'dms' | 'you') => { setMobileTab(tab); if (tab === 'dms') navigate('/channels/@me'); if (tab === 'spaces') { // Prefer `currentSpaceId` (the canonical "currently selected space" — // updated by URL routing, the space strip, SpaceInviteCard joins, etc.). // Fall back to `lastSelectedSpaceId`, the sticky memory that survives // navigating to `/channels/@me`. AppLayout's URL effect clears // `currentSpaceId` to null whenever the URL is `@me`; without the // sticky memory, returning to Spaces from a DM/Friends/Settings detour // would have nothing to anchor to and `MobileSpacesScreen`'s auto-select // would fall back to `spaces[0]`. const { currentSpaceId, lastSelectedSpaceId } = useSpaceStore.getState(); const target = currentSpaceId ?? lastSelectedSpaceId; if (target) navigate(`/channels/${target}`); else navigate('/'); } }; const tabs = [ { id: 'spaces' as const, label: 'Spaces', icon: ( ), badge: hasUnreadSpaces ? ('dot' as const) : null, }, { id: 'dms' as const, label: 'DMs', icon: ( ), badge: unreadDmCount > 0 ? unreadDmCount : null, }, { id: 'you' as const, label: 'You', icon: ( ), badge: pendingIncoming.length > 0 ? ('dot' as const) : null, }, ]; return ( ); }