1de724b24b
* Get home screen's swipable pager working with the drawer * Add tab bar to pager * Implement popular & following views on home screen * Visual tune-up * Move the feed selector to the footer * Fix to 'new posts' poll * Add the view header as a feed item * Use the native driver on the tabbar indicator to improve perf * Reduce home polling to the currently active page; also reuse some code * Add soft reset on tap selected in tab bar * Remove explicit 'onboarding' flow * Choose good stuff based on service * Add foaf-based follow discovery * Fall back to who to follow * Fix backgrounds * Switch to the off-spec goodstuff route * 1.8 * Fix for dev & staging * Swap the tab bar items and rename suggested to what's hot * Go to whats-hot by default if you have no follows * Implement pager and tabbar for desktop web * Pin deps to make expo happy * Add language filtering to goodstuff
88 lines
2.2 KiB
TypeScript
88 lines
2.2 KiB
TypeScript
import React from 'react'
|
|
import {Animated, View} from 'react-native'
|
|
import PagerView, {PagerViewOnPageSelectedEvent} from 'react-native-pager-view'
|
|
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
|
|
import {s} from 'lib/styles'
|
|
|
|
export type PageSelectedEvent = PagerViewOnPageSelectedEvent
|
|
const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
|
|
|
|
export interface RenderTabBarFnProps {
|
|
selectedPage: number
|
|
position: Animated.Value
|
|
offset: Animated.Value
|
|
onSelect?: (index: number) => void
|
|
}
|
|
export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
|
|
|
|
interface Props {
|
|
tabBarPosition?: 'top' | 'bottom'
|
|
initialPage?: number
|
|
renderTabBar: RenderTabBarFn
|
|
onPageSelected?: (index: number) => void
|
|
}
|
|
export const Pager = ({
|
|
children,
|
|
tabBarPosition = 'top',
|
|
initialPage = 0,
|
|
renderTabBar,
|
|
onPageSelected,
|
|
}: React.PropsWithChildren<Props>) => {
|
|
const [selectedPage, setSelectedPage] = React.useState(0)
|
|
const position = useAnimatedValue(0)
|
|
const offset = useAnimatedValue(0)
|
|
const pagerView = React.useRef<PagerView>()
|
|
|
|
const onPageSelectedInner = React.useCallback(
|
|
(e: PageSelectedEvent) => {
|
|
setSelectedPage(e.nativeEvent.position)
|
|
onPageSelected?.(e.nativeEvent.position)
|
|
},
|
|
[setSelectedPage, onPageSelected],
|
|
)
|
|
|
|
const onTabBarSelect = React.useCallback(
|
|
(index: number) => {
|
|
pagerView.current?.setPage(index)
|
|
},
|
|
[pagerView],
|
|
)
|
|
|
|
return (
|
|
<View>
|
|
{tabBarPosition === 'top' &&
|
|
renderTabBar({
|
|
selectedPage,
|
|
position,
|
|
offset,
|
|
onSelect: onTabBarSelect,
|
|
})}
|
|
<AnimatedPagerView
|
|
ref={pagerView}
|
|
style={s.h100pct}
|
|
initialPage={initialPage}
|
|
onPageSelected={onPageSelectedInner}
|
|
onPageScroll={Animated.event(
|
|
[
|
|
{
|
|
nativeEvent: {
|
|
position: position,
|
|
offset: offset,
|
|
},
|
|
},
|
|
],
|
|
{useNativeDriver: true},
|
|
)}>
|
|
{children}
|
|
</AnimatedPagerView>
|
|
{tabBarPosition === 'bottom' &&
|
|
renderTabBar({
|
|
selectedPage,
|
|
position,
|
|
offset,
|
|
onSelect: onTabBarSelect,
|
|
})}
|
|
</View>
|
|
)
|
|
}
|