116 lines
3.8 KiB
TypeScript
116 lines
3.8 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
CommonActions,
|
|
NavigationContainer as NavigationContainerBase,
|
|
} from '@react-navigation/native';
|
|
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
|
|
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
|
import { BottomNavigation, useTheme } from 'react-native-paper';
|
|
import { Home, Tags, Settings, AddMeme, AddTag } from './screens';
|
|
import { darkNavigationTheme, lightNavigationTheme } from './theme';
|
|
import { FloatingActionButton } from './components';
|
|
import { ROUTE } from './types';
|
|
|
|
const TabNavigator = () => {
|
|
const TabNavigatorBase = createBottomTabNavigator();
|
|
const [showFab, setShowFab] = React.useState(true);
|
|
|
|
return (
|
|
<>
|
|
<TabNavigatorBase.Navigator
|
|
screenOptions={{
|
|
headerShown: false,
|
|
}}
|
|
tabBar={({ navigation, state, descriptors, insets }) => (
|
|
<BottomNavigation.Bar
|
|
navigationState={state}
|
|
safeAreaInsets={insets}
|
|
onTabPress={({ route, preventDefault }) => {
|
|
const event = navigation.emit({
|
|
type: 'tabPress',
|
|
target: route.key,
|
|
canPreventDefault: true,
|
|
});
|
|
if (event.defaultPrevented) {
|
|
preventDefault();
|
|
} else {
|
|
navigation.dispatch({
|
|
...CommonActions.navigate(route.name, route.params),
|
|
target: state.key,
|
|
});
|
|
}
|
|
setShowFab((route.name as ROUTE) !== ROUTE.SETTINGS);
|
|
}}
|
|
renderIcon={({ route, focused, color }) => {
|
|
const { options } = descriptors[route.key];
|
|
if (options.tabBarIcon) {
|
|
return options.tabBarIcon({
|
|
focused,
|
|
color,
|
|
size: 22,
|
|
});
|
|
}
|
|
}}
|
|
getLabelText={({ route }) => {
|
|
const { options } = descriptors[route.key];
|
|
return options.title ?? route.name;
|
|
}}
|
|
/>
|
|
)}>
|
|
<TabNavigatorBase.Screen
|
|
name={ROUTE.HOME}
|
|
component={Home}
|
|
options={{
|
|
tabBarIcon: ({ color, size }) => (
|
|
<FontAwesome5 name="home" color={color} size={size} />
|
|
),
|
|
}}
|
|
/>
|
|
<TabNavigatorBase.Screen
|
|
name={ROUTE.TAGS}
|
|
component={Tags}
|
|
options={{
|
|
tabBarIcon: ({ color, size }) => (
|
|
<FontAwesome5 name="tags" color={color} size={size} />
|
|
),
|
|
}}
|
|
/>
|
|
<TabNavigatorBase.Screen
|
|
name={ROUTE.SETTINGS}
|
|
component={Settings}
|
|
options={{
|
|
tabBarIcon: ({ color, size }) => (
|
|
<FontAwesome5 name="cog" color={color} size={size} />
|
|
),
|
|
}}
|
|
/>
|
|
</TabNavigatorBase.Navigator>
|
|
<FloatingActionButton visible={showFab} />
|
|
</>
|
|
);
|
|
};
|
|
|
|
const NavigationContainer = () => {
|
|
const StackNavigatorBase = createNativeStackNavigator();
|
|
const theme = useTheme();
|
|
|
|
return (
|
|
<NavigationContainerBase
|
|
theme={theme.dark ? darkNavigationTheme : lightNavigationTheme}>
|
|
<StackNavigatorBase.Navigator
|
|
screenOptions={{
|
|
headerShown: false,
|
|
freezeOnBlur: true,
|
|
animation: 'slide_from_bottom',
|
|
}}>
|
|
<StackNavigatorBase.Screen name={ROUTE.MAIN} component={TabNavigator} />
|
|
<StackNavigatorBase.Screen name={ROUTE.ADD_MEME} component={AddMeme} />
|
|
<StackNavigatorBase.Screen name={ROUTE.ADD_TAG} component={AddTag} />
|
|
</StackNavigatorBase.Navigator>
|
|
</NavigationContainerBase>
|
|
);
|
|
};
|
|
|
|
export default NavigationContainer;
|