Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

simplify how x position is calculated for scrollTo in TabBar (#820)

authored by

Ansh and committed by
GitHub
8fde55b5 31a41d9b

+21 -35
+21 -35
src/view/com/pager/TabBar.tsx
··· 1 - import React, { 2 - useRef, 3 - createRef, 4 - useMemo, 5 - useEffect, 6 - useState, 7 - useCallback, 8 - } from 'react' 9 - import {StyleSheet, View, ScrollView} from 'react-native' 1 + import React, {useRef, useMemo, useEffect, useState, useCallback} from 'react' 2 + import {StyleSheet, View, ScrollView, LayoutChangeEvent} from 'react-native' 10 3 import {Text} from '../util/text/Text' 11 4 import {PressableWithHover} from '../util/PressableWithHover' 12 5 import {usePalette} from 'lib/hooks/usePalette' ··· 33 26 const pal = usePalette('default') 34 27 const scrollElRef = useRef<ScrollView>(null) 35 28 const [itemXs, setItemXs] = useState<number[]>([]) 36 - const itemRefs = useMemo( 37 - () => Array.from({length: items.length}).map(() => createRef<View>()), 38 - [items.length], 39 - ) 40 29 const indicatorStyle = useMemo( 41 30 () => ({borderBottomColor: indicatorColor || pal.colors.link}), 42 31 [indicatorColor, pal], 43 32 ) 44 33 34 + // scrolls to the selected item when the page changes 45 35 useEffect(() => { 46 - scrollElRef.current?.scrollTo({x: itemXs[selectedPage] || 0}) 36 + scrollElRef.current?.scrollTo({ 37 + x: itemXs[selectedPage] || 0, 38 + }) 47 39 }, [scrollElRef, itemXs, selectedPage]) 48 40 49 41 const onPressItem = useCallback( ··· 53 45 onPressSelected?.() 54 46 } 55 47 }, 56 - [onSelect, onPressSelected, selectedPage], 48 + [onSelect, selectedPage, onPressSelected], 57 49 ) 58 50 59 - const onLayout = React.useCallback(() => { 60 - const promises = [] 61 - for (let i = 0; i < items.length; i++) { 62 - promises.push( 63 - new Promise<number>(resolve => { 64 - if (!itemRefs[i].current) { 65 - return resolve(0) 66 - } 67 - 68 - itemRefs[i].current?.measure((x: number) => resolve(x)) 69 - }), 70 - ) 71 - } 72 - Promise.all(promises).then((Xs: number[]) => { 73 - setItemXs(Xs) 74 - }) 75 - }, [itemRefs, setItemXs, items.length]) 51 + // calculates the x position of each item on mount and on layout change 52 + const onItemLayout = React.useCallback( 53 + (e: LayoutChangeEvent, index: number) => { 54 + const x = e.nativeEvent.layout.x 55 + setItemXs(prev => { 56 + const Xs = [...prev] 57 + Xs[index] = x 58 + return Xs 59 + }) 60 + }, 61 + [], 62 + ) 76 63 77 64 return ( 78 65 <View testID={testID} style={[pal.view, styles.outer]}> ··· 80 67 horizontal={true} 81 68 showsHorizontalScrollIndicator={false} 82 69 ref={scrollElRef} 83 - contentContainerStyle={styles.contentContainer} 84 - onLayout={onLayout}> 70 + contentContainerStyle={styles.contentContainer}> 85 71 {items.map((item, i) => { 86 72 const selected = i === selectedPage 87 73 return ( 88 74 <PressableWithHover 89 - ref={itemRefs[i]} 90 75 key={item} 76 + onLayout={e => onItemLayout(e, i)} 91 77 style={[styles.item, selected && indicatorStyle]} 92 78 hoverStyle={pal.viewLight} 93 79 onPress={() => onPressItem(i)}>