bad fix to the tab bar animation

zio/stable
Ansh Nanda 2023-05-16 17:27:46 -07:00
parent 532bc88ecc
commit 139027ac5f
2 changed files with 82 additions and 73 deletions

View File

@ -53,6 +53,7 @@ export const FeedsTabBar = observer(
<UserAvatar avatar={store.me.avatar} size={30} /> <UserAvatar avatar={store.me.avatar} size={30} />
</TouchableOpacity> </TouchableOpacity>
<TabBar <TabBar
key={store.me.savedFeeds.listOfPinnedFeedNames.join(',')}
{...props} {...props}
items={items} items={items}
indicatorPosition="bottom" indicatorPosition="bottom"

View File

@ -1,10 +1,9 @@
import React, {createRef, useState, useMemo, useRef} from 'react' import React, {createRef, useState, useMemo, useRef} from 'react'
import {Animated, StyleSheet, View} from 'react-native' import {Animated, StyleSheet, View, ScrollView} from 'react-native'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
import {PressableWithHover} from '../util/PressableWithHover' import {PressableWithHover} from '../util/PressableWithHover'
import {usePalette} from 'lib/hooks/usePalette' import {usePalette} from 'lib/hooks/usePalette'
import {isDesktopWeb} from 'platform/detection' import {isDesktopWeb} from 'platform/detection'
import {ScrollView} from 'react-native-gesture-handler'
interface Layout { interface Layout {
x: number x: number
@ -35,59 +34,71 @@ export function TabBar({
onPressSelected, onPressSelected,
}: TabBarProps) { }: TabBarProps) {
const pal = usePalette('default') const pal = usePalette('default')
// const [itemLayouts, setItemLayouts] = useState<Layout[]>( const [itemLayouts, setItemLayouts] = useState<Layout[]>(
// items.map(() => ({x: 0, width: 0})), items.map(() => ({x: 0, width: 0})),
// ) )
const itemRefs = useMemo( const itemRefs = useMemo(
() => Array.from({length: items.length}).map(() => createRef<View>()), () => Array.from({length: items.length}).map(() => createRef<View>()),
[items.length], [items.length],
) )
// const panX = Animated.add(position, offset) const panX = Animated.add(position, offset)
const containerRef = useRef<View>(null) const containerRef = useRef<View>(null)
const [scrollX, setScrollX] = useState(0)
// const indicatorStyle = { const indicatorStyle = useMemo(
// backgroundColor: indicatorColor || pal.colors.link, () => ({
// bottom: backgroundColor: indicatorColor || pal.colors.link,
// indicatorPosition === 'bottom' ? (isDesktopWeb ? 0 : -1) : undefined, bottom:
// top: indicatorPosition === 'top' ? (isDesktopWeb ? 0 : -1) : undefined, indicatorPosition === 'bottom' ? (isDesktopWeb ? 0 : -1) : undefined,
// transform: [ top: indicatorPosition === 'top' ? (isDesktopWeb ? 0 : -1) : undefined,
// { transform: [
// translateX: panX.interpolate({ {
// inputRange: items.map((_item, i) => i), translateX: panX.interpolate({
// outputRange: itemLayouts.map(l => l.x + l.width / 2), inputRange: items.map((_item, i) => i),
// }), outputRange: itemLayouts.map(l => l.x + l.width / 2 - scrollX),
// }, }),
// { },
// scaleX: panX.interpolate({ {
// inputRange: items.map((_item, i) => i), scaleX: panX.interpolate({
// outputRange: itemLayouts.map(l => l.width), inputRange: items.map((_item, i) => i),
// }), outputRange: itemLayouts.map(l => l.width),
// }, }),
// ], },
// } ],
}),
[
indicatorColor,
indicatorPosition,
itemLayouts,
items,
panX,
pal.colors.link,
scrollX,
],
)
// const onLayout = () => { const onLayout = () => {
// const promises = [] const promises = []
// for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
// promises.push( promises.push(
// new Promise<Layout>(resolve => { new Promise<Layout>(resolve => {
// if (!containerRef.current || !itemRefs[i].current) { if (!containerRef.current || !itemRefs[i].current) {
// return resolve({x: 0, width: 0}) return resolve({x: 0, width: 0})
// } }
// itemRefs[i].current?.measureLayout( itemRefs[i].current?.measureLayout(
// containerRef.current, containerRef.current,
// (x: number, _y: number, width: number) => { (x: number, _y: number, width: number) => {
// resolve({x, width}) resolve({x, width})
// }, },
// ) )
// }), }),
// ) )
// } }
// Promise.all(promises).then((layouts: Layout[]) => { Promise.all(promises).then((layouts: Layout[]) => {
// setItemLayouts(layouts) setItemLayouts(layouts)
// }) })
// } }
const onPressItem = (index: number) => { const onPressItem = (index: number) => {
onSelect?.(index) onSelect?.(index)
@ -100,31 +111,33 @@ export function TabBar({
<View <View
testID={testID} testID={testID}
style={[pal.view, styles.outer]} style={[pal.view, styles.outer]}
// onLayout={onLayout} onLayout={onLayout}
ref={containerRef}> ref={containerRef}>
<Animated.View style={[styles.indicator]} /> <Animated.View style={[styles.indicator, indicatorStyle]} />
<ScrollView horizontal={true} showsHorizontalScrollIndicator={false}> <ScrollView
horizontal={true}
showsHorizontalScrollIndicator={false}
onScroll={({nativeEvent}) => {
setScrollX(nativeEvent.contentOffset.x)
}}>
{items.map((item, i) => { {items.map((item, i) => {
const selected = i === selectedPage const selected = i === selectedPage
return ( return (
<Animated.View key={item} style={selected ? styles.active : []}> <PressableWithHover
<PressableWithHover ref={itemRefs[i]}
ref={itemRefs[i]} key={item}
style={[ style={
indicatorPosition === 'top' indicatorPosition === 'top' ? styles.itemTop : styles.itemBottom
? styles.itemTop }
: styles.itemBottom, hoverStyle={pal.viewLight}
]} onPress={() => onPressItem(i)}>
hoverStyle={pal.viewLight} <Text
onPress={() => onPressItem(i)}> type="xl-bold"
<Text testID={testID ? `${testID}-${item}` : undefined}
type="xl-bold" style={selected ? pal.text : pal.textLight}>
testID={testID ? `${testID}-${item}` : undefined} {item}
style={selected ? pal.text : pal.textLight}> </Text>
{item} </PressableWithHover>
</Text>
</PressableWithHover>
</Animated.View>
) )
})} })}
</ScrollView> </ScrollView>
@ -155,7 +168,6 @@ const styles = isDesktopWeb
height: 3, height: 3,
zIndex: 1, zIndex: 1,
}, },
active: {},
}) })
: StyleSheet.create({ : StyleSheet.create({
outer: { outer: {
@ -178,8 +190,4 @@ const styles = isDesktopWeb
width: 1, width: 1,
height: 3, height: 3,
}, },
active: {
borderBottomColor: 'blue',
borderBottomWidth: 3,
},
}) })