diff --git a/src/view/com/pager/FeedsTabBarMobile.tsx b/src/view/com/pager/FeedsTabBarMobile.tsx index d0893ebd5e..883cde5be6 100644 --- a/src/view/com/pager/FeedsTabBarMobile.tsx +++ b/src/view/com/pager/FeedsTabBarMobile.tsx @@ -87,6 +87,7 @@ export const FeedsTabBar = observer(function FeedsTabBarImpl( testID={props.testID} items={items} dragProgress={props.dragProgress} + dragState={props.dragState} indicatorColor={pal.colors.link} /> diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx index d9017fbadf..480969906a 100644 --- a/src/view/com/pager/Pager.tsx +++ b/src/view/com/pager/Pager.tsx @@ -34,6 +34,7 @@ export const Pager = forwardRef>( initialPage = 0, renderTabBar, onPageScroll, + onPageScrollStateChanged, onPageSelected, testID, }: React.PropsWithChildren, @@ -74,7 +75,8 @@ export const Pager = forwardRef>( style={s.h100pct} initialPage={initialPage} onPageSelected={onPageSelectedInner} - onPageScroll={handlePageScroll}> + onPageScroll={handlePageScroll} + onPageScrollStateChanged={onPageScrollStateChanged}> {children} {tabBarPosition === 'bottom' && diff --git a/src/view/com/pager/TabBar.tsx b/src/view/com/pager/TabBar.tsx index b7f036d43d..9b0bb08816 100644 --- a/src/view/com/pager/TabBar.tsx +++ b/src/view/com/pager/TabBar.tsx @@ -1,4 +1,4 @@ -import React, {useMemo, useCallback, useState} from 'react' +import React, {useMemo, useCallback, useEffect, useState} from 'react' import Animated, {useAnimatedReaction, useAnimatedRef, useAnimatedStyle, useDerivedValue, useSharedValue, measure, interpolate, interpolateColor, scrollTo, withSpring} from 'react-native-reanimated' import {Dimensions, StyleSheet, View, ScrollView} from 'react-native' import {PressableWithHover} from '../util/PressableWithHover' @@ -22,6 +22,7 @@ const SCREEN = Dimensions.get('screen') export function TabBar({ testID, dragProgress, + dragState, selectedPage, items, indicatorColor, @@ -33,6 +34,7 @@ export function TabBar({ const scrollElRef = useAnimatedRef(null) const {isDesktop, isTablet} = useWebMediaQueries() const [layouts, setLayouts] = useState([]) + const shouldSync = useSharedValue(true) const indicatorStyle = useAnimatedStyle(() => { if (layouts.length < items.length - 1 || layouts.some(l => l === undefined)) { @@ -57,11 +59,21 @@ export function TabBar({ useAnimatedReaction(() => { return (dragProgress.value / (items.length - 1)) * (contentSize.value - SCREEN.width) }, (nextX, prevX) => { - if (prevX !== nextX) { + if (shouldSync.value && prevX !== nextX) { scrollTo(scrollElRef, nextX, 0, false); } }) + useAnimatedReaction(() => { + return dragState.value + }, (nextDragState, prevDragState) => { + if (nextDragState === 'idle' && nextDragState !== prevDragState) { + const nextX = (dragProgress.value / (items.length - 1)) * (contentSize.value - SCREEN.width) + scrollTo(scrollElRef, nextX, 0, true); + shouldSync.value = true + } + }) + const onItemLayout = (e: LayoutChangeEvent, index: number) => { const l = e.nativeEvent.layout setLayouts(ls => items.map((item, i) => { @@ -84,6 +96,9 @@ export function TabBar({ contentContainerStyle={styles.contentContainer} onContentSizeChange={e => { contentSize.value = e + }} + onScrollBeginDrag={e => { + shouldSync.value = false }}> {items.map((item, i) => { return ( diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx index 9c9de982cf..555f27c0d3 100644 --- a/src/view/screens/Home.tsx +++ b/src/view/screens/Home.tsx @@ -30,6 +30,7 @@ export const HomeScreen = withAuthRequired( string[] >([]) const dragProgress = useSharedValue(selectedPage) + const dragState = useSharedValue('idle') React.useEffect(() => { const {pinned} = store.me.savedFeeds @@ -90,6 +91,10 @@ export const HomeScreen = withAuthRequired( [dragProgress], ) + const onPageScrollStateChanged = React.useCallback(e => { + dragState.value = e.nativeEvent.pageScrollState + }) + const onPressSelected = React.useCallback(() => { store.emitScreenSoftReset() }, [store]) @@ -102,6 +107,7 @@ export const HomeScreen = withAuthRequired( selectedPage={props.selectedPage} onSelect={props.onSelect} dragProgress={dragProgress} + dragState={dragState} testID="homeScreenFeedTabs" onPressSelected={onPressSelected} /> @@ -124,6 +130,7 @@ export const HomeScreen = withAuthRequired( testID="homeScreen" onPageSelected={onPageSelected} onPageScroll={onPageScroll} + onPageScrollStateChanged={onPageScrollStateChanged} renderTabBar={renderTabBar} tabBarPosition="top">