import { useNetInfo } from '@react-native-community/netinfo'; import { Tabs, useRouter } from 'expo-router'; import { useTranslation } from 'react-i18next'; import { Pressable, Text, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { player } from '../../player/controller'; import { usePlayerState } from '../../player/hooks'; import { useColors } from '../../theme'; import { Cover, Icon, type IconName } from '../../ui/kit'; import { UpdateDialog } from '../../ui/UpdateDialog'; const ICONS: Record = { index: 'home', search: 'search', collection: 'library-music', profile: 'person' }; export default function TabsLayout() { const colors = useColors(); const { t } = useTranslation(); const labels: Record = { index: t('nav.home'), search: t('mobile.search'), collection: t('nav.collection'), profile: t('mobile.profile'), }; const net = useNetInfo(); return ( <> {net.isConnected === false && } ( r.name)} active={state.index} labels={labels} onPress={(name) => navigation.navigate(name)} /> )} > ); } function TabBar({ routes, active, labels, onPress, }: { routes: string[]; active: number; labels: Record; onPress: (name: string) => void; }) { const colors = useColors(); const insets = useSafeAreaInsets(); return ( {routes.map((name, i) => { const on = i === active; return ( onPress(name)} accessibilityRole="tab" accessibilityState={{ selected: on }} accessibilityLabel={labels[name]} style={{ flex: 1, alignItems: 'center', paddingVertical: 8, gap: 2 }} > {labels[name]} ); })} ); } /** Мини-плеер над навигацией; нажатие — полноэкранный плеер. */ function MiniPlayer() { const colors = useColors(); const { t } = useTranslation(); const router = useRouter(); const st = usePlayerState(); const track = st.track; if (!track) return null; const progress = st.durationMs ? Math.min(st.positionMs / st.durationMs, 1) : 0; return ( router.push('/player')} accessibilityRole="button" accessibilityLabel={t('mobile.open_player')} style={{ backgroundColor: colors.surface, borderTopWidth: 1, borderTopColor: colors.line }} > {track.title} {track.artists.map((a) => a.name).join(', ')} player.toggle()} hitSlop={10} accessibilityRole="button" accessibilityLabel={t(st.playing ? 'player.pause' : 'player.play')}> player.next()} hitSlop={10} accessibilityRole="button" accessibilityLabel={t('player.next')}> ); } /** Нет сети: доступны «Скачанное» и офлайн-волна. */ function OfflineBanner({ text }: { text: string }) { const colors = useColors(); const insets = useSafeAreaInsets(); return ( {text} ); }