import * as Notifications from 'expo-notifications'; import { Redirect, Tabs } from 'expo-router'; import { useEffect, useMemo, useState } from 'react'; import { AppState, DeviceEventEmitter } from 'react-native'; import { HapticTab } from '@/components/haptic-tab'; import { IconSymbol } from '@/components/ui/icon-symbol'; import { Colors } from '@/constants/theme'; import { useColorScheme } from '@/hooks/use-color-scheme'; import { chatApi } from '@/src/lib/chat-api'; import { useAuth } from '@/src/providers/auth-provider'; export default function TabLayout() { const colorScheme = useColorScheme(); const { activeTenantId, isBootstrapping, token, requiresTenantSelection } = useAuth(); const [communicationUnread, setCommunicationUnread] = useState(0); useEffect(() => { let active = true; let revision = 0; setCommunicationUnread(0); void Notifications.setBadgeCountAsync(0).catch(() => undefined); async function refresh() { if (!token || !activeTenantId || requiresTenantSelection || AppState.currentState !== 'active') return; const request = ++revision; try { const total = await chatApi.unread(token); if (!active || request !== revision) return; setCommunicationUnread(total); await Notifications.setBadgeCountAsync(total); } catch { /* Badge loading must not block tab navigation. */ } } void refresh(); const timer = setInterval(() => void refresh(), 30000); const foreground = AppState.addEventListener('change', state => { if (state === 'active') void refresh(); }); const changed = DeviceEventEmitter.addListener('fedeo:chat-changed', () => void refresh()); return () => { active = false; ++revision; clearInterval(timer); foreground.remove(); changed.remove(); }; }, [activeTenantId, requiresTenantSelection, token]); const communicationBadge = useMemo(() => { if (!communicationUnread) return undefined; return communicationUnread > 99 ? '99+' : communicationUnread; }, [communicationUnread]); if (isBootstrapping) { return null; } if (!token) { return ; } if (requiresTenantSelection) { return ; } return ( , }} /> , }} /> , }} /> , }} /> , }} /> , }} /> ); }