memoize bottom bar
This commit is contained in:
@@ -121,26 +121,8 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
accountSwitchControl.open()
|
||||
}, [accountSwitchControl, playHaptic])
|
||||
|
||||
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"
|
||||
icon={
|
||||
const renderHomeIcon = React.useCallback(
|
||||
() =>
|
||||
isAtHome ? (
|
||||
<HomeFilled
|
||||
width={iconWidth + 1}
|
||||
@@ -151,15 +133,12 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
width={iconWidth + 1}
|
||||
style={[styles.ctrlIcon, pal.text, styles.homeIcon]}
|
||||
/>
|
||||
),
|
||||
[isAtHome, pal.text],
|
||||
)
|
||||
}
|
||||
onPress={onPressHome}
|
||||
accessibilityRole="tab"
|
||||
accessibilityLabel={_(msg`Home`)}
|
||||
accessibilityHint=""
|
||||
/>
|
||||
<Btn
|
||||
icon={
|
||||
|
||||
const renderSearchIcon = React.useCallback(
|
||||
() =>
|
||||
isAtSearch ? (
|
||||
<MagnifyingGlassFilled
|
||||
width={iconWidth + 2}
|
||||
@@ -171,16 +150,12 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
width={iconWidth + 2}
|
||||
style={[styles.ctrlIcon, pal.text, styles.searchIcon]}
|
||||
/>
|
||||
),
|
||||
[isAtSearch, pal.text],
|
||||
)
|
||||
}
|
||||
onPress={onPressSearch}
|
||||
accessibilityRole="search"
|
||||
accessibilityLabel={_(msg`Search`)}
|
||||
accessibilityHint=""
|
||||
/>
|
||||
<Btn
|
||||
testID="bottomBarMessagesBtn"
|
||||
icon={
|
||||
|
||||
const renderMessagesIcon = React.useCallback(
|
||||
() =>
|
||||
isAtMessages ? (
|
||||
<MessageFilled
|
||||
width={iconWidth - 1}
|
||||
@@ -191,22 +166,12 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
width={iconWidth - 1}
|
||||
style={[styles.ctrlIcon, pal.text, styles.feedsIcon]}
|
||||
/>
|
||||
),
|
||||
[isAtMessages, pal.text],
|
||||
)
|
||||
}
|
||||
onPress={onPressMessages}
|
||||
notificationCount={numUnreadMessages.numUnread}
|
||||
accessible={true}
|
||||
accessibilityRole="tab"
|
||||
accessibilityLabel={_(msg`Chat`)}
|
||||
accessibilityHint={
|
||||
numUnreadMessages.count > 0
|
||||
? _(msg`${numUnreadMessages.numUnread} unread items`)
|
||||
: ''
|
||||
}
|
||||
/>
|
||||
<Btn
|
||||
testID="bottomBarNotificationsBtn"
|
||||
icon={
|
||||
|
||||
const renderNotificationsIcon = React.useCallback(
|
||||
() =>
|
||||
isAtNotifications ? (
|
||||
<BellFilled
|
||||
width={iconWidth}
|
||||
@@ -217,22 +182,12 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
width={iconWidth}
|
||||
style={[styles.ctrlIcon, pal.text, styles.bellIcon]}
|
||||
/>
|
||||
),
|
||||
[isAtNotifications, pal.text],
|
||||
)
|
||||
}
|
||||
onPress={onPressNotifications}
|
||||
notificationCount={numUnreadNotifications}
|
||||
accessible={true}
|
||||
accessibilityRole="tab"
|
||||
accessibilityLabel={_(msg`Notifications`)}
|
||||
accessibilityHint={
|
||||
numUnreadNotifications === ''
|
||||
? ''
|
||||
: _(msg`${numUnreadNotifications} unread items`)
|
||||
}
|
||||
/>
|
||||
<Btn
|
||||
testID="bottomBarProfileBtn"
|
||||
icon={
|
||||
|
||||
const renderProfileIcon = React.useCallback(
|
||||
() => (
|
||||
<View style={styles.ctrlIconSizingWrapper}>
|
||||
{isAtMyProfile ? (
|
||||
<View
|
||||
@@ -252,8 +207,7 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View
|
||||
style={[styles.ctrlIcon, pal.text, styles.profileIcon]}>
|
||||
<View style={[styles.ctrlIcon, pal.text, styles.profileIcon]}>
|
||||
<UserAvatar
|
||||
avatar={profile?.avatar}
|
||||
size={iconWidth - 3}
|
||||
@@ -264,7 +218,74 @@ export function BottomBar({navigation}: BottomTabBarProps) {
|
||||
</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}
|
||||
onLongPress={onLongPressProfile}
|
||||
accessibilityRole="tab"
|
||||
@@ -332,22 +353,22 @@ interface BtnProps
|
||||
| 'accessibilityLabel'
|
||||
> {
|
||||
testID?: string
|
||||
icon: JSX.Element
|
||||
renderIcon: () => React.ReactNode
|
||||
notificationCount?: string
|
||||
onPress?: (event: GestureResponderEvent) => void
|
||||
onLongPress?: (event: GestureResponderEvent) => void
|
||||
}
|
||||
|
||||
function Btn({
|
||||
let Btn = ({
|
||||
testID,
|
||||
icon,
|
||||
renderIcon,
|
||||
notificationCount,
|
||||
onPress,
|
||||
onLongPress,
|
||||
accessible,
|
||||
accessibilityHint,
|
||||
accessibilityLabel,
|
||||
}: BtnProps) {
|
||||
}: BtnProps): React.ReactNode => {
|
||||
return (
|
||||
<PressableScale
|
||||
testID={testID}
|
||||
@@ -358,7 +379,7 @@ function Btn({
|
||||
accessibilityLabel={accessibilityLabel}
|
||||
accessibilityHint={accessibilityHint}
|
||||
targetScale={0.8}>
|
||||
{icon}
|
||||
{renderIcon()}
|
||||
{notificationCount ? (
|
||||
<View style={[styles.notificationCount, a.rounded_full]}>
|
||||
<Text style={styles.notificationCountLabel}>{notificationCount}</Text>
|
||||
@@ -367,3 +388,4 @@ function Btn({
|
||||
</PressableScale>
|
||||
)
|
||||
}
|
||||
Btn = React.memo(Btn)
|
||||
|
||||
Reference in New Issue
Block a user