diff --git a/apps/mobile/src/components/browse/BrowseLocations.tsx b/apps/mobile/src/components/browse/BrowseLocations.tsx index 6ceadd16c..dc4020184 100644 --- a/apps/mobile/src/components/browse/BrowseLocations.tsx +++ b/apps/mobile/src/components/browse/BrowseLocations.tsx @@ -1,8 +1,8 @@ import { useNavigation } from '@react-navigation/native'; +import { useCache, useLibraryQuery, useNodes } from '@sd/client'; import { DotsThreeOutline, Plus } from 'phosphor-react-native'; import { useRef } from 'react'; import { Text, View } from 'react-native'; -import { useCache, useLibraryQuery, useNodes } from '@sd/client'; import { ModalRef } from '~/components/layout/Modal'; import { tw } from '~/lib/tailwind'; import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack'; diff --git a/apps/mobile/src/components/browse/BrowseTags.tsx b/apps/mobile/src/components/browse/BrowseTags.tsx index fa74e98d8..9b5cc0ef0 100644 --- a/apps/mobile/src/components/browse/BrowseTags.tsx +++ b/apps/mobile/src/components/browse/BrowseTags.tsx @@ -1,8 +1,8 @@ import { useNavigation } from '@react-navigation/native'; +import { useCache, useLibraryQuery, useNodes } from '@sd/client'; import { DotsThreeOutline, Plus } from 'phosphor-react-native'; import React, { useRef } from 'react'; import { Text, View } from 'react-native'; -import { useCache, useLibraryQuery, useNodes } from '@sd/client'; import { ModalRef } from '~/components/layout/Modal'; import { tw } from '~/lib/tailwind'; import { BrowseStackScreenProps } from '~/navigation/tabs/BrowseStack'; diff --git a/apps/mobile/src/components/header/DynamicHeader.tsx b/apps/mobile/src/components/header/DynamicHeader.tsx new file mode 100644 index 000000000..5973280f3 --- /dev/null +++ b/apps/mobile/src/components/header/DynamicHeader.tsx @@ -0,0 +1,110 @@ +import { DrawerNavigationHelpers } from '@react-navigation/drawer/lib/typescript/src/types'; +import { RouteProp, useNavigation } from '@react-navigation/native'; +import { NativeStackHeaderProps } from '@react-navigation/native-stack'; +import { ArrowLeft, DotsThreeOutline, MagnifyingGlass } from 'phosphor-react-native'; +import { Platform, Pressable, Text, View } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { tw, twStyle } from '~/lib/tailwind'; +import { getExplorerStore, useExplorerStore } from '~/stores/explorerStore'; +import { Icon } from '../icons/Icon'; + + +type Props = { + headerRoute?: NativeStackHeaderProps; //supporting title from the options object of navigation + optionsRoute?: RouteProp; //supporting params passed + kind: 'tag' | 'location'; //the kind of icon to display + explorerMenu?: boolean; //whether to show the explorer menu +}; + +export default function DynamicHeader({ + headerRoute, + optionsRoute, + kind, + explorerMenu = true +}: Props) { + const navigation = useNavigation(); + const headerHeight = useSafeAreaInsets().top; + const isAndroid = Platform.OS === 'android'; + const explorerStore = useExplorerStore(); + + return ( + + + + + navigation.goBack()} + > + + + + + + {headerRoute?.options.title} + + + + + {explorerMenu && { + getExplorerStore().toggleMenu = !explorerStore.toggleMenu; + }} + > + + } + { + navigation.navigate('SearchStack', { + screen: 'Search' + }); + }} + > + + + + + + + ); +} + +interface HeaderIconKindProps { + routeParams?: any; + kind: Props['kind']; +} + +const HeaderIconKind = ({routeParams, kind }: HeaderIconKindProps) => { + switch (kind) { + case 'location': + return ; + case 'tag': + return ( + + ); + default: + return null; + } +}; diff --git a/apps/mobile/src/components/header/Header.tsx b/apps/mobile/src/components/header/Header.tsx index b864af58b..a60fd4b2e 100644 --- a/apps/mobile/src/components/header/Header.tsx +++ b/apps/mobile/src/components/header/Header.tsx @@ -1,48 +1,25 @@ import { DrawerNavigationHelpers } from '@react-navigation/drawer/lib/typescript/src/types'; -import { useNavigation } from '@react-navigation/native'; -import { NativeStackHeaderProps } from '@react-navigation/native-stack'; -import { ArrowLeft, DotsThreeOutline, List, MagnifyingGlass } from 'phosphor-react-native'; +import { RouteProp, useNavigation } from '@react-navigation/native'; +import { ArrowLeft, List, MagnifyingGlass } from 'phosphor-react-native'; import { Platform, Pressable, Text, View } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { tw, twStyle } from '~/lib/tailwind'; -import { getExplorerStore, useExplorerStore } from '~/stores/explorerStore'; -import { Icon } from '../icons/Icon'; -import Search from '../search/Search'; - -type HeaderProps = { - title?: string; //title of the page - showSearch?: boolean; //show the search button - showDrawer?: boolean; //show the drawer button - searchType?: 'explorer' | 'location' | 'categories' | 'tags'; //Temporary - navBack?: boolean; //navigate back to the previous screen - headerKind?: 'default' | 'location' | 'tag'; //kind of header - route?: never; - routeTitle?: never; +type Props = { + route?: RouteProp; // supporting title from the options object of navigation + navBack?: boolean; // whether to show the back icon + search?: boolean; // whether to show the search icon + title?: string; // in some cases - we want to override the route title }; -//you can pass in a routeTitle only if route is passed in -type Props = - | HeaderProps - | ({ - route: NativeStackHeaderProps; - routeTitle?: boolean; - } & Omit); - // Default header with search bar and button to open drawer export default function Header({ - title, - searchType, - navBack, route, - routeTitle, - headerKind = 'default', - showDrawer = false, - showSearch = false, + navBack, + title, + search = false }: Props) { const navigation = useNavigation(); - const explorerStore = useExplorerStore(); - const routeParams = route?.route.params as any; const headerHeight = useSafeAreaInsets().top; const isAndroid = Platform.OS === 'android'; @@ -55,35 +32,22 @@ export default function Header({ - {navBack && ( + {navBack ? ( { - navigation.goBack(); - }} - > - - - )} - - - {showDrawer && ( - navigation.openDrawer()}> - - - )} - - {title || (routeTitle && route?.options.title)} - - + hitSlop={24} + onPress={() => navigation.goBack()} + > + + + + ) : ( + navigation.openDrawer()}> + + + )} + {title || route?.name} - - {showSearch && ( - - { navigation.navigate('SearchStack', { @@ -96,69 +60,9 @@ export default function Header({ weight="bold" color={tw.color('text-zinc-300')} /> - - - )} - {(headerKind === 'location' || headerKind === 'tag') && ( - { - getExplorerStore().toggleMenu = !explorerStore.toggleMenu; - }} - > - - - )} - + } - {searchType && } ); } - -interface HeaderSearchTypeProps { - searchType: HeaderProps['searchType']; -} - -const HeaderSearchType = ({ searchType }: HeaderSearchTypeProps) => { - switch (searchType) { - case 'explorer': - return 'Explorer'; //TODO - case 'location': - return ; - case 'tags': - return ; - case 'categories': - return ; - default: - return null; - } -}; - -interface HeaderIconKindProps { - headerKind: HeaderProps['headerKind']; - routeParams?: any; -} - -const HeaderIconKind = ({ headerKind, routeParams }: HeaderIconKindProps) => { - switch (headerKind) { - case 'location': - return ; - case 'tag': - return ( - - ); - default: - return null; - } -}; diff --git a/apps/mobile/src/components/header/SearchHeader.tsx b/apps/mobile/src/components/header/SearchHeader.tsx new file mode 100644 index 000000000..0312f6544 --- /dev/null +++ b/apps/mobile/src/components/header/SearchHeader.tsx @@ -0,0 +1,53 @@ +import { DrawerNavigationHelpers } from '@react-navigation/drawer/lib/typescript/src/types'; +import { RouteProp, useNavigation } from '@react-navigation/native'; +import { ArrowLeft } from 'phosphor-react-native'; +import { Platform, Pressable, Text, View } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { tw, twStyle } from '~/lib/tailwind'; +import Search from '../search/Search'; + + +const searchPlaceholder = { + locations: 'Search location name...', + tags: 'Search tag name...', + categories: 'Search category name...', +} + +type Props = { + route?: RouteProp; // supporting title from the options object of navigation + kind: keyof typeof searchPlaceholder; // the kind of search we are doing + title?: string; // in some cases - we want to override the route title +}; + +export default function SearchHeader({ + route, + kind, + title +}: Props) { + const navigation = useNavigation(); + const headerHeight = useSafeAreaInsets().top; + const isAndroid = Platform.OS === 'android'; + + return ( + + + + + navigation.goBack()} + > + + + {title || route?.name} + + + + + + ); +} diff --git a/apps/mobile/src/navigation/SearchStack.tsx b/apps/mobile/src/navigation/SearchStack.tsx index 60ec90aa1..647e7b550 100644 --- a/apps/mobile/src/navigation/SearchStack.tsx +++ b/apps/mobile/src/navigation/SearchStack.tsx @@ -21,7 +21,7 @@ export default function SearchStack() { component={FiltersScreen} options={{ header: () => { - return
; + return
; } }} /> diff --git a/apps/mobile/src/navigation/tabs/BrowseStack.tsx b/apps/mobile/src/navigation/tabs/BrowseStack.tsx index f5873ccc7..cdf751c55 100644 --- a/apps/mobile/src/navigation/tabs/BrowseStack.tsx +++ b/apps/mobile/src/navigation/tabs/BrowseStack.tsx @@ -8,6 +8,8 @@ import LocationsScreen from '~/screens/browse/Locations'; import TagScreen from '~/screens/browse/Tag'; import TagsScreen from '~/screens/browse/Tags'; +import DynamicHeader from '~/components/header/DynamicHeader'; +import SearchHeader from '~/components/header/SearchHeader'; import { TabScreenProps } from '../TabNavigator'; const Stack = createNativeStackNavigator(); @@ -18,44 +20,44 @@ export default function BrowseStack() {
}} + options={({route}) => ({ + header: () =>
+ })} /> ( -
- ) - }} + options={({route: optionsRoute}) => ({ + header: (route) => + })} />
- }} + options={({route}) => ({ + header: () => + })} />
- }} + options={({route}) => ({ + header: () => + })} />
- }} + options={({route: optionsRoute}) => ({ + header: (route) => + })} />
- }} + options={({route}) => ({ + header: () =>
+ })} /> ); diff --git a/apps/mobile/src/navigation/tabs/NetworkStack.tsx b/apps/mobile/src/navigation/tabs/NetworkStack.tsx index 137ba3711..25171b516 100644 --- a/apps/mobile/src/navigation/tabs/NetworkStack.tsx +++ b/apps/mobile/src/navigation/tabs/NetworkStack.tsx @@ -13,7 +13,9 @@ export default function NetworkStack() {
}} + options={({route}) => ({ + header: () =>
+ })} /> ); diff --git a/apps/mobile/src/navigation/tabs/OverviewStack.tsx b/apps/mobile/src/navigation/tabs/OverviewStack.tsx index f4c104815..ac0dd6068 100644 --- a/apps/mobile/src/navigation/tabs/OverviewStack.tsx +++ b/apps/mobile/src/navigation/tabs/OverviewStack.tsx @@ -1,9 +1,10 @@ import { CompositeScreenProps } from '@react-navigation/native'; import { createNativeStackNavigator, NativeStackScreenProps } from '@react-navigation/native-stack'; -import Header from '~/components/header/Header'; import CategoriesScreen from '~/screens/overview/Categories'; import OverviewScreen from '~/screens/overview/Overview'; +import Header from '~/components/header/Header'; +import SearchHeader from '~/components/header/SearchHeader'; import { TabScreenProps } from '../TabNavigator'; const Stack = createNativeStackNavigator(); @@ -14,14 +15,16 @@ export default function OverviewStack() {
}} + options={({route}) => ({ + header: () =>
+ })} />
- }} + options={({route}) => ({ + header: () => + })} /> ); diff --git a/apps/mobile/src/navigation/tabs/SettingsStack.tsx b/apps/mobile/src/navigation/tabs/SettingsStack.tsx index f3949bd59..1ace6dded 100644 --- a/apps/mobile/src/navigation/tabs/SettingsStack.tsx +++ b/apps/mobile/src/navigation/tabs/SettingsStack.tsx @@ -18,6 +18,7 @@ import NodesSettingsScreen from '~/screens/settings/library/NodesSettings'; import TagsSettingsScreen from '~/screens/settings/library/TagsSettings'; import SettingsScreen from '~/screens/settings/Settings'; +import SearchHeader from '~/components/header/SearchHeader'; import { TabScreenProps } from '../TabNavigator'; const Stack = createNativeStackNavigator(); @@ -28,7 +29,9 @@ export default function SettingsStack() {
}} + options={({route}) => ({ + header: () =>
+ })} /> {/* Client */}
- }} + options={() => ({ + header: () => + })} />