Update BottomBar for react navigation

This commit is contained in:
Paul Frazee
2023-03-09 20:43:43 -06:00
parent df4dee6db2
commit 5b3eeaf747
2 changed files with 71 additions and 66 deletions
+33 -16
View File
@@ -12,6 +12,8 @@ import {
State,
} from 'lib/routes/types'
import {BottomBar} from './shell/BottomBar'
import {HomeScreen} from './screens/Home'
import {SearchScreen} from './screens/Search'
import {NotificationsScreen} from './screens/Notifications'
@@ -167,7 +169,7 @@ function HomeDrawerNavigator() {
return (
<HomeDrawer.Navigator
drawerContent={DrawerContent}
screenOptions={{swipeEdgeWidth: 300}}>
screenOptions={{swipeEdgeWidth: 300, headerShown: false}}>
<HomeDrawer.Screen name="HomeInner" component={HomeScreen} />
</HomeDrawer.Navigator>
)
@@ -176,7 +178,11 @@ function HomeDrawerNavigator() {
function HomeStackNavigator() {
return (
<HomeStack.Navigator
screenOptions={{gestureEnabled: true, fullScreenGestureEnabled: true}}>
screenOptions={{
gestureEnabled: true,
fullScreenGestureEnabled: true,
headerShown: false,
}}>
<HomeStack.Screen name="Home" component={HomeDrawerNavigator} />
{commonScreens(HomeStack)}
</HomeStack.Navigator>
@@ -187,7 +193,7 @@ function NotificationsDrawerNavigator() {
return (
<NotificationsDrawer.Navigator
drawerContent={DrawerContent}
screenOptions={{swipeEdgeWidth: 300}}>
screenOptions={{swipeEdgeWidth: 300, headerShown: false}}>
<NotificationsDrawer.Screen
name="NotificationsInner"
component={NotificationsScreen}
@@ -199,7 +205,11 @@ function NotificationsDrawerNavigator() {
function NotificationsStackNavigator() {
return (
<NotificationsStack.Navigator
screenOptions={{gestureEnabled: true, fullScreenGestureEnabled: true}}>
screenOptions={{
gestureEnabled: true,
fullScreenGestureEnabled: true,
headerShown: false,
}}>
<NotificationsStack.Screen
name="Notifications"
component={NotificationsDrawerNavigator}
@@ -213,7 +223,7 @@ function SearchDrawerNavigator() {
return (
<SearchDrawer.Navigator
drawerContent={DrawerContent}
screenOptions={{swipeEdgeWidth: 300}}>
screenOptions={{swipeEdgeWidth: 300, headerShown: false}}>
<SearchDrawer.Screen name="SearchInner" component={SearchScreen} />
</SearchDrawer.Navigator>
)
@@ -222,7 +232,11 @@ function SearchDrawerNavigator() {
function SearchStackNavigator() {
return (
<SearchStack.Navigator
screenOptions={{gestureEnabled: true, fullScreenGestureEnabled: true}}>
screenOptions={{
gestureEnabled: true,
fullScreenGestureEnabled: true,
headerShown: false,
}}>
<SearchStack.Screen name="Search" component={SearchDrawerNavigator} />
{commonScreens(SearchStack)}
</SearchStack.Navigator>
@@ -230,17 +244,20 @@ function SearchStackNavigator() {
}
function TabsNavigator() {
const tabBar = React.useCallback(props => <BottomBar {...props} />, [])
return (
<React.Fragment>
<Tab.Navigator initialRouteName="HomeStack" backBehavior="initialRoute">
<Tab.Screen name="HomeStack" component={HomeStackNavigator} />
<Tab.Screen
name="NotificationsStack"
component={NotificationsStackNavigator}
/>
<Tab.Screen name="SearchStack" component={SearchStackNavigator} />
</Tab.Navigator>
</React.Fragment>
<Tab.Navigator
initialRouteName="HomeStack"
backBehavior="initialRoute"
screenOptions={{headerShown: false}}
tabBar={tabBar}>
<Tab.Screen name="HomeStack" component={HomeStackNavigator} />
<Tab.Screen
name="NotificationsStack"
component={NotificationsStackNavigator}
/>
<Tab.Screen name="SearchStack" component={SearchStackNavigator} />
</Tab.Navigator>
)
}
@@ -6,6 +6,8 @@ import {
TouchableOpacity,
View,
} from 'react-native'
import {StackActions} from '@react-navigation/native'
import {BottomTabBarProps} from '@react-navigation/bottom-tabs'
import {useSafeAreaInsets} from 'react-native-safe-area-context'
import {observer} from 'mobx-react-lite'
import {Text} from 'view/com/util/text/Text'
@@ -26,7 +28,15 @@ import {
import {colors} from 'lib/styles'
import {usePalette} from 'lib/hooks/usePalette'
export const BottomBar = observer(() => {
function currentRoute(state) {
let node = state.routes[state.index]
while (node.state?.routes && typeof node.state?.index === 'number') {
node = node.state?.routes[node.state?.index]
}
return node
}
export const BottomBar = observer(({navigation}: BottomTabBarProps) => {
const store = useStores()
const pal = usePalette('default')
const minimalShellInterp = useAnimatedValue(0)
@@ -54,62 +64,40 @@ export const BottomBar = observer(() => {
transform: [{translateY: Animated.multiply(minimalShellInterp, 100)}],
}
const onPressHome = React.useCallback(() => {
track('MobileShell:HomeButtonPressed')
if (store.nav.tab.fixedTabPurpose === TabPurpose.Default) {
if (!store.nav.tab.canGoBack) {
const onPressTab = React.useCallback(
(tab: string) => {
track(`MobileShell:${tab}ButtonPressed`)
const state = navigation.getState()
const curr = currentRoute(state).name
if (curr === tab || curr === `${tab}Stack`) {
store.emitScreenSoftReset()
} else if (state.routes[state.index].name === `${tab}Stack`) {
navigation.dispatch(StackActions.popToTop())
} else {
store.nav.tab.fixedTabReset()
navigation.navigate(`${tab}Stack`)
}
} else {
store.nav.switchTo(TabPurpose.Default, false)
if (store.nav.tab.index === 0) {
store.nav.tab.fixedTabReset()
}
}
}, [store, track])
const onPressSearch = React.useCallback(() => {
track('MobileShell:SearchButtonPressed')
if (store.nav.tab.fixedTabPurpose === TabPurpose.Search) {
if (!store.nav.tab.canGoBack) {
store.emitScreenSoftReset()
} else {
store.nav.tab.fixedTabReset()
}
} else {
store.nav.switchTo(TabPurpose.Search, false)
if (store.nav.tab.index === 0) {
store.nav.tab.fixedTabReset()
}
}
}, [store, track])
const onPressNotifications = React.useCallback(() => {
track('MobileShell:NotificationsButtonPressed')
if (store.nav.tab.fixedTabPurpose === TabPurpose.Notifs) {
if (!store.nav.tab.canGoBack) {
store.emitScreenSoftReset()
} else {
store.nav.tab.fixedTabReset()
}
} else {
store.nav.switchTo(TabPurpose.Notifs, false)
if (store.nav.tab.index === 0) {
store.nav.tab.fixedTabReset()
}
}
}, [store, track])
},
[store, track, navigation],
)
const onPressHome = React.useCallback(() => onPressTab('Home'), [onPressTab])
const onPressSearch = React.useCallback(
() => onPressTab('Search'),
[onPressTab],
)
const onPressNotifications = React.useCallback(
() => onPressTab('Notifications'),
[onPressTab],
)
const onPressProfile = React.useCallback(() => {
track('MobileShell:ProfileButtonPressed')
store.nav.navigate(`/profile/${store.me.handle}`)
}, [store, track])
navigation.navigate('Profile', {name: store.me.handle})
}, [navigation, track, store.me.handle])
const isAtHome =
store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Default]
const isAtSearch =
store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Search]
const curr = currentRoute(navigation.getState()).name
const isAtHome = curr === 'HomeStack' || curr === 'Home'
const isAtSearch = curr === 'SearchStack' || curr === 'Search'
const isAtNotifications =
store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Notifs]
curr === 'NotificationsStack' || curr === 'Notifications'
return (
<Animated.View