commit 13155a0e6993d47560a6ee23f8f70190e903901c
parent d252ca32d1b200bf985d217ba338f5a1c8f7f74e
Author: Blubfish <101827184+Blubfish@users.noreply.github.com>
Date: Tue, 24 Jun 2025 15:51:43 -0500
Add expo app, add splash, add icon, add safeAreaView, add Status bar
Diffstat:
35 files changed, 125 insertions(+), 840 deletions(-)
diff --git a/.expo/README.md b/.expo/README.md
@@ -0,0 +1,8 @@
+> Why do I have a folder named ".expo" in my project?
+The ".expo" folder is created when an Expo project is started using "expo start" command.
+> What do the files contain?
+- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
+- "settings.json": contains the server configuration that is used to serve the application manifest.
+> Should I commit the ".expo" folder?
+No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
+Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
diff --git a/.expo/devices.json b/.expo/devices.json
@@ -0,0 +1,3 @@
+{
+ "devices": []
+}
diff --git a/.expo/types/router.d.ts b/.expo/types/router.d.ts
@@ -0,0 +1,14 @@
+/* eslint-disable */
+import * as Router from 'expo-router';
+
+export * from 'expo-router';
+
+declare module 'expo-router' {
+ export namespace ExpoRouter {
+ export interface __routes<T extends string | object = string> {
+ hrefInputParams: { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/`; params?: Router.UnknownInputParams; } | { pathname: `/about`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | { pathname: `/+not-found`, params: Router.UnknownInputParams & { } };
+ hrefOutputParams: { pathname: Router.RelativePathString, params?: Router.UnknownOutputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownOutputParams } | { pathname: `/`; params?: Router.UnknownOutputParams; } | { pathname: `/about`; params?: Router.UnknownOutputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownOutputParams; } | { pathname: `/+not-found`, params: Router.UnknownOutputParams & { } };
+ href: Router.RelativePathString | Router.ExternalPathString | `/${`?${string}` | `#${string}` | ''}` | `/about${`?${string}` | `#${string}` | ''}` | `/_sitemap${`?${string}` | `#${string}` | ''}` | { pathname: Router.RelativePathString, params?: Router.UnknownInputParams } | { pathname: Router.ExternalPathString, params?: Router.UnknownInputParams } | { pathname: `/`; params?: Router.UnknownInputParams; } | { pathname: `/about`; params?: Router.UnknownInputParams; } | { pathname: `/_sitemap`; params?: Router.UnknownInputParams; } | `/+not-found` | { pathname: `/+not-found`, params: Router.UnknownInputParams & { } };
+ }
+ }
+}
diff --git a/.expo/web/cache/production/images/favicon/favicon-24272cdaeff82cc5facdaccd982a6f05b60c4504704bbf94c19a6388659880bb-contain-transparent/favicon-48.png b/.expo/web/cache/production/images/favicon/favicon-24272cdaeff82cc5facdaccd982a6f05b60c4504704bbf94c19a6388659880bb-contain-transparent/favicon-48.png
Binary files differ.
diff --git a/.gitignore b/.gitignore
@@ -1 +1,8 @@
-node_modules
+node_modules
+
+# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb
+# The following patterns were generated by expo-cli
+
+expo-env.d.ts
+# @end expo-cli
+.expo
+\ No newline at end of file
diff --git a/app.json b/app.json
@@ -4,12 +4,13 @@
"slug": "finger",
"version": "1.0.0",
"orientation": "portrait",
- "icon": "./assets/images/icon.png",
+ "icon": "./assets/icon.png",
"scheme": "finger",
"userInterfaceStyle": "automatic",
"newArchEnabled": true,
"ios": {
- "supportsTablet": true
+ "supportsTablet": true,
+ "icon": "./assets/ios-light.png"
},
"android": {
"adaptiveIcon": {
@@ -28,10 +29,14 @@
[
"expo-splash-screen",
{
- "image": "./assets/images/splash-icon.png",
- "imageWidth": 200,
"resizeMode": "contain",
- "backgroundColor": "#ffffff"
+ "backgroundColor": "#232323",
+ "image": "./assets/images/splash-light.png",
+ "dark": {
+ "image": "./assets/images/splash-dark.png",
+ "backgroundColor": "#000000"
+ },
+ "imageWidth": 200
}
]
],
diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
@@ -1,45 +0,0 @@
-import { Tabs } from 'expo-router';
-import React from 'react';
-import { Platform } from 'react-native';
-
-import { HapticTab } from '@/components/HapticTab';
-import { IconSymbol } from '@/components/ui/IconSymbol';
-import TabBarBackground from '@/components/ui/TabBarBackground';
-import { Colors } from '@/constants/Colors';
-import { useColorScheme } from '@/hooks/useColorScheme';
-
-export default function TabLayout() {
- const colorScheme = useColorScheme();
-
- return (
- <Tabs
- screenOptions={{
- tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
- headerShown: false,
- tabBarButton: HapticTab,
- tabBarBackground: TabBarBackground,
- tabBarStyle: Platform.select({
- ios: {
- // Use a transparent background on iOS to show the blur effect
- position: 'absolute',
- },
- default: {},
- }),
- }}>
- <Tabs.Screen
- name="index"
- options={{
- title: 'Home',
- tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
- }}
- />
- <Tabs.Screen
- name="explore"
- options={{
- title: 'Explore',
- tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
- }}
- />
- </Tabs>
- );
-}
diff --git a/app/(tabs)/explore.tsx b/app/(tabs)/explore.tsx
@@ -1,110 +0,0 @@
-import { Image } from 'expo-image';
-import { Platform, StyleSheet } from 'react-native';
-
-import { Collapsible } from '@/components/Collapsible';
-import { ExternalLink } from '@/components/ExternalLink';
-import ParallaxScrollView from '@/components/ParallaxScrollView';
-import { ThemedText } from '@/components/ThemedText';
-import { ThemedView } from '@/components/ThemedView';
-import { IconSymbol } from '@/components/ui/IconSymbol';
-
-export default function TabTwoScreen() {
- return (
- <ParallaxScrollView
- headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }}
- headerImage={
- <IconSymbol
- size={310}
- color="#808080"
- name="chevron.left.forwardslash.chevron.right"
- style={styles.headerImage}
- />
- }>
- <ThemedView style={styles.titleContainer}>
- <ThemedText type="title">Explore</ThemedText>
- </ThemedView>
- <ThemedText>This app includes example code to help you get started.</ThemedText>
- <Collapsible title="File-based routing">
- <ThemedText>
- This app has two screens:{' '}
- <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '}
- <ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
- </ThemedText>
- <ThemedText>
- The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '}
- sets up the tab navigator.
- </ThemedText>
- <ExternalLink href="https://docs.expo.dev/router/introduction">
- <ThemedText type="link">Learn more</ThemedText>
- </ExternalLink>
- </Collapsible>
- <Collapsible title="Android, iOS, and web support">
- <ThemedText>
- You can open this project on Android, iOS, and the web. To open the web version, press{' '}
- <ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project.
- </ThemedText>
- </Collapsible>
- <Collapsible title="Images">
- <ThemedText>
- For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
- <ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for
- different screen densities
- </ThemedText>
- <Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} />
- <ExternalLink href="https://reactnative.dev/docs/images">
- <ThemedText type="link">Learn more</ThemedText>
- </ExternalLink>
- </Collapsible>
- <Collapsible title="Custom fonts">
- <ThemedText>
- Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText> to see how to load{' '}
- <ThemedText style={{ fontFamily: 'SpaceMono' }}>
- custom fonts such as this one.
- </ThemedText>
- </ThemedText>
- <ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font">
- <ThemedText type="link">Learn more</ThemedText>
- </ExternalLink>
- </Collapsible>
- <Collapsible title="Light and dark mode components">
- <ThemedText>
- This template has light and dark mode support. The{' '}
- <ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect
- what the user's current color scheme is, and so you can adjust UI colors accordingly.
- </ThemedText>
- <ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
- <ThemedText type="link">Learn more</ThemedText>
- </ExternalLink>
- </Collapsible>
- <Collapsible title="Animations">
- <ThemedText>
- This template includes an example of an animated component. The{' '}
- <ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses
- the powerful <ThemedText type="defaultSemiBold">react-native-reanimated</ThemedText>{' '}
- library to create a waving hand animation.
- </ThemedText>
- {Platform.select({
- ios: (
- <ThemedText>
- The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '}
- component provides a parallax effect for the header image.
- </ThemedText>
- ),
- })}
- </Collapsible>
- </ParallaxScrollView>
- );
-}
-
-const styles = StyleSheet.create({
- headerImage: {
- color: '#808080',
- bottom: -90,
- left: -35,
- position: 'absolute',
- },
- titleContainer: {
- flexDirection: 'row',
- gap: 8,
- },
-});
diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx
@@ -1,75 +0,0 @@
-import { Image } from 'expo-image';
-import { Platform, StyleSheet } from 'react-native';
-
-import { HelloWave } from '@/components/HelloWave';
-import ParallaxScrollView from '@/components/ParallaxScrollView';
-import { ThemedText } from '@/components/ThemedText';
-import { ThemedView } from '@/components/ThemedView';
-
-export default function HomeScreen() {
- return (
- <ParallaxScrollView
- headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
- headerImage={
- <Image
- source={require('@/assets/images/partial-react-logo.png')}
- style={styles.reactLogo}
- />
- }>
- <ThemedView style={styles.titleContainer}>
- <ThemedText type="title">Welcome!</ThemedText>
- <HelloWave />
- </ThemedView>
- <ThemedView style={styles.stepContainer}>
- <ThemedText type="subtitle">Step 1: Try it</ThemedText>
- <ThemedText>
- Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
- Press{' '}
- <ThemedText type="defaultSemiBold">
- {Platform.select({
- ios: 'cmd + d',
- android: 'cmd + m',
- web: 'F12',
- })}
- </ThemedText>{' '}
- to open developer tools.
- </ThemedText>
- </ThemedView>
- <ThemedView style={styles.stepContainer}>
- <ThemedText type="subtitle">Step 2: Explore</ThemedText>
- <ThemedText>
- {`Tap the Explore tab to learn more about what's included in this starter app.`}
- </ThemedText>
- </ThemedView>
- <ThemedView style={styles.stepContainer}>
- <ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText>
- <ThemedText>
- {`When you're ready, run `}
- <ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '}
- <ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '}
- <ThemedText type="defaultSemiBold">app</ThemedText> to{' '}
- <ThemedText type="defaultSemiBold">app-example</ThemedText>.
- </ThemedText>
- </ThemedView>
- </ParallaxScrollView>
- );
-}
-
-const styles = StyleSheet.create({
- titleContainer: {
- flexDirection: 'row',
- alignItems: 'center',
- gap: 8,
- },
- stepContainer: {
- gap: 8,
- marginBottom: 8,
- },
- reactLogo: {
- height: 178,
- width: 290,
- bottom: 0,
- left: 0,
- position: 'absolute',
- },
-});
diff --git a/app/+not-found.tsx b/app/+not-found.tsx
@@ -1,32 +1,29 @@
-import { Link, Stack } from 'expo-router';
-import { StyleSheet } from 'react-native';
+import {StyleSheet} from 'react-native';
+import {Link, Stack} from 'expo-router';
+import { SafeAreaView } from "react-native-safe-area-context";
-import { ThemedText } from '@/components/ThemedText';
-import { ThemedView } from '@/components/ThemedView';
-
-export default function NotFoundScreen() {
- return (
- <>
- <Stack.Screen options={{ title: 'Oops!' }} />
- <ThemedView style={styles.container}>
- <ThemedText type="title">This screen does not exist.</ThemedText>
- <Link href="/" style={styles.link}>
- <ThemedText type="link">Go to home screen!</ThemedText>
- </Link>
- </ThemedView>
- </>
- );
+export default function NotFoundScreen(){
+ return (
+ <SafeAreaView style={styles.container}>
+ <Stack.Screen options={{ title: 'Page Not Found' }} />
+ <Link href="/" style={styles.button}>Go back to home </Link>
+ </SafeAreaView>
+ )
}
const styles = StyleSheet.create({
container: {
flex: 1,
+ backgroundColor: '#25292e',
alignItems: 'center',
justifyContent: 'center',
- padding: 20,
},
- link: {
- marginTop: 15,
- paddingVertical: 15,
+ text: {
+ color: '#fff',
+ },
+ button: {
+ fontSize: 20,
+ textDecorationLine: 'underline',
+ color: '#fff',
},
-});
+});
+\ No newline at end of file
diff --git a/app/_layout.tsx b/app/_layout.tsx
@@ -1,29 +1,16 @@
-import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
-import { useFonts } from 'expo-font';
import { Stack } from 'expo-router';
+import { SafeAreaView } from "react-native-safe-area-context";
import { StatusBar } from 'expo-status-bar';
-import 'react-native-reanimated';
-
-import { useColorScheme } from '@/hooks/useColorScheme';
export default function RootLayout() {
- const colorScheme = useColorScheme();
- const [loaded] = useFonts({
- SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
- });
-
- if (!loaded) {
- // Async font loading only occurs in development.
- return null;
- }
-
return (
- <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
+ <SafeAreaView>
+ <StatusBar style="auto" />
<Stack>
- <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
- <Stack.Screen name="+not-found" />
+ <Stack.Screen name="index" options={{ title: 'Home' }} />
+ <Stack.Screen name="about" options={{ title: 'About' }} />
</Stack>
- <StatusBar style="auto" />
- </ThemeProvider>
+ </SafeAreaView>
);
}
+
diff --git a/app/about.tsx b/app/about.tsx
@@ -0,0 +1,22 @@
+import { Text, StyleSheet } from 'react-native';
+import { SafeAreaView } from "react-native-safe-area-context";
+
+export default function AboutScreen() {
+ return (
+ <SafeAreaView style={styles.container}>
+ <Text style={styles.text}>About screen</Text>
+ </SafeAreaView>
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: '#25292e',
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ text: {
+ color: '#fff',
+ },
+});
diff --git a/app/index.tsx b/app/index.tsx
@@ -0,0 +1,31 @@
+import { Text, StyleSheet } from "react-native";
+import { Link } from "expo-router";
+import { SafeAreaView } from "react-native-safe-area-context";
+
+export default function Index() {
+ return (
+ <SafeAreaView style={styles.container}>
+ <Text style={styles.text}>Hello Sleepy Boy</Text>
+ <Link href="/about" style={styles.button}>
+ Go to About
+ </Link>
+ </SafeAreaView>
+ );
+}
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ backgroundColor: '#25292e',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ text: {
+ color: '#fff',
+ },
+ button: {
+ fontSize: 20,
+ textDecorationLine: 'underline',
+ color: '#fff',
+ },
+});
+\ No newline at end of file
diff --git a/assets/images/adaptive-icon.png b/assets/images/adaptive-icon.png
Binary files differ.
diff --git a/assets/images/ios-dark.png b/assets/images/ios-dark.png
Binary files differ.
diff --git a/assets/images/ios-light.png b/assets/images/ios-light.png
Binary files differ.
diff --git a/assets/images/ios-tinted.png b/assets/images/ios-tinted.png
Binary files differ.
diff --git a/assets/images/splash-dark.png b/assets/images/splash-dark.png
Binary files differ.
diff --git a/assets/images/splash-light.png b/assets/images/splash-light.png
Binary files differ.
diff --git a/components/Collapsible.tsx b/components/Collapsible.tsx
@@ -1,45 +0,0 @@
-import { PropsWithChildren, useState } from 'react';
-import { StyleSheet, TouchableOpacity } from 'react-native';
-
-import { ThemedText } from '@/components/ThemedText';
-import { ThemedView } from '@/components/ThemedView';
-import { IconSymbol } from '@/components/ui/IconSymbol';
-import { Colors } from '@/constants/Colors';
-import { useColorScheme } from '@/hooks/useColorScheme';
-
-export function Collapsible({ children, title }: PropsWithChildren & { title: string }) {
- const [isOpen, setIsOpen] = useState(false);
- const theme = useColorScheme() ?? 'light';
-
- return (
- <ThemedView>
- <TouchableOpacity
- style={styles.heading}
- onPress={() => setIsOpen((value) => !value)}
- activeOpacity={0.8}>
- <IconSymbol
- name="chevron.right"
- size={18}
- weight="medium"
- color={theme === 'light' ? Colors.light.icon : Colors.dark.icon}
- style={{ transform: [{ rotate: isOpen ? '90deg' : '0deg' }] }}
- />
-
- <ThemedText type="defaultSemiBold">{title}</ThemedText>
- </TouchableOpacity>
- {isOpen && <ThemedView style={styles.content}>{children}</ThemedView>}
- </ThemedView>
- );
-}
-
-const styles = StyleSheet.create({
- heading: {
- flexDirection: 'row',
- alignItems: 'center',
- gap: 6,
- },
- content: {
- marginTop: 6,
- marginLeft: 24,
- },
-});
diff --git a/components/ExternalLink.tsx b/components/ExternalLink.tsx
@@ -1,24 +0,0 @@
-import { Href, Link } from 'expo-router';
-import { openBrowserAsync } from 'expo-web-browser';
-import { type ComponentProps } from 'react';
-import { Platform } from 'react-native';
-
-type Props = Omit<ComponentProps<typeof Link>, 'href'> & { href: Href & string };
-
-export function ExternalLink({ href, ...rest }: Props) {
- return (
- <Link
- target="_blank"
- {...rest}
- href={href}
- onPress={async (event) => {
- if (Platform.OS !== 'web') {
- // Prevent the default behavior of linking to the default browser on native.
- event.preventDefault();
- // Open the link in an in-app browser.
- await openBrowserAsync(href);
- }
- }}
- />
- );
-}
diff --git a/components/HapticTab.tsx b/components/HapticTab.tsx
@@ -1,18 +0,0 @@
-import { BottomTabBarButtonProps } from '@react-navigation/bottom-tabs';
-import { PlatformPressable } from '@react-navigation/elements';
-import * as Haptics from 'expo-haptics';
-
-export function HapticTab(props: BottomTabBarButtonProps) {
- return (
- <PlatformPressable
- {...props}
- onPressIn={(ev) => {
- if (process.env.EXPO_OS === 'ios') {
- // Add a soft haptic feedback when pressing down on the tabs.
- Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
- }
- props.onPressIn?.(ev);
- }}
- />
- );
-}
diff --git a/components/HelloWave.tsx b/components/HelloWave.tsx
@@ -1,40 +0,0 @@
-import { useEffect } from 'react';
-import { StyleSheet } from 'react-native';
-import Animated, {
- useAnimatedStyle,
- useSharedValue,
- withRepeat,
- withSequence,
- withTiming,
-} from 'react-native-reanimated';
-
-import { ThemedText } from '@/components/ThemedText';
-
-export function HelloWave() {
- const rotationAnimation = useSharedValue(0);
-
- useEffect(() => {
- rotationAnimation.value = withRepeat(
- withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })),
- 4 // Run the animation 4 times
- );
- }, [rotationAnimation]);
-
- const animatedStyle = useAnimatedStyle(() => ({
- transform: [{ rotate: `${rotationAnimation.value}deg` }],
- }));
-
- return (
- <Animated.View style={animatedStyle}>
- <ThemedText style={styles.text}>š</ThemedText>
- </Animated.View>
- );
-}
-
-const styles = StyleSheet.create({
- text: {
- fontSize: 28,
- lineHeight: 32,
- marginTop: -6,
- },
-});
diff --git a/components/ParallaxScrollView.tsx b/components/ParallaxScrollView.tsx
@@ -1,82 +0,0 @@
-import type { PropsWithChildren, ReactElement } from 'react';
-import { StyleSheet } from 'react-native';
-import Animated, {
- interpolate,
- useAnimatedRef,
- useAnimatedStyle,
- useScrollViewOffset,
-} from 'react-native-reanimated';
-
-import { ThemedView } from '@/components/ThemedView';
-import { useBottomTabOverflow } from '@/components/ui/TabBarBackground';
-import { useColorScheme } from '@/hooks/useColorScheme';
-
-const HEADER_HEIGHT = 250;
-
-type Props = PropsWithChildren<{
- headerImage: ReactElement;
- headerBackgroundColor: { dark: string; light: string };
-}>;
-
-export default function ParallaxScrollView({
- children,
- headerImage,
- headerBackgroundColor,
-}: Props) {
- const colorScheme = useColorScheme() ?? 'light';
- const scrollRef = useAnimatedRef<Animated.ScrollView>();
- const scrollOffset = useScrollViewOffset(scrollRef);
- const bottom = useBottomTabOverflow();
- const headerAnimatedStyle = useAnimatedStyle(() => {
- return {
- transform: [
- {
- translateY: interpolate(
- scrollOffset.value,
- [-HEADER_HEIGHT, 0, HEADER_HEIGHT],
- [-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75]
- ),
- },
- {
- scale: interpolate(scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1]),
- },
- ],
- };
- });
-
- return (
- <ThemedView style={styles.container}>
- <Animated.ScrollView
- ref={scrollRef}
- scrollEventThrottle={16}
- scrollIndicatorInsets={{ bottom }}
- contentContainerStyle={{ paddingBottom: bottom }}>
- <Animated.View
- style={[
- styles.header,
- { backgroundColor: headerBackgroundColor[colorScheme] },
- headerAnimatedStyle,
- ]}>
- {headerImage}
- </Animated.View>
- <ThemedView style={styles.content}>{children}</ThemedView>
- </Animated.ScrollView>
- </ThemedView>
- );
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- },
- header: {
- height: HEADER_HEIGHT,
- overflow: 'hidden',
- },
- content: {
- flex: 1,
- padding: 32,
- gap: 16,
- overflow: 'hidden',
- },
-});
diff --git a/components/ThemedText.tsx b/components/ThemedText.tsx
@@ -1,60 +0,0 @@
-import { StyleSheet, Text, type TextProps } from 'react-native';
-
-import { useThemeColor } from '@/hooks/useThemeColor';
-
-export type ThemedTextProps = TextProps & {
- lightColor?: string;
- darkColor?: string;
- type?: 'default' | 'title' | 'defaultSemiBold' | 'subtitle' | 'link';
-};
-
-export function ThemedText({
- style,
- lightColor,
- darkColor,
- type = 'default',
- ...rest
-}: ThemedTextProps) {
- const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
-
- return (
- <Text
- style={[
- { color },
- type === 'default' ? styles.default : undefined,
- type === 'title' ? styles.title : undefined,
- type === 'defaultSemiBold' ? styles.defaultSemiBold : undefined,
- type === 'subtitle' ? styles.subtitle : undefined,
- type === 'link' ? styles.link : undefined,
- style,
- ]}
- {...rest}
- />
- );
-}
-
-const styles = StyleSheet.create({
- default: {
- fontSize: 16,
- lineHeight: 24,
- },
- defaultSemiBold: {
- fontSize: 16,
- lineHeight: 24,
- fontWeight: '600',
- },
- title: {
- fontSize: 32,
- fontWeight: 'bold',
- lineHeight: 32,
- },
- subtitle: {
- fontSize: 20,
- fontWeight: 'bold',
- },
- link: {
- lineHeight: 30,
- fontSize: 16,
- color: '#0a7ea4',
- },
-});
diff --git a/components/ThemedView.tsx b/components/ThemedView.tsx
@@ -1,14 +0,0 @@
-import { View, type ViewProps } from 'react-native';
-
-import { useThemeColor } from '@/hooks/useThemeColor';
-
-export type ThemedViewProps = ViewProps & {
- lightColor?: string;
- darkColor?: string;
-};
-
-export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) {
- const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
-
- return <View style={[{ backgroundColor }, style]} {...otherProps} />;
-}
diff --git a/components/ui/IconSymbol.ios.tsx b/components/ui/IconSymbol.ios.tsx
@@ -1,32 +0,0 @@
-import { SymbolView, SymbolViewProps, SymbolWeight } from 'expo-symbols';
-import { StyleProp, ViewStyle } from 'react-native';
-
-export function IconSymbol({
- name,
- size = 24,
- color,
- style,
- weight = 'regular',
-}: {
- name: SymbolViewProps['name'];
- size?: number;
- color: string;
- style?: StyleProp<ViewStyle>;
- weight?: SymbolWeight;
-}) {
- return (
- <SymbolView
- weight={weight}
- tintColor={color}
- resizeMode="scaleAspectFit"
- name={name}
- style={[
- {
- width: size,
- height: size,
- },
- style,
- ]}
- />
- );
-}
diff --git a/components/ui/IconSymbol.tsx b/components/ui/IconSymbol.tsx
@@ -1,41 +0,0 @@
-// Fallback for using MaterialIcons on Android and web.
-
-import MaterialIcons from '@expo/vector-icons/MaterialIcons';
-import { SymbolWeight, SymbolViewProps } from 'expo-symbols';
-import { ComponentProps } from 'react';
-import { OpaqueColorValue, type StyleProp, type TextStyle } from 'react-native';
-
-type IconMapping = Record<SymbolViewProps['name'], ComponentProps<typeof MaterialIcons>['name']>;
-type IconSymbolName = keyof typeof MAPPING;
-
-/**
- * Add your SF Symbols to Material Icons mappings here.
- * - see Material Icons in the [Icons Directory](https://icons.expo.fyi).
- * - see SF Symbols in the [SF Symbols](https://developer.apple.com/sf-symbols/) app.
- */
-const MAPPING = {
- 'house.fill': 'home',
- 'paperplane.fill': 'send',
- 'chevron.left.forwardslash.chevron.right': 'code',
- 'chevron.right': 'chevron-right',
-} as IconMapping;
-
-/**
- * An icon component that uses native SF Symbols on iOS, and Material Icons on Android and web.
- * This ensures a consistent look across platforms, and optimal resource usage.
- * Icon `name`s are based on SF Symbols and require manual mapping to Material Icons.
- */
-export function IconSymbol({
- name,
- size = 24,
- color,
- style,
-}: {
- name: IconSymbolName;
- size?: number;
- color: string | OpaqueColorValue;
- style?: StyleProp<TextStyle>;
- weight?: SymbolWeight;
-}) {
- return <MaterialIcons color={color} size={size} name={MAPPING[name]} style={style} />;
-}
diff --git a/components/ui/TabBarBackground.ios.tsx b/components/ui/TabBarBackground.ios.tsx
@@ -1,19 +0,0 @@
-import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
-import { BlurView } from 'expo-blur';
-import { StyleSheet } from 'react-native';
-
-export default function BlurTabBarBackground() {
- return (
- <BlurView
- // System chrome material automatically adapts to the system's theme
- // and matches the native tab bar appearance on iOS.
- tint="systemChromeMaterial"
- intensity={100}
- style={StyleSheet.absoluteFill}
- />
- );
-}
-
-export function useBottomTabOverflow() {
- return useBottomTabBarHeight();
-}
diff --git a/components/ui/TabBarBackground.tsx b/components/ui/TabBarBackground.tsx
@@ -1,6 +0,0 @@
-// This is a shim for web and Android where the tab bar is generally opaque.
-export default undefined;
-
-export function useBottomTabOverflow() {
- return 0;
-}
diff --git a/constants/Colors.ts b/constants/Colors.ts
@@ -1,26 +0,0 @@
-/**
- * Below are the colors that are used in the app. The colors are defined in the light and dark mode.
- * There are many other ways to style your app. For example, [Nativewind](https://www.nativewind.dev/), [Tamagui](https://tamagui.dev/), [unistyles](https://reactnativeunistyles.vercel.app), etc.
- */
-
-const tintColorLight = '#0a7ea4';
-const tintColorDark = '#fff';
-
-export const Colors = {
- light: {
- text: '#11181C',
- background: '#fff',
- tint: tintColorLight,
- icon: '#687076',
- tabIconDefault: '#687076',
- tabIconSelected: tintColorLight,
- },
- dark: {
- text: '#ECEDEE',
- background: '#151718',
- tint: tintColorDark,
- icon: '#9BA1A6',
- tabIconDefault: '#9BA1A6',
- tabIconSelected: tintColorDark,
- },
-};
diff --git a/hooks/useColorScheme.ts b/hooks/useColorScheme.ts
@@ -1 +0,0 @@
-export { useColorScheme } from 'react-native';
diff --git a/hooks/useColorScheme.web.ts b/hooks/useColorScheme.web.ts
@@ -1,21 +0,0 @@
-import { useEffect, useState } from 'react';
-import { useColorScheme as useRNColorScheme } from 'react-native';
-
-/**
- * To support static rendering, this value needs to be re-calculated on the client side for web
- */
-export function useColorScheme() {
- const [hasHydrated, setHasHydrated] = useState(false);
-
- useEffect(() => {
- setHasHydrated(true);
- }, []);
-
- const colorScheme = useRNColorScheme();
-
- if (hasHydrated) {
- return colorScheme;
- }
-
- return 'light';
-}
diff --git a/hooks/useThemeColor.ts b/hooks/useThemeColor.ts
@@ -1,21 +0,0 @@
-/**
- * Learn more about light and dark modes:
- * https://docs.expo.dev/guides/color-schemes/
- */
-
-import { Colors } from '@/constants/Colors';
-import { useColorScheme } from '@/hooks/useColorScheme';
-
-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];
- }
-}
diff --git a/scripts/reset-project.js b/scripts/reset-project.js
@@ -1,112 +0,0 @@
-#!/usr/bin/env node
-
-/**
- * This script is used to reset the project to a blank state.
- * It deletes or moves the /app, /components, /hooks, /scripts, and /constants directories to /app-example based on user input and creates a new /app directory with an index.tsx and _layout.tsx file.
- * You can remove the `reset-project` script from package.json and safely delete this file after running it.
- */
-
-const fs = require("fs");
-const path = require("path");
-const readline = require("readline");
-
-const root = process.cwd();
-const oldDirs = ["app", "components", "hooks", "constants", "scripts"];
-const exampleDir = "app-example";
-const newAppDir = "app";
-const exampleDirPath = path.join(root, exampleDir);
-
-const indexContent = `import { Text, View } from "react-native";
-
-export default function Index() {
- return (
- <View
- style={{
- flex: 1,
- justifyContent: "center",
- alignItems: "center",
- }}
- >
- <Text>Edit app/index.tsx to edit this screen.</Text>
- </View>
- );
-}
-`;
-
-const layoutContent = `import { Stack } from "expo-router";
-
-export default function RootLayout() {
- return <Stack />;
-}
-`;
-
-const rl = readline.createInterface({
- input: process.stdin,
- output: process.stdout,
-});
-
-const moveDirectories = async (userInput) => {
- try {
- if (userInput === "y") {
- // Create the app-example directory
- await fs.promises.mkdir(exampleDirPath, { recursive: true });
- console.log(`š /${exampleDir} directory created.`);
- }
-
- // Move old directories to new app-example directory or delete them
- for (const dir of oldDirs) {
- const oldDirPath = path.join(root, dir);
- if (fs.existsSync(oldDirPath)) {
- if (userInput === "y") {
- const newDirPath = path.join(root, exampleDir, dir);
- await fs.promises.rename(oldDirPath, newDirPath);
- console.log(`ā”ļø /${dir} moved to /${exampleDir}/${dir}.`);
- } else {
- await fs.promises.rm(oldDirPath, { recursive: true, force: true });
- console.log(`ā /${dir} deleted.`);
- }
- } else {
- console.log(`ā”ļø /${dir} does not exist, skipping.`);
- }
- }
-
- // Create new /app directory
- const newAppDirPath = path.join(root, newAppDir);
- await fs.promises.mkdir(newAppDirPath, { recursive: true });
- console.log("\nš New /app directory created.");
-
- // Create index.tsx
- const indexPath = path.join(newAppDirPath, "index.tsx");
- await fs.promises.writeFile(indexPath, indexContent);
- console.log("š app/index.tsx created.");
-
- // Create _layout.tsx
- const layoutPath = path.join(newAppDirPath, "_layout.tsx");
- await fs.promises.writeFile(layoutPath, layoutContent);
- console.log("š app/_layout.tsx created.");
-
- console.log("\nā
Project reset complete. Next steps:");
- console.log(
- `1. Run \`npx expo start\` to start a development server.\n2. Edit app/index.tsx to edit the main screen.${
- userInput === "y"
- ? `\n3. Delete the /${exampleDir} directory when you're done referencing it.`
- : ""
- }`
- );
- } catch (error) {
- console.error(`ā Error during script execution: ${error.message}`);
- }
-};
-
-rl.question(
- "Do you want to move existing files to /app-example instead of deleting them? (Y/n): ",
- (answer) => {
- const userInput = answer.trim().toLowerCase() || "y";
- if (userInput === "y" || userInput === "n") {
- moveDirectories(userInput).finally(() => rl.close());
- } else {
- console.log("ā Invalid input. Please enter 'Y' or 'N'.");
- rl.close();
- }
- }
-);