/** * AnimatedSlot — обёртка над ``. Исторически тут была slide- * анимация при смене pathname'а + tab-swipe pan. Обе фичи вызывали * баги: * - tab-swipe конфликтовал с vertical FlatList scroll (чаты пропадали * при flick'е) * - translateX застревал на ±width когда анимация прерывалась * re-render-cascade'ом от useGlobalInbox → UI уезжал за экран * * Решение: убрали обе. Навигация между tab'ами — только через NavBar, * переходы — без slide. Sub-route back-swipe остаётся (он не конфликтует * с FlatList'ом, т.к. на chat detail FlatList inverted и смотрит вверх). */ import React, { useMemo } from 'react'; import { PanResponder, View } from 'react-native'; import { Slot, usePathname, router } from 'expo-router'; import { useWindowDimensions } from 'react-native'; function topSegment(p: string): string { const m = p.match(/^\/[^/]+/); return m ? m[0] : ''; } /** Это sub-route — внутри какого-либо tab'а, но глубже первого сегмента. */ function isSubRoute(path: string): boolean { const seg = topSegment(path); if (seg === '/chats') return path !== '/chats' && path !== '/chats/'; if (seg === '/feed') return path !== '/feed' && path !== '/feed/'; if (seg === '/profile') return true; if (seg === '/settings') return true; if (seg === '/compose') return true; return false; } export function AnimatedSlot() { const pathname = usePathname(); const { width } = useWindowDimensions(); // Pan-gesture только на sub-route'ах: swipe-right → back. На tab'ах // gesture полностью отключён — исключает конфликт с vertical scroll. const panResponder = useMemo(() => { const sub = isSubRoute(pathname); return PanResponder.create({ onMoveShouldSetPanResponder: (_e, g) => { if (!sub) return false; if (Math.abs(g.dx) < 40) return false; if (Math.abs(g.dy) > 15) return false; if (g.dx <= 0) return false; // только правое направление return Math.abs(g.dx) > Math.abs(g.dy) * 3; }, onMoveShouldSetPanResponderCapture: () => false, onPanResponderRelease: (_e, g) => { if (!sub) return; if (Math.abs(g.dy) > 30) return; if (g.dx > width * 0.30) router.back(); }, }); }, [pathname, width]); return ( ); }