-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add tab bar header navigation #5082
Changes from 18 commits
fafb4ac
c2bd286
11bd86b
d2f0fc9
932b4ec
a544525
dddd0c4
fdba8da
2ffe340
0cdac6b
95a5c43
2aeef88
26ffb10
926aa3a
585a26f
9551481
8111b63
2597590
e2846b7
d5cc11c
74a55b5
c4cf8fe
51af4d9
54e3825
af9d1c8
ce2177b
fc03d3e
f588a88
f70e4ca
3a4ac76
2133d98
beb06fe
f155a47
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2179,7 +2179,8 @@ | |
"title": "Welcome" | ||
}, | ||
"discover": { | ||
"tabName": "Discover" | ||
"tabName": "Discover", | ||
"title": "Discover" | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from 'react' | ||
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native' | ||
import Touchable from 'src/components/Touchable' | ||
import AccountCircle from 'src/icons/AccountCircle' | ||
import { navigate } from 'src/navigator/NavigationService' | ||
import { Screens } from 'src/navigator/Screens' | ||
import { Spacing } from 'src/styles/styles' | ||
|
||
interface Props { | ||
style?: StyleProp<ViewStyle> | ||
size?: number | ||
testID?: string | ||
} | ||
|
||
export default function AccountCircleButton({ style, size, testID }: Props) { | ||
const onPress = () => { | ||
navigate(Screens.ProfileMenu) | ||
} | ||
|
||
return ( | ||
<View style={styles.container}> | ||
<Touchable | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Touchable used here and in other added icons instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this something TopBarIconButton can support? if not, is there a purpose of keeping TopBarIconButton around? |
||
testID={testID} | ||
onPress={onPress} | ||
style={[style, styles.button]} | ||
borderRadius={Spacing.Thick24} | ||
> | ||
<AccountCircle size={size} /> | ||
</Touchable> | ||
</View> | ||
) | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
container: { | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
}, | ||
button: { | ||
padding: Spacing.Small12, | ||
}, | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,17 @@ | ||
import { NativeStackScreenProps } from '@react-navigation/native-stack' | ||
import React, { useEffect, useMemo, useRef, useState } from 'react' | ||
import { useTranslation } from 'react-i18next' | ||
import { RefreshControl, SectionList, SectionListProps, StyleSheet, Text, View } from 'react-native' | ||
import { | ||
LayoutChangeEvent, | ||
RefreshControl, | ||
SectionList, | ||
SectionListProps, | ||
StyleSheet, | ||
Text, | ||
View, | ||
} from 'react-native' | ||
import { ScrollView } from 'react-native-gesture-handler' | ||
import Animated from 'react-native-reanimated' | ||
import Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated' | ||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context' | ||
import { DappExplorerEvents } from 'src/analytics/Events' | ||
import ValoraAnalytics from 'src/analytics/ValoraAnalytics' | ||
|
@@ -31,10 +39,11 @@ | |
import DrawerTopBar from 'src/navigator/DrawerTopBar' | ||
import { styles as headerStyles } from 'src/navigator/Headers' | ||
import { Screens } from 'src/navigator/Screens' | ||
import useScrollAwareHeader from 'src/navigator/ScrollAwareHeader' | ||
import { StackParamList } from 'src/navigator/types' | ||
import { useDispatch, useSelector } from 'src/redux/hooks' | ||
import colors from 'src/styles/colors' | ||
import fontStyles from 'src/styles/fonts' | ||
import colors, { Colors } from 'src/styles/colors' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: could we just use the default export or the named export? I believe both point to the same object There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Switched to using the named export in 74a55b5. |
||
import fontStyles, { typeScale } from 'src/styles/fonts' | ||
import { Spacing } from 'src/styles/styles' | ||
|
||
const AnimatedSectionList = | ||
|
@@ -52,7 +61,7 @@ | |
Screens.DAppsExplorerScreen | Screens.TabDiscover | ||
> | ||
|
||
export function DAppsExplorerScreenSearchFilter({ route }: Props) { | ||
export function DAppsExplorerScreenSearchFilter({ navigation, route }: Props) { | ||
const { t } = useTranslation() | ||
|
||
// temporary parameter while we build the tab navigator, should be cleaned up | ||
|
@@ -62,11 +71,11 @@ | |
const insets = useSafeAreaInsets() | ||
|
||
const sectionListRef = useRef<SectionList>(null) | ||
const scrollPosition = useRef(new Animated.Value(0)).current | ||
const scrollPositionValue = useRef(new Animated.Value(0)).current | ||
const horizontalScrollView = useRef<ScrollView>(null) | ||
const dappRankingsBottomSheetRef = useRef<BottomSheetRefType>(null) | ||
|
||
const onScroll = Animated.event([{ nativeEvent: { contentOffset: { y: scrollPosition } } }]) | ||
const onScroll = Animated.event([{ nativeEvent: { contentOffset: { y: scrollPositionValue } } }]) | ||
const dispatch = useDispatch() | ||
const loading = useSelector(dappsListLoadingSelector) | ||
const error = useSelector(dappsListErrorSelector) | ||
|
@@ -136,6 +145,28 @@ | |
}) | ||
} | ||
|
||
// Scroll Aware Header | ||
const scrollPosition = useSharedValue(0) | ||
const [titleHeight, setTitleHeight] = useState(0) | ||
|
||
const handleMeasureTitleHeight = (event: LayoutChangeEvent) => { | ||
setTitleHeight(event.nativeEvent.layout.height) | ||
} | ||
|
||
const handleScroll = useAnimatedScrollHandler((event) => { | ||
Animated.event([{ nativeEvent: { contentOffset: { y: scrollPositionValue } } }]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved to calling onScroll in e2846b7 and I no longer see the error. |
||
scrollPosition.value = event.contentOffset.y | ||
}) | ||
|
||
useScrollAwareHeader({ | ||
navigation, | ||
title: isTabNavigator ? t('bottomTabsNavigator.discover.title') : '', | ||
titleStyle: isTabNavigator ? { ...typeScale.labelSemiBoldMedium } : null, | ||
scrollPosition, | ||
startFadeInPosition: titleHeight - titleHeight * 0.33, | ||
animationDistance: titleHeight * 0.33, | ||
}) | ||
|
||
const sections: SectionData[] = useMemo(() => { | ||
const dappsMatchingFilter = selectedFilter | ||
? nonFavoriteDappsWithCategoryNames.filter((dapp) => selectedFilter.filterFn(dapp)) | ||
|
@@ -193,7 +224,7 @@ | |
<DrawerTopBar | ||
rightElement={<QrScanButton testID={'DAppsExplorerScreen/QRScanButton'} />} | ||
middleElement={<Text style={headerStyles.headerTitle}>{t('dappsScreen.title')}</Text>} | ||
scrollPosition={scrollPosition} | ||
scrollPosition={scrollPositionValue} | ||
/> | ||
)} | ||
<> | ||
|
@@ -221,6 +252,11 @@ | |
} | ||
ListHeaderComponent={ | ||
<> | ||
{isTabNavigator && ( | ||
<Text onLayout={handleMeasureTitleHeight} style={styles.title}> | ||
{t('bottomTabsNavigator.discover.title')} | ||
</Text> | ||
)} | ||
<DappFeaturedActions onPressShowDappRankings={handleShowDappRankings} /> | ||
<SearchInput | ||
onChangeText={(text) => { | ||
|
@@ -252,7 +288,7 @@ | |
// Workaround iOS setting an incorrect automatic inset at the top | ||
scrollIndicatorInsets={{ top: 0.01 }} | ||
scrollEventThrottle={16} | ||
onScroll={onScroll} | ||
onScroll={isTabNavigator ? handleScroll : onScroll} | ||
sections={sections} | ||
renderItem={({ item: dapp, index, section }) => { | ||
return ( | ||
|
@@ -343,6 +379,11 @@ | |
flex: 1, | ||
justifyContent: 'flex-end', | ||
}, | ||
title: { | ||
...typeScale.titleMedium, | ||
color: Colors.black, | ||
marginBottom: Spacing.Large32, | ||
}, | ||
}) | ||
|
||
export default DAppsExplorerScreenSearchFilter |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,11 @@ | |
import EscrowedPaymentListItem from 'src/escrow/EscrowedPaymentListItem' | ||
import { getReclaimableEscrowPayments } from 'src/escrow/reducer' | ||
import i18n from 'src/i18n' | ||
import { | ||
NotificationList, | ||
titleWithBalanceNavigationOptions, | ||
} from 'src/notifications/NotificationList' | ||
import { HeaderTitleWithBalance, headerWithBackButton } from 'src/navigator/Headers' | ||
import { NotificationList } from 'src/notifications/NotificationList' | ||
import { useSelector } from 'src/redux/hooks' | ||
import { Spacing } from 'src/styles/styles' | ||
import { Currency } from 'src/utils/currencies' | ||
|
||
export const listItemRenderer = (payment: EscrowedPayment, key: number | undefined = undefined) => { | ||
return ( | ||
|
@@ -24,9 +23,12 @@ | |
return <NotificationList items={sentEscrowedPayments} listItemRenderer={listItemRenderer} /> | ||
} | ||
|
||
EscrowedPaymentListScreen.navigationOptions = titleWithBalanceNavigationOptions( | ||
i18n.t('escrowedPaymentReminder') | ||
) | ||
EscrowedPaymentListScreen.navigationOptions = () => ({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed due to a failing test case in 2aeef88. |
||
...headerWithBackButton, | ||
headerTitle: () => ( | ||
<HeaderTitleWithBalance title={i18n.t('escrowedPaymentReminder')} token={Currency.Dollar} /> | ||
), | ||
}) | ||
|
||
const styles = StyleSheet.create({ | ||
listItem: { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add an analytics event for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in c4cf8fe!