WIP Switch to react-navigation 3

This commit is contained in:
Paul Frazee
2023-03-09 18:45:59 -06:00
parent bf951421ea
commit 6a4961caa5
+130 -56
View File
@@ -1,43 +1,44 @@
import * as React from 'react'
import {View, Text, Button} from 'react-native'
import {NavigationContainer} from '@react-navigation/native'
import {createNativeStackNavigator} from '@react-navigation/native-stack'
import {
createNativeStackNavigator,
NativeStackScreenProps,
} from '@react-navigation/native-stack'
import {createDrawerNavigator} from '@react-navigation/drawer'
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs'
import {NavigationState, PartialState} from '@react-navigation/native'
type CommonNavigatorParamlist = {
type CommonNavigatorParams = {
Settings: undefined
Profile: {name: string}
ProfileFollowers: {name: string}
ProfileFollows: {name: string}
PostThread: {name: string; rkey: string}
PostUpvotedBy: {name: string; rkey: string}
PostDownvotedBy: {name: string; rkey: string}
PostRepostedBy: {name: string; rkey: string}
Debug: undefined
Log: undefined
}
type HomeStackNavigatorParamlist = CommonNavigatorParamlist & {
type HomeStackNavigatorParams = CommonNavigatorParams & {
Home: undefined
}
type NotificationsStackNavigatorParamlist = CommonNavigatorParamlist & {
type NotificationsStackNavigatorParams = CommonNavigatorParams & {
Notifications: undefined
}
type SearchStackNavigatorParamlist = CommonNavigatorParamlist & {
type SearchStackNavigatorParams = CommonNavigatorParams & {
Search: undefined
}
type State = NavigationState | Omit<PartialState<NavigationState>, 'stale'>
const HomeDrawer = createDrawerNavigator()
const HomeStack = createNativeStackNavigator<HomeStackNavigatorParamlist>()
const HomeStack = createNativeStackNavigator<HomeStackNavigatorParams>()
const SearchDrawer = createDrawerNavigator()
const SearchStack =
createNativeStackNavigator<NotificationsStackNavigatorParamlist>()
const SearchStack = createNativeStackNavigator<SearchStackNavigatorParams>()
const NotificationsDrawer = createDrawerNavigator()
const NotificationsStack =
createNativeStackNavigator<SearchStackNavigatorParamlist>()
createNativeStackNavigator<NotificationsStackNavigatorParams>()
const Tab = createBottomTabNavigator()
type RouteParams = Record<string, string>
@@ -78,7 +79,6 @@ const ROUTES: Record<string, Route> = {
ProfileFollows: r('/profile/:name/follows'),
PostThread: r('/profile/:name/post/:rkey'),
PostUpvotedBy: r('/profile/:name/post/:rkey/upvoted-by'),
PostDownvotedBy: r('/profile/:name/post/:rkey/downvoted-by'),
PostRepostedBy: r('/profile/:name/post/:rkey/reposted-by'),
Debug: r('/sys/debug'),
Log: r('/sys/log'),
@@ -87,7 +87,7 @@ const ROUTES: Record<string, Route> = {
const LINKING = {
prefixes: ['bsky://', 'https://bsky.app'],
getPathFromState(state: State, options?: any) {
getPathFromState(state: State) {
// find the current node in the navigation tree
let node = state.routes[state.index]
while (node.state?.routes && typeof node.state?.index === 'number') {
@@ -99,15 +99,13 @@ const LINKING = {
if (typeof route === 'undefined') {
return '/' // default to home
}
return route.build({
/* TODO */
})
return route.build((node.params || {}) as RouteParams)
},
getStateFromPath(path: string, options?: any) {
getStateFromPath(path: string) {
// match the route
let match = 'Home' // TODO should be not found
let params: Record<string, string> = {}
let params: RouteParams = {}
for (const [name, matcher] of Object.entries(ROUTES)) {
const res = matcher.match(path)
if (res) {
@@ -118,7 +116,6 @@ const LINKING = {
}
// build the state object
// TODO params
let container = 'HomeStack'
if (match === 'Notifications') {
container = 'NotificationsStack'
@@ -130,7 +127,7 @@ const LINKING = {
{
name: container,
state: {
routes: [{name: match}],
routes: [{name: match, params}],
},
},
],
@@ -138,83 +135,161 @@ const LINKING = {
},
}
function HomeScreen({navigation}) {
function HomeScreen({
navigation,
}: NativeStackScreenProps<HomeStackNavigatorParams, 'Home'>) {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Home Screen</Text>
<Button
title="Go to Post"
onPress={() => navigation.push('PostThread', {name: 'bob', rkey: 123})}
onPress={() =>
navigation.push('PostThread', {name: 'bob', rkey: '123'})
}
/>
<Button
title="Go to profile"
onPress={() => navigation.push('Profile')}
onPress={() => navigation.push('Profile', {name: 'alice'})}
/>
</View>
)
}
function NotificationsScreen({navigation}) {
function NotificationsScreen({
navigation,
}: NativeStackScreenProps<NotificationsStackNavigatorParams, 'Notifications'>) {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Notifications Screen</Text>
<Button
title="Go to Post"
onPress={() => navigation.push('PostThread', {name: 'bob', rkey: 123})}
onPress={() =>
navigation.push('PostThread', {name: 'bob', rkey: '123'})
}
/>
<Button
title="Go to profile"
onPress={() => navigation.push('Profile')}
onPress={() => navigation.push('Profile', {name: 'alice'})}
/>
</View>
)
}
function SearchScreen({navigation}) {
function SearchScreen({
navigation,
}: NativeStackScreenProps<SearchStackNavigatorParams, 'Search'>) {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Search Screen</Text>
<Button
title="Go to Post"
onPress={() => navigation.push('PostThread', {name: 'bob', rkey: 123})}
onPress={() =>
navigation.push('PostThread', {name: 'bob', rkey: '123'})
}
/>
<Button
title="Go to profile"
onPress={() => navigation.push('Profile')}
onPress={() => navigation.push('Profile', {name: 'alice'})}
/>
</View>
)
}
function debugMkScreen(name: string) {
return function ({navigation}) {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>{name} Screen</Text>
<Button
title="Go to Home"
onPress={() => navigation.navigate('Home')}
/>
<Button title="Go back" onPress={() => navigation.goBack()} />
<Button
title="Go back to first screen in stack"
onPress={() => navigation.popToTop()}
/>
</View>
)
}
function SettingsScreen({}: NativeStackScreenProps<
CommonNavigatorParams,
'Settings'
>) {
return (
<View>
<Text>SettingsScreen</Text>
</View>
)
}
const SettingsScreen = debugMkScreen('Settings')
const ProfileScreen = debugMkScreen('Profile')
const ProfileFollowersScreen = debugMkScreen('ProfileFollowers')
const ProfileFollowsScreen = debugMkScreen('ProfileFollows')
const PostThreadScreen = debugMkScreen('PostThread')
const PostUpvotedByScreen = debugMkScreen('PostUpvotedBy')
const PostDownvotedByScreen = debugMkScreen('PostDownvotedBy')
const PostRepostedByScreen = debugMkScreen('PostRepostedBy')
const DebugScreen = debugMkScreen('Debug')
const LogScreen = debugMkScreen('Log')
function ProfileScreen({
route,
}: NativeStackScreenProps<CommonNavigatorParams, 'Profile'>) {
return (
<View>
<Text>ProfileScreen {route.params.name}</Text>
</View>
)
}
function ProfileFollowersScreen({
route,
}: NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollowers'>) {
return (
<View>
<Text>ProfileFollowersScreen {route.params.name}</Text>
</View>
)
}
function ProfileFollowsScreen({
route,
}: NativeStackScreenProps<CommonNavigatorParams, 'ProfileFollows'>) {
return (
<View>
<Text>ProfileFollowsScreen {route.params.name}</Text>
</View>
)
}
function PostThreadScreen({
route,
}: NativeStackScreenProps<CommonNavigatorParams, 'PostThread'>) {
return (
<View>
<Text>
PostThreadScreen {route.params.name} {route.params.rkey}
</Text>
</View>
)
}
function PostUpvotedByScreen({
route,
}: NativeStackScreenProps<CommonNavigatorParams, 'PostUpvotedBy'>) {
return (
<View>
<Text>
PostUpvotedByScreen {route.params.name} {route.params.rkey}
</Text>
</View>
)
}
function PostRepostedByScreen({
route,
}: NativeStackScreenProps<CommonNavigatorParams, 'PostRepostedBy'>) {
return (
<View>
<Text>
PostRepostedByScreen {route.params.name} {route.params.rkey}
</Text>
</View>
)
}
function DebugScreen({}: NativeStackScreenProps<
CommonNavigatorParams,
'Debug'
>) {
return (
<View>
<Text>DebugScreen</Text>
</View>
)
}
function LogScreen({}: NativeStackScreenProps<CommonNavigatorParams, 'Log'>) {
return (
<View>
<Text>LogScreen</Text>
</View>
)
}
function DrawerContent() {
return (
@@ -236,7 +311,6 @@ function commonScreens(Stack: ReturnType<typeof createNativeStackNavigator>) {
<Stack.Screen name="ProfileFollows" component={ProfileFollowsScreen} />
<Stack.Screen name="PostThread" component={PostThreadScreen} />
<Stack.Screen name="PostUpvotedBy" component={PostUpvotedByScreen} />
<Stack.Screen name="PostDownvotedBy" component={PostDownvotedByScreen} />
<Stack.Screen name="PostRepostedBy" component={PostRepostedByScreen} />
<Stack.Screen name="Debug" component={DebugScreen} />
<Stack.Screen name="Log" component={LogScreen} />