memoize bottom bar

This commit is contained in:
Samuel Newman
2024-11-12 18:26:36 +00:00
parent df3f71286d
commit e38d5400a7
+96 -74
View File
@@ -121,26 +121,8 @@ export function BottomBar({navigation}: BottomTabBarProps) {
accountSwitchControl.open() accountSwitchControl.open()
}, [accountSwitchControl, playHaptic]) }, [accountSwitchControl, playHaptic])
return ( const renderHomeIcon = React.useCallback(
<> () =>
<SwitchAccountDialog control={accountSwitchControl} />
<Animated.View
style={[
styles.bottomBar,
pal.view,
pal.border,
{paddingBottom: clamp(safeAreaInsets.bottom, 15, 30)},
footerMinimalShellTransform,
]}
onLayout={e => {
footerHeight.value = e.nativeEvent.layout.height
}}>
{hasSession ? (
<>
<Btn
testID="bottomBarHomeBtn"
icon={
isAtHome ? ( isAtHome ? (
<HomeFilled <HomeFilled
width={iconWidth + 1} width={iconWidth + 1}
@@ -151,15 +133,12 @@ export function BottomBar({navigation}: BottomTabBarProps) {
width={iconWidth + 1} width={iconWidth + 1}
style={[styles.ctrlIcon, pal.text, styles.homeIcon]} style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
/> />
),
[isAtHome, pal.text],
) )
}
onPress={onPressHome} const renderSearchIcon = React.useCallback(
accessibilityRole="tab" () =>
accessibilityLabel={_(msg`Home`)}
accessibilityHint=""
/>
<Btn
icon={
isAtSearch ? ( isAtSearch ? (
<MagnifyingGlassFilled <MagnifyingGlassFilled
width={iconWidth + 2} width={iconWidth + 2}
@@ -171,16 +150,12 @@ export function BottomBar({navigation}: BottomTabBarProps) {
width={iconWidth + 2} width={iconWidth + 2}
style={[styles.ctrlIcon, pal.text, styles.searchIcon]} style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
/> />
),
[isAtSearch, pal.text],
) )
}
onPress={onPressSearch} const renderMessagesIcon = React.useCallback(
accessibilityRole="search" () =>
accessibilityLabel={_(msg`Search`)}
accessibilityHint=""
/>
<Btn
testID="bottomBarMessagesBtn"
icon={
isAtMessages ? ( isAtMessages ? (
<MessageFilled <MessageFilled
width={iconWidth - 1} width={iconWidth - 1}
@@ -191,22 +166,12 @@ export function BottomBar({navigation}: BottomTabBarProps) {
width={iconWidth - 1} width={iconWidth - 1}
style={[styles.ctrlIcon, pal.text, styles.feedsIcon]} style={[styles.ctrlIcon, pal.text, styles.feedsIcon]}
/> />
),
[isAtMessages, pal.text],
) )
}
onPress={onPressMessages} const renderNotificationsIcon = React.useCallback(
notificationCount={numUnreadMessages.numUnread} () =>
accessible={true}
accessibilityRole="tab"
accessibilityLabel={_(msg`Chat`)}
accessibilityHint={
numUnreadMessages.count > 0
? _(msg`${numUnreadMessages.numUnread} unread items`)
: ''
}
/>
<Btn
testID="bottomBarNotificationsBtn"
icon={
isAtNotifications ? ( isAtNotifications ? (
<BellFilled <BellFilled
width={iconWidth} width={iconWidth}
@@ -217,22 +182,12 @@ export function BottomBar({navigation}: BottomTabBarProps) {
width={iconWidth} width={iconWidth}
style={[styles.ctrlIcon, pal.text, styles.bellIcon]} style={[styles.ctrlIcon, pal.text, styles.bellIcon]}
/> />
),
[isAtNotifications, pal.text],
) )
}
onPress={onPressNotifications} const renderProfileIcon = React.useCallback(
notificationCount={numUnreadNotifications} () => (
accessible={true}
accessibilityRole="tab"
accessibilityLabel={_(msg`Notifications`)}
accessibilityHint={
numUnreadNotifications === ''
? ''
: _(msg`${numUnreadNotifications} unread items`)
}
/>
<Btn
testID="bottomBarProfileBtn"
icon={
<View style={styles.ctrlIconSizingWrapper}> <View style={styles.ctrlIconSizingWrapper}>
{isAtMyProfile ? ( {isAtMyProfile ? (
<View <View
@@ -252,8 +207,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
/> />
</View> </View>
) : ( ) : (
<View <View style={[styles.ctrlIcon, pal.text, styles.profileIcon]}>
style={[styles.ctrlIcon, pal.text, styles.profileIcon]}>
<UserAvatar <UserAvatar
avatar={profile?.avatar} avatar={profile?.avatar}
size={iconWidth - 3} size={iconWidth - 3}
@@ -264,7 +218,74 @@ export function BottomBar({navigation}: BottomTabBarProps) {
</View> </View>
)} )}
</View> </View>
),
[isAtMyProfile, profile?.avatar, profile?.associated?.labeler, pal.text],
)
return (
<>
<SwitchAccountDialog control={accountSwitchControl} />
<Animated.View
style={[
styles.bottomBar,
pal.view,
pal.border,
{paddingBottom: clamp(safeAreaInsets.bottom, 15, 30)},
footerMinimalShellTransform,
]}
onLayout={e => {
footerHeight.value = e.nativeEvent.layout.height
}}>
{hasSession ? (
<>
<Btn
testID="bottomBarHomeBtn"
renderIcon={renderHomeIcon}
onPress={onPressHome}
accessibilityRole="tab"
accessibilityLabel={_(msg`Home`)}
accessibilityHint=""
/>
<Btn
testID="bottomBarSearchBtn"
renderIcon={renderSearchIcon}
onPress={onPressSearch}
accessibilityRole="search"
accessibilityLabel={_(msg`Search`)}
accessibilityHint=""
/>
<Btn
testID="bottomBarMessagesBtn"
renderIcon={renderMessagesIcon}
onPress={onPressMessages}
notificationCount={numUnreadMessages.numUnread}
accessible={true}
accessibilityRole="tab"
accessibilityLabel={_(msg`Chat`)}
accessibilityHint={
numUnreadMessages.count > 0
? _(msg`${numUnreadMessages.numUnread} unread items`)
: ''
} }
/>
<Btn
testID="bottomBarNotificationsBtn"
renderIcon={renderNotificationsIcon}
onPress={onPressNotifications}
notificationCount={numUnreadNotifications}
accessible={true}
accessibilityRole="tab"
accessibilityLabel={_(msg`Notifications`)}
accessibilityHint={
numUnreadNotifications === ''
? ''
: _(msg`${numUnreadNotifications} unread items`)
}
/>
<Btn
testID="bottomBarProfileBtn"
renderIcon={renderProfileIcon}
onPress={onPressProfile} onPress={onPressProfile}
onLongPress={onLongPressProfile} onLongPress={onLongPressProfile}
accessibilityRole="tab" accessibilityRole="tab"
@@ -332,22 +353,22 @@ interface BtnProps
| 'accessibilityLabel' | 'accessibilityLabel'
> { > {
testID?: string testID?: string
icon: JSX.Element renderIcon: () => React.ReactNode
notificationCount?: string notificationCount?: string
onPress?: (event: GestureResponderEvent) => void onPress?: (event: GestureResponderEvent) => void
onLongPress?: (event: GestureResponderEvent) => void onLongPress?: (event: GestureResponderEvent) => void
} }
function Btn({ let Btn = ({
testID, testID,
icon, renderIcon,
notificationCount, notificationCount,
onPress, onPress,
onLongPress, onLongPress,
accessible, accessible,
accessibilityHint, accessibilityHint,
accessibilityLabel, accessibilityLabel,
}: BtnProps) { }: BtnProps): React.ReactNode => {
return ( return (
<PressableScale <PressableScale
testID={testID} testID={testID}
@@ -358,7 +379,7 @@ function Btn({
accessibilityLabel={accessibilityLabel} accessibilityLabel={accessibilityLabel}
accessibilityHint={accessibilityHint} accessibilityHint={accessibilityHint}
targetScale={0.8}> targetScale={0.8}>
{icon} {renderIcon()}
{notificationCount ? ( {notificationCount ? (
<View style={[styles.notificationCount, a.rounded_full]}> <View style={[styles.notificationCount, a.rounded_full]}>
<Text style={styles.notificationCountLabel}>{notificationCount}</Text> <Text style={styles.notificationCountLabel}>{notificationCount}</Text>
@@ -367,3 +388,4 @@ function Btn({
</PressableScale> </PressableScale>
) )
} }
Btn = React.memo(Btn)