about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2022-06-09 16:32:03 -0500
committerPaul Frazee <pfrazee@gmail.com>2022-06-09 16:32:03 -0500
commitfc3b2952bb59b80665ebb53ffb3377f647ccdbd3 (patch)
tree37477c0803459ff55f0e26ae27c8231305e6856a /src
parentd6942bffab68ce80d5cb26b42710dd9276f62ded (diff)
downloadvoidsky-fc3b2952bb59b80665ebb53ffb3377f647ccdbd3.tar.zst
Add routes and core views
Diffstat (limited to 'src')
-rw-r--r--src/App.native.tsx59
-rw-r--r--src/App.web.tsx59
-rw-r--r--src/routes/index.tsx72
-rw-r--r--src/routes/types.ts24
-rw-r--r--src/screens/Home.tsx17
-rw-r--r--src/screens/Menu.tsx19
-rw-r--r--src/screens/NotFound.tsx27
-rw-r--r--src/screens/Notifications.tsx21
-rw-r--r--src/screens/Profile.tsx7
-rw-r--r--src/screens/Search.tsx19
10 files changed, 210 insertions, 114 deletions
diff --git a/src/App.native.tsx b/src/App.native.tsx
index 40989caf0..2fadf993f 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -1,52 +1,6 @@
 import React, {useState, useEffect} from 'react'
-import {
-  SafeAreaView,
-  ScrollView,
-  StatusBar,
-  Text,
-  Button,
-  useColorScheme,
-  View,
-} from 'react-native'
-import {NavigationContainer} from '@react-navigation/native'
-import {
-  createNativeStackNavigator,
-  NativeStackScreenProps,
-} from '@react-navigation/native-stack'
 import {RootStore, setupState, RootStoreProvider} from './state'
-
-type RootStackParamList = {
-  Home: undefined
-  Profile: {name: string}
-}
-const Stack = createNativeStackNavigator()
-
-const HomeScreen = ({
-  navigation,
-}: NativeStackScreenProps<RootStackParamList, 'Home'>) => {
-  const isDarkMode = useColorScheme() === 'dark'
-
-  return (
-    <SafeAreaView>
-      <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
-      <ScrollView contentInsetAdjustmentBehavior="automatic">
-        <View>
-          <Text>Native</Text>
-          <Button
-            title="Go to Jane's profile"
-            onPress={() => navigation.navigate('Profile', {name: 'Jane'})}
-          />
-        </View>
-      </ScrollView>
-    </SafeAreaView>
-  )
-}
-
-const ProfileScreen = ({
-  route,
-}: NativeStackScreenProps<RootStackParamList, 'Profile'>) => {
-  return <Text>This is {route.params.name}'s profile</Text>
-}
+import * as Routes from './routes'
 
 function App() {
   const [rootStore, setRootStore] = useState<RootStore | undefined>(undefined)
@@ -63,16 +17,7 @@ function App() {
 
   return (
     <RootStoreProvider value={rootStore}>
-      <NavigationContainer>
-        <Stack.Navigator>
-          <Stack.Screen
-            name="Home"
-            component={HomeScreen}
-            options={{title: 'Welcome'}}
-          />
-          <Stack.Screen name="Profile" component={ProfileScreen} />
-        </Stack.Navigator>
-      </NavigationContainer>
+      <Routes.Root />
     </RootStoreProvider>
   )
 }
diff --git a/src/App.web.tsx b/src/App.web.tsx
index 18b15821b..2fadf993f 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -1,52 +1,6 @@
 import React, {useState, useEffect} from 'react'
-import {
-  SafeAreaView,
-  ScrollView,
-  StatusBar,
-  Text,
-  Button,
-  useColorScheme,
-  View,
-} from 'react-native'
-import {NavigationContainer} from '@react-navigation/native'
-import {
-  createNativeStackNavigator,
-  NativeStackScreenProps,
-} from '@react-navigation/native-stack'
 import {RootStore, setupState, RootStoreProvider} from './state'
-
-type RootStackParamList = {
-  Home: undefined
-  Profile: {name: string}
-}
-const Stack = createNativeStackNavigator()
-
-const HomeScreen = ({
-  navigation,
-}: NativeStackScreenProps<RootStackParamList, 'Home'>) => {
-  const isDarkMode = useColorScheme() === 'dark'
-
-  return (
-    <SafeAreaView>
-      <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
-      <ScrollView contentInsetAdjustmentBehavior="automatic">
-        <View>
-          <Text>Web</Text>
-          <Button
-            title="Go to Jane's profile"
-            onPress={() => navigation.navigate('Profile', {name: 'Jane'})}
-          />
-        </View>
-      </ScrollView>
-    </SafeAreaView>
-  )
-}
-
-const ProfileScreen = ({
-  route,
-}: NativeStackScreenProps<RootStackParamList, 'Profile'>) => {
-  return <Text>This is {route.params.name}'s profile</Text>
-}
+import * as Routes from './routes'
 
 function App() {
   const [rootStore, setRootStore] = useState<RootStore | undefined>(undefined)
@@ -63,16 +17,7 @@ function App() {
 
   return (
     <RootStoreProvider value={rootStore}>
-      <NavigationContainer>
-        <Stack.Navigator>
-          <Stack.Screen
-            name="Home"
-            component={HomeScreen}
-            options={{title: 'Welcome'}}
-          />
-          <Stack.Screen name="Profile" component={ProfileScreen} />
-        </Stack.Navigator>
-      </NavigationContainer>
+      <Routes.Root />
     </RootStoreProvider>
   )
 }
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
new file mode 100644
index 000000000..9ea1766f5
--- /dev/null
+++ b/src/routes/index.tsx
@@ -0,0 +1,72 @@
+import React from 'react'
+import {Text} from 'react-native'
+import {
+  NavigationContainer,
+  LinkingOptions,
+  RouteProp,
+  ParamListBase,
+} from '@react-navigation/native'
+import {createNativeStackNavigator} from '@react-navigation/native-stack'
+import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'
+import type {RootStackParamList} from './types'
+import {Home} from '../screens/Home'
+import {Search} from '../screens/Search'
+import {Notifications} from '../screens/Notifications'
+import {Menu} from '../screens/Menu'
+import {Profile} from '../screens/Profile'
+import {NotFound} from '../screens/NotFound'
+
+const linking: LinkingOptions<RootStackParamList> = {
+  prefixes: [
+    'http://localhost:3000', // local dev
+  ],
+  config: {
+    screens: {
+      Primary: {
+        screens: {
+          Home: '',
+          Search: 'search',
+          Notifications: 'notifications',
+          Menu: 'menu',
+        },
+      },
+      Profile: 'profile/:name',
+      NotFound: '*',
+    },
+  },
+}
+
+export const RootStack = createNativeStackNavigator()
+export const PrimaryTab = createBottomTabNavigator()
+
+const tabBarScreenOptions = ({
+  route,
+}: {
+  route: RouteProp<ParamListBase, string>
+}) => ({
+  tabBarIcon: (_state: {focused: boolean; color: string; size: number}) => {
+    // TODO: icons
+    return <Text>{route.name.at(0)}</Text>
+  },
+})
+
+const Primary = () => (
+  <PrimaryTab.Navigator
+    screenOptions={tabBarScreenOptions}
+    initialRouteName="Home">
+    <PrimaryTab.Screen name="Home" component={Home} />
+    <PrimaryTab.Screen name="Search" component={Search} />
+    <PrimaryTab.Screen name="Notifications" component={Notifications} />
+    <PrimaryTab.Screen name="Menu" component={Menu} />
+  </PrimaryTab.Navigator>
+)
+
+export const Root = () => (
+  <NavigationContainer linking={linking} fallback={<Text>Loading...</Text>}>
+    <RootStack.Navigator initialRouteName="Primary">
+      <RootStack.Screen name="Primary" component={Primary} />
+      <RootStack.Screen name="Profile" component={Profile} />
+      <RootStack.Screen name="NotFound" component={NotFound} />
+    </RootStack.Navigator>
+  </NavigationContainer>
+)
diff --git a/src/routes/types.ts b/src/routes/types.ts
new file mode 100644
index 000000000..668dc2e2f
--- /dev/null
+++ b/src/routes/types.ts
@@ -0,0 +1,24 @@
+import type {NavigatorScreenParams} from '@react-navigation/native'
+import type {CompositeScreenProps} from '@react-navigation/native'
+import type {StackScreenProps} from '@react-navigation/stack'
+import type {BottomTabScreenProps} from '@react-navigation/bottom-tabs'
+
+export type RootStackParamList = {
+  Primary: undefined
+  Profile: {name: string}
+  NotFound: undefined
+}
+export type RootStackScreenProps<T extends keyof RootStackParamList> =
+  StackScreenProps<RootStackParamList, T>
+
+export type PrimaryTabParamList = {
+  Home: NavigatorScreenParams<RootStackParamList>
+  Search: undefined
+  Notifications: undefined
+  Menu: undefined
+}
+export type PrimaryTabScreenProps<T extends keyof PrimaryTabParamList> =
+  CompositeScreenProps<
+    BottomTabScreenProps<PrimaryTabParamList, T>,
+    RootStackScreenProps<keyof RootStackParamList>
+  >
diff --git a/src/screens/Home.tsx b/src/screens/Home.tsx
new file mode 100644
index 000000000..f4b8ffb63
--- /dev/null
+++ b/src/screens/Home.tsx
@@ -0,0 +1,17 @@
+import React from 'react'
+import {Text, Button, View, SafeAreaView} from 'react-native'
+import type {PrimaryTabScreenProps} from '../routes/types'
+
+export const Home = ({navigation}: PrimaryTabScreenProps<'Home'>) => {
+  return (
+    <SafeAreaView style={{flex: 1}}>
+      <View style={{flex: 1}}>
+        <Text>Hello world</Text>
+        <Button
+          title="Go to Jane's profile"
+          onPress={() => navigation.navigate('Profile', {name: 'Jane'})}
+        />
+      </View>
+    </SafeAreaView>
+  )
+}
diff --git a/src/screens/Menu.tsx b/src/screens/Menu.tsx
new file mode 100644
index 000000000..2e0376a49
--- /dev/null
+++ b/src/screens/Menu.tsx
@@ -0,0 +1,19 @@
+import React from 'react'
+import {SafeAreaView, ScrollView, Text, Button, View} from 'react-native'
+import type {PrimaryTabScreenProps} from '../routes/types'
+
+export const Menu = ({navigation}: PrimaryTabScreenProps<'Menu'>) => {
+  return (
+    <SafeAreaView>
+      <ScrollView contentInsetAdjustmentBehavior="automatic">
+        <View>
+          <Text>Hello world</Text>
+          <Button
+            title="Go to Jane's profile"
+            onPress={() => navigation.navigate('Profile', {name: 'Jane'})}
+          />
+        </View>
+      </ScrollView>
+    </SafeAreaView>
+  )
+}
diff --git a/src/screens/NotFound.tsx b/src/screens/NotFound.tsx
new file mode 100644
index 000000000..afb91b402
--- /dev/null
+++ b/src/screens/NotFound.tsx
@@ -0,0 +1,27 @@
+import React from 'react'
+import {
+  SafeAreaView,
+  ScrollView,
+  StatusBar,
+  Text,
+  Button,
+  useColorScheme,
+  View,
+} from 'react-native'
+import type {RootStackScreenProps} from '../routes/types'
+
+export const NotFound = ({navigation}: RootStackScreenProps<'NotFound'>) => {
+  const isDarkMode = useColorScheme() === 'dark'
+
+  return (
+    <SafeAreaView>
+      <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
+      <ScrollView contentInsetAdjustmentBehavior="automatic">
+        <View>
+          <Text>Page not found</Text>
+          <Button title="Home" onPress={() => navigation.navigate('Primary')} />
+        </View>
+      </ScrollView>
+    </SafeAreaView>
+  )
+}
diff --git a/src/screens/Notifications.tsx b/src/screens/Notifications.tsx
new file mode 100644
index 000000000..8ffb5bb87
--- /dev/null
+++ b/src/screens/Notifications.tsx
@@ -0,0 +1,21 @@
+import React from 'react'
+import {SafeAreaView, ScrollView, Text, Button, View} from 'react-native'
+import type {PrimaryTabScreenProps} from '../routes/types'
+
+export const Notifications = ({
+  navigation,
+}: PrimaryTabScreenProps<'Notifications'>) => {
+  return (
+    <SafeAreaView>
+      <ScrollView contentInsetAdjustmentBehavior="automatic">
+        <View>
+          <Text>Hello world</Text>
+          <Button
+            title="Go to Jane's profile"
+            onPress={() => navigation.navigate('Profile', {name: 'Jane'})}
+          />
+        </View>
+      </ScrollView>
+    </SafeAreaView>
+  )
+}
diff --git a/src/screens/Profile.tsx b/src/screens/Profile.tsx
new file mode 100644
index 000000000..ffd30a499
--- /dev/null
+++ b/src/screens/Profile.tsx
@@ -0,0 +1,7 @@
+import React from 'react'
+import {Text} from 'react-native'
+import type {RootStackScreenProps} from '../routes/types'
+
+export const Profile = ({route}: RootStackScreenProps<'Profile'>) => {
+  return <Text>This is {route.params.name}'s profile</Text>
+}
diff --git a/src/screens/Search.tsx b/src/screens/Search.tsx
new file mode 100644
index 000000000..85943190a
--- /dev/null
+++ b/src/screens/Search.tsx
@@ -0,0 +1,19 @@
+import React from 'react'
+import {SafeAreaView, ScrollView, Text, Button, View} from 'react-native'
+import type {PrimaryTabScreenProps} from '../routes/types'
+
+export const Search = ({navigation}: PrimaryTabScreenProps<'Search'>) => {
+  return (
+    <SafeAreaView>
+      <ScrollView contentInsetAdjustmentBehavior="automatic">
+        <View>
+          <Text>Hello world</Text>
+          <Button
+            title="Go to Jane's profile"
+            onPress={() => navigation.navigate('Profile', {name: 'Jane'})}
+          />
+        </View>
+      </ScrollView>
+    </SafeAreaView>
+  )
+}