Cleanup and First Small Changes
This commit is contained in:
parent
739e5e8f08
commit
59696b2caf
18 changed files with 39 additions and 475 deletions
|
|
@ -1,55 +0,0 @@
|
||||||
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
|
||||||
import { Link, Tabs } from 'expo-router';
|
|
||||||
import { Pressable, useColorScheme } from 'react-native';
|
|
||||||
|
|
||||||
import Colors from '../../constants/Colors';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
|
|
||||||
*/
|
|
||||||
function TabBarIcon(props: {
|
|
||||||
name: React.ComponentProps<typeof FontAwesome>['name'];
|
|
||||||
color: string;
|
|
||||||
}) {
|
|
||||||
return <FontAwesome size={28} style={{ marginBottom: -3 }} {...props} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function TabLayout() {
|
|
||||||
const colorScheme = useColorScheme();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Tabs
|
|
||||||
screenOptions={{
|
|
||||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
|
||||||
}}>
|
|
||||||
<Tabs.Screen
|
|
||||||
name="index"
|
|
||||||
options={{
|
|
||||||
title: 'Tab One',
|
|
||||||
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
|
|
||||||
headerRight: () => (
|
|
||||||
<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
|
|
||||||
name="two"
|
|
||||||
options={{
|
|
||||||
title: 'Tab Two',
|
|
||||||
tabBarIcon: ({ color }) => <TabBarIcon name="code" color={color} />,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tabs>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import EditScreenInfo from '../../components/EditScreenInfo';
|
|
||||||
import { Text, View } from '../../components/Themed';
|
|
||||||
|
|
||||||
export default function TabOneScreen() {
|
|
||||||
return (
|
|
||||||
<View style={styles.container}>
|
|
||||||
<Text style={styles.title}>Tab One</Text>
|
|
||||||
<View style={styles.separator} lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
|
|
||||||
<EditScreenInfo path="app/(tabs)/index.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%',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import EditScreenInfo from '../../components/EditScreenInfo';
|
|
||||||
import { Text, View } from '../../components/Themed';
|
|
||||||
|
|
||||||
export default function TabTwoScreen() {
|
|
||||||
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%',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
import { ScrollViewStyleReset } from 'expo-router/html';
|
|
||||||
|
|
||||||
// This file is web-only and used to configure the root HTML for every
|
|
||||||
// web page during static rendering.
|
|
||||||
// The contents of this function only run in Node.js environments and
|
|
||||||
// do not have access to the DOM or browser APIs.
|
|
||||||
export default function Root({ children }: { children: React.ReactNode }) {
|
|
||||||
return (
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charSet="utf-8" />
|
|
||||||
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
|
|
||||||
|
|
||||||
{/*
|
|
||||||
This viewport disables scaling which makes the mobile website act more like a native app.
|
|
||||||
However this does reduce built-in accessibility. If you want to enable scaling, use this instead:
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
||||||
*/}
|
|
||||||
<meta
|
|
||||||
name="viewport"
|
|
||||||
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover"
|
|
||||||
/>
|
|
||||||
{/*
|
|
||||||
Disable body scrolling on web. This makes ScrollView components work closer to how they do on native.
|
|
||||||
However, body scrolling is often nice to have for mobile web. If you want to enable it, remove this line.
|
|
||||||
*/}
|
|
||||||
<ScrollViewStyleReset />
|
|
||||||
|
|
||||||
{/* Using raw CSS styles as an escape-hatch to ensure the background color never flickers in dark-mode. */}
|
|
||||||
<style dangerouslySetInnerHTML={{ __html: responsiveBackground }} />
|
|
||||||
{/* Add any additional <head> elements that you want globally available on web... */}
|
|
||||||
</head>
|
|
||||||
<body>{children}</body>
|
|
||||||
</html>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const responsiveBackground = `
|
|
||||||
body {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
body {
|
|
||||||
background-color: #000;
|
|
||||||
}
|
|
||||||
}`;
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
import { Link, Stack } from 'expo-router';
|
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import { Text, View } from '../components/Themed';
|
|
||||||
|
|
||||||
export default function NotFoundScreen() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Stack.Screen options={{ title: 'Oops!' }} />
|
|
||||||
<View style={styles.container}>
|
|
||||||
<Text style={styles.title}>This screen doesn't exist.</Text>
|
|
||||||
|
|
||||||
<Link href="/" style={styles.link}>
|
|
||||||
<Text style={styles.linkText}>Go to home screen!</Text>
|
|
||||||
</Link>
|
|
||||||
</View>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
padding: 20,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
link: {
|
|
||||||
marginTop: 15,
|
|
||||||
paddingVertical: 15,
|
|
||||||
},
|
|
||||||
linkText: {
|
|
||||||
fontSize: 14,
|
|
||||||
color: '#2e78b7',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
@ -1,56 +1,12 @@
|
||||||
import FontAwesome from '@expo/vector-icons/FontAwesome';
|
import { Tabs } from 'expo-router/tabs';
|
||||||
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
|
import {HeaderTitle} from "@react-navigation/elements";
|
||||||
import { useFonts } from 'expo-font';
|
|
||||||
import { SplashScreen, Stack } from 'expo-router';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
import { useColorScheme } from 'react-native';
|
|
||||||
|
|
||||||
export {
|
|
||||||
// Catch any errors thrown by the Layout component.
|
|
||||||
ErrorBoundary,
|
|
||||||
} from 'expo-router';
|
|
||||||
|
|
||||||
export const unstable_settings = {
|
|
||||||
// Ensure that reloading on `/modal` keeps a back button present.
|
|
||||||
initialRouteName: '(tabs)',
|
|
||||||
};
|
|
||||||
|
|
||||||
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
|
||||||
SplashScreen.preventAutoHideAsync();
|
|
||||||
|
|
||||||
export default function RootLayout() {
|
|
||||||
const [loaded, error] = useFonts({
|
|
||||||
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
|
||||||
...FontAwesome.font,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Expo Router uses Error Boundaries to catch errors in the navigation tree.
|
|
||||||
useEffect(() => {
|
|
||||||
if (error) throw error;
|
|
||||||
}, [error]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (loaded) {
|
|
||||||
SplashScreen.hideAsync();
|
|
||||||
}
|
|
||||||
}, [loaded]);
|
|
||||||
|
|
||||||
if (!loaded) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <RootLayoutNav />;
|
|
||||||
}
|
|
||||||
|
|
||||||
function RootLayoutNav() {
|
|
||||||
const colorScheme = useColorScheme();
|
|
||||||
|
|
||||||
|
export default function Layout() {
|
||||||
return (
|
return (
|
||||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
<Tabs>
|
||||||
<Stack>
|
<Tabs.Screen name="budget" options={{tabBarShowLabel: false}}/>
|
||||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
<Tabs.Screen name="index" />
|
||||||
<Stack.Screen name="modal" options={{ presentation: 'modal' }} />
|
<Tabs.Screen name="stats" />
|
||||||
</Stack>
|
</Tabs>
|
||||||
</ThemeProvider>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
5
app/budget.tsx
Normal file
5
app/budget.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { Text } from 'react-native';
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return <Text>Budget Page</Text>;
|
||||||
|
}
|
||||||
19
app/index.tsx
Normal file
19
app/index.tsx
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { Text, StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<Text style={styles.lightThemeText}>Home Page</Text>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
lightThemeText: {
|
||||||
|
color: "#242c40"
|
||||||
|
},
|
||||||
|
darkThemeText: {
|
||||||
|
color: "#d0d0c0"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
import { StatusBar } from 'expo-status-bar';
|
|
||||||
import { Platform, StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import EditScreenInfo from '../components/EditScreenInfo';
|
|
||||||
import { Text, View } from '../components/Themed';
|
|
||||||
|
|
||||||
export default function ModalScreen() {
|
|
||||||
return (
|
|
||||||
<View style={styles.container}>
|
|
||||||
<Text style={styles.title}>Modal</Text>
|
|
||||||
<View style={styles.separator} lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
|
|
||||||
<EditScreenInfo path="app/modal.tsx" />
|
|
||||||
|
|
||||||
{/* Use a light status bar on iOS to account for the black space above the modal */}
|
|
||||||
<StatusBar style={Platform.OS === 'ios' ? 'light' : 'auto'} />
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
fontSize: 20,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
},
|
|
||||||
separator: {
|
|
||||||
marginVertical: 30,
|
|
||||||
height: 1,
|
|
||||||
width: '80%',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
5
app/stats.tsx
Normal file
5
app/stats.tsx
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { Text } from 'react-native';
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
return <Text>Stats Page</Text>;
|
||||||
|
}
|
||||||
BIN
assets/images/splash-template.png
Normal file
BIN
assets/images/splash-template.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 259 KiB |
|
|
@ -1,77 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import { StyleSheet } from 'react-native';
|
|
||||||
|
|
||||||
import Colors from '../constants/Colors';
|
|
||||||
import { ExternalLink } from './ExternalLink';
|
|
||||||
import { MonoText } from './StyledText';
|
|
||||||
import { Text, View } from './Themed';
|
|
||||||
|
|
||||||
|
|
||||||
export default function EditScreenInfo({ path }: { path: string }) {
|
|
||||||
return (
|
|
||||||
<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({
|
|
||||||
getStartedContainer: {
|
|
||||||
alignItems: 'center',
|
|
||||||
marginHorizontal: 50,
|
|
||||||
},
|
|
||||||
homeScreenFilename: {
|
|
||||||
marginVertical: 7,
|
|
||||||
},
|
|
||||||
codeHighlightContainer: {
|
|
||||||
borderRadius: 3,
|
|
||||||
paddingHorizontal: 4,
|
|
||||||
},
|
|
||||||
getStartedText: {
|
|
||||||
fontSize: 17,
|
|
||||||
lineHeight: 24,
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
helpContainer: {
|
|
||||||
marginTop: 15,
|
|
||||||
marginHorizontal: 20,
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
helpLink: {
|
|
||||||
paddingVertical: 15,
|
|
||||||
},
|
|
||||||
helpLinkText: {
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
import { Link } from 'expo-router';
|
|
||||||
import * as WebBrowser from 'expo-web-browser';
|
|
||||||
import React from 'react';
|
|
||||||
import { Platform } from 'react-native';
|
|
||||||
|
|
||||||
export function ExternalLink(
|
|
||||||
props: Omit<React.ComponentProps<typeof Link>, 'href'> & { href: string }
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
hrefAttrs={{
|
|
||||||
// On web, launch the link in a new tab.
|
|
||||||
target: '_blank',
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
// @ts-expect-error: External URLs are not typed.
|
|
||||||
href={props.href}
|
|
||||||
onPress={(e) => {
|
|
||||||
if (Platform.OS !== 'web') {
|
|
||||||
// Prevent the default behavior of linking to the default browser on native.
|
|
||||||
e.preventDefault();
|
|
||||||
// Open the link in an in-app browser.
|
|
||||||
WebBrowser.openBrowserAsync(props.href as string);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
import { Text, TextProps } from './Themed';
|
|
||||||
|
|
||||||
export function MonoText(props: TextProps) {
|
|
||||||
return <Text {...props} style={[props.style, { fontFamily: 'SpaceMono' }]} />;
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
/**
|
|
||||||
* Learn more about Light and Dark modes:
|
|
||||||
* https://docs.expo.io/guides/color-schemes/
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Text as DefaultText, useColorScheme, View as DefaultView } from 'react-native';
|
|
||||||
|
|
||||||
import Colors from '../constants/Colors';
|
|
||||||
|
|
||||||
type ThemeProps = {
|
|
||||||
lightColor?: string;
|
|
||||||
darkColor?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TextProps = ThemeProps & DefaultText['props'];
|
|
||||||
export type ViewProps = ThemeProps & DefaultView['props'];
|
|
||||||
|
|
||||||
export function useThemeColor(
|
|
||||||
props: { light?: string; dark?: string },
|
|
||||||
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
|
|
||||||
) {
|
|
||||||
const theme = useColorScheme() ?? 'light';
|
|
||||||
const colorFromProps = props[theme];
|
|
||||||
|
|
||||||
if (colorFromProps) {
|
|
||||||
return colorFromProps;
|
|
||||||
} else {
|
|
||||||
return Colors[theme][colorName];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Text(props: TextProps) {
|
|
||||||
const { style, lightColor, darkColor, ...otherProps } = props;
|
|
||||||
const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
|
|
||||||
|
|
||||||
return <DefaultText style={[{ color }, style]} {...otherProps} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function View(props: ViewProps) {
|
|
||||||
const { style, lightColor, darkColor, ...otherProps } = props;
|
|
||||||
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
|
|
||||||
|
|
||||||
return <DefaultView style={[{ backgroundColor }, style]} {...otherProps} />;
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
import * as React from 'react';
|
|
||||||
import renderer from 'react-test-renderer';
|
|
||||||
|
|
||||||
import { MonoText } from '../StyledText';
|
|
||||||
|
|
||||||
it(`renders correctly`, () => {
|
|
||||||
const tree = renderer.create(<MonoText>Snapshot test!</MonoText>).toJSON();
|
|
||||||
|
|
||||||
expect(tree).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
const tintColorLight = '#2f95dc';
|
|
||||||
const tintColorDark = '#fff';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
light: {
|
|
||||||
text: '#000',
|
|
||||||
background: '#fff',
|
|
||||||
tint: tintColorLight,
|
|
||||||
tabIconDefault: '#ccc',
|
|
||||||
tabIconSelected: tintColorLight,
|
|
||||||
},
|
|
||||||
dark: {
|
|
||||||
text: '#fff',
|
|
||||||
background: '#000',
|
|
||||||
tint: tintColorDark,
|
|
||||||
tabIconDefault: '#ccc',
|
|
||||||
tabIconSelected: tintColorDark,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
Reference in a new issue