memoize bottom bar
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user