mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 16:33:26 +00:00
[feat] tabs added
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"singleQuote": true
|
"singleQuote": true,
|
||||||
|
"endOfLine": "auto"
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,12 @@ module.exports = {
|
|||||||
'react/react-in-jsx-scope': 'off',
|
'react/react-in-jsx-scope': 'off',
|
||||||
'react/require-default-props': 'off',
|
'react/require-default-props': 'off',
|
||||||
'react/destructuring-assignment': 'off',
|
'react/destructuring-assignment': 'off',
|
||||||
|
'prettier/prettier': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
endOfLine: 'auto',
|
||||||
|
},
|
||||||
|
],
|
||||||
'react/jsx-filename-extension': [
|
'react/jsx-filename-extension': [
|
||||||
'error',
|
'error',
|
||||||
{ extensions: ['.js', '.tsx', '.jsx'] },
|
{ extensions: ['.js', '.tsx', '.jsx'] },
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
||||||
import { Link, Tabs } from 'expo-router';
|
import { Tabs } from 'expo-router';
|
||||||
import { Pressable, useColorScheme } from 'react-native';
|
import { StyleProp, TextStyle } from 'react-native';
|
||||||
|
|
||||||
import Colors from '../../constants/Colors';
|
import Colors from '../../constants/Colors';
|
||||||
|
|
||||||
@@ -9,46 +9,112 @@ import Colors from '../../constants/Colors';
|
|||||||
*/
|
*/
|
||||||
function TabBarIcon(props: {
|
function TabBarIcon(props: {
|
||||||
name: React.ComponentProps<typeof FontAwesome>['name'];
|
name: React.ComponentProps<typeof FontAwesome>['name'];
|
||||||
color: string;
|
color?: string;
|
||||||
|
focused?: boolean;
|
||||||
|
style?: StyleProp<TextStyle>;
|
||||||
}) {
|
}) {
|
||||||
return <FontAwesome size={28} style={{ marginBottom: -3 }} {...props} />;
|
return (
|
||||||
|
<FontAwesome
|
||||||
|
color={
|
||||||
|
props.color ||
|
||||||
|
(props.focused ? Colors.dark.purple300 : Colors.dark.shade300)
|
||||||
|
}
|
||||||
|
size={24}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TabLayout() {
|
export default function TabLayout() {
|
||||||
const colorScheme = useColorScheme();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
|
sceneContainerStyle={{
|
||||||
|
backgroundColor: '#000',
|
||||||
|
}}
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
headerShown: false,
|
||||||
|
tabBarActiveTintColor: Colors.dark.purple100,
|
||||||
|
tabBarStyle: {
|
||||||
|
backgroundColor: Colors.dark.shade700,
|
||||||
|
borderTopColor: 'transparent',
|
||||||
|
borderTopRightRadius: 20,
|
||||||
|
borderTopLeftRadius: 20,
|
||||||
|
height: 80,
|
||||||
|
},
|
||||||
|
tabBarItemStyle: {
|
||||||
|
paddingVertical: 18,
|
||||||
|
height: 82,
|
||||||
|
},
|
||||||
|
tabBarLabelStyle: {
|
||||||
|
marginTop: 2,
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="index"
|
name="index"
|
||||||
options={{
|
options={{
|
||||||
title: 'Tab One',
|
title: 'Home',
|
||||||
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
|
tabBarIcon: ({ focused }) => (
|
||||||
headerRight: () => (
|
<TabBarIcon name="home" focused={focused} />
|
||||||
<Link href="/modal" asChild>
|
|
||||||
<Pressable>
|
|
||||||
{({ pressed }) => (
|
|
||||||
<FontAwesome
|
|
||||||
name="info-circle"
|
|
||||||
size={25}
|
|
||||||
color={Colors[colorScheme ?? 'light'].text}
|
|
||||||
style={{ marginRight: 15, opacity: pressed ? 0.5 : 1 }}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Pressable>
|
|
||||||
</Link>
|
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="two"
|
name="about"
|
||||||
options={{
|
options={{
|
||||||
title: 'Tab Two',
|
title: 'About',
|
||||||
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
|
tabBarIcon: ({ focused }) => (
|
||||||
|
<TabBarIcon name="500px" focused={focused} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="search"
|
||||||
|
options={{
|
||||||
|
title: 'Search',
|
||||||
|
tabBarLabel: 'test',
|
||||||
|
tabBarShowLabel: false,
|
||||||
|
tabBarLabelStyle: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
tabBarIconStyle: {},
|
||||||
|
tabBarIcon: () => (
|
||||||
|
<TabBarIcon
|
||||||
|
style={{
|
||||||
|
position: 'relative',
|
||||||
|
top: -1,
|
||||||
|
backgroundColor: Colors.dark.purple400,
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
aspectRatio: 1,
|
||||||
|
borderRadius: 100,
|
||||||
|
textAlign: 'center',
|
||||||
|
textAlignVertical: 'center',
|
||||||
|
height: 56,
|
||||||
|
}}
|
||||||
|
name="search"
|
||||||
|
color="#FFF"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="settings"
|
||||||
|
options={{
|
||||||
|
title: 'Settings',
|
||||||
|
tabBarIcon: ({ focused }) => (
|
||||||
|
<TabBarIcon name="cog" focused={focused} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Tabs.Screen
|
||||||
|
name="account"
|
||||||
|
options={{
|
||||||
|
title: 'Account',
|
||||||
|
tabBarIcon: ({ focused }) => (
|
||||||
|
<TabBarIcon name="user" focused={focused} />
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
30
apps/mobile/app/(tabs)/account.tsx
Normal file
30
apps/mobile/app/(tabs)/account.tsx
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import EditScreenInfo from '../../components/EditScreenInfo';
|
||||||
|
import { Text, View } from '../../components/Themed';
|
||||||
|
|
||||||
|
export default function AccountScreen() {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text>Home</Text>
|
||||||
|
<EditScreenInfo path="app/(tabs)/two.tsx" />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
separator: {
|
||||||
|
marginVertical: 30,
|
||||||
|
height: 1,
|
||||||
|
width: '80%',
|
||||||
|
},
|
||||||
|
});
|
@@ -2,17 +2,12 @@ import { StyleSheet } from 'react-native';
|
|||||||
|
|
||||||
import EditScreenInfo from '../../components/EditScreenInfo';
|
import EditScreenInfo from '../../components/EditScreenInfo';
|
||||||
import { Text, View } from '../../components/Themed';
|
import { Text, View } from '../../components/Themed';
|
||||||
|
import Colors from '../../constants/Colors';
|
||||||
|
|
||||||
export default function TabOneScreen() {
|
export default function TabOneScreen() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.title}>Tab One</Text>
|
<Text>Home</Text>
|
||||||
<View
|
|
||||||
style={styles.separator}
|
|
||||||
lightColor="#eee"
|
|
||||||
darkColor="rgba(255,255,255,0.1)"
|
|
||||||
/>
|
|
||||||
<EditScreenInfo path="app/(tabs)/index.tsx" />
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -21,6 +16,7 @@ const styles = StyleSheet.create({
|
|||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
backgroundColor: Colors.dark.shade900,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
|
35
apps/mobile/app/(tabs)/search.tsx
Normal file
35
apps/mobile/app/(tabs)/search.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import EditScreenInfo from '../../components/EditScreenInfo';
|
||||||
|
import { Text, View } from '../../components/Themed';
|
||||||
|
|
||||||
|
export default function SearchScreen() {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.title}>Tab Two</Text>
|
||||||
|
<View
|
||||||
|
style={styles.separator}
|
||||||
|
lightColor="#eee"
|
||||||
|
darkColor="rgba(255,255,255,0.1)"
|
||||||
|
/>
|
||||||
|
<EditScreenInfo path="app/(tabs)/two.tsx" />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
separator: {
|
||||||
|
marginVertical: 30,
|
||||||
|
height: 1,
|
||||||
|
width: '80%',
|
||||||
|
},
|
||||||
|
});
|
35
apps/mobile/app/(tabs)/settings.tsx
Normal file
35
apps/mobile/app/(tabs)/settings.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import EditScreenInfo from '../../components/EditScreenInfo';
|
||||||
|
import { Text, View } from '../../components/Themed';
|
||||||
|
|
||||||
|
export default function SettingsScreen() {
|
||||||
|
return (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<Text style={styles.title}>Tab Two</Text>
|
||||||
|
<View
|
||||||
|
style={styles.separator}
|
||||||
|
lightColor="#eee"
|
||||||
|
darkColor="rgba(255,255,255,0.1)"
|
||||||
|
/>
|
||||||
|
<EditScreenInfo path="app/(tabs)/two.tsx" />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
},
|
||||||
|
separator: {
|
||||||
|
marginVertical: 30,
|
||||||
|
height: 1,
|
||||||
|
width: '80%',
|
||||||
|
},
|
||||||
|
});
|
@@ -9,6 +9,8 @@ import { SplashScreen, Stack } from 'expo-router';
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useColorScheme } from 'react-native';
|
import { useColorScheme } from 'react-native';
|
||||||
|
|
||||||
|
import Colors from '../constants/Colors';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
// Catch any errors thrown by the Layout component.
|
// Catch any errors thrown by the Layout component.
|
||||||
ErrorBoundary,
|
ErrorBoundary,
|
||||||
@@ -53,7 +55,15 @@ function RootLayoutNav() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||||
<Stack>
|
<Stack
|
||||||
|
screenOptions={{
|
||||||
|
gestureEnabled: true,
|
||||||
|
headerShown: false,
|
||||||
|
contentStyle: {
|
||||||
|
backgroundColor: Colors.dark.shade900,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||||
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
|
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@@ -7,48 +7,7 @@ import { Text, View } from './Themed';
|
|||||||
import Colors from '../constants/Colors';
|
import Colors from '../constants/Colors';
|
||||||
|
|
||||||
export default function EditScreenInfo({ path }: { path: string }) {
|
export default function EditScreenInfo({ path }: { path: string }) {
|
||||||
return (
|
return <View />;
|
||||||
<View>
|
|
||||||
<View style={styles.getStartedContainer}>
|
|
||||||
<Text
|
|
||||||
style={styles.getStartedText}
|
|
||||||
lightColor="rgba(0,0,0,0.8)"
|
|
||||||
darkColor="rgba(255,255,255,0.8)"
|
|
||||||
>
|
|
||||||
Open up the code for this screen:
|
|
||||||
</Text>
|
|
||||||
|
|
||||||
<View
|
|
||||||
style={[styles.codeHighlightContainer, styles.homeScreenFilename]}
|
|
||||||
darkColor="rgba(255,255,255,0.05)"
|
|
||||||
lightColor="rgba(0,0,0,0.05)"
|
|
||||||
>
|
|
||||||
<MonoText>{path}</MonoText>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<Text
|
|
||||||
style={styles.getStartedText}
|
|
||||||
lightColor="rgba(0,0,0,0.8)"
|
|
||||||
darkColor="rgba(255,255,255,0.8)"
|
|
||||||
>
|
|
||||||
Change any of the text, save the file, and your app will automatically
|
|
||||||
update.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View style={styles.helpContainer}>
|
|
||||||
<ExternalLink
|
|
||||||
style={styles.helpLink}
|
|
||||||
href="https://docs.expo.io/get-started/create-a-new-app/#opening-the-app-on-your-phonetablet"
|
|
||||||
>
|
|
||||||
<Text style={styles.helpLinkText} lightColor={Colors.light.tint}>
|
|
||||||
Tap here if your app doesn't automatically update after making
|
|
||||||
changes
|
|
||||||
</Text>
|
|
||||||
</ExternalLink>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
|
19
apps/mobile/components/TabBar.tsx
Normal file
19
apps/mobile/components/TabBar.tsx
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
|
|
||||||
|
export default function TabBar() {
|
||||||
|
return (
|
||||||
|
<View style={styles.wrapper}>
|
||||||
|
<Text>First Tab</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
wrapper: {
|
||||||
|
backgroundColor: '#131322',
|
||||||
|
paddingVertical: 24,
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
},
|
||||||
|
});
|
@@ -15,5 +15,13 @@ export default {
|
|||||||
tint: tintColorDark,
|
tint: tintColorDark,
|
||||||
tabIconDefault: '#ccc',
|
tabIconDefault: '#ccc',
|
||||||
tabIconSelected: tintColorDark,
|
tabIconSelected: tintColorDark,
|
||||||
|
purple100: '#C082FF',
|
||||||
|
purple300: '#8D44D6',
|
||||||
|
purple400: '#7831BF',
|
||||||
|
shade50: '#676790',
|
||||||
|
shade200: '#3F3F60',
|
||||||
|
shade300: '#32324F',
|
||||||
|
shade700: '#131322',
|
||||||
|
shade900: '#0A0A12',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
13918
apps/mobile/package-lock.json
generated
Normal file
13918
apps/mobile/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user