Address remaining PR review feedback for invite friends

- Pin "New Feature" tag color to lightPalette in the announcement NUX so
  it stays legible against the always-light header illustration in dark
  mode (APP-2349)
- Replace useEffect+eslint-disable with useCallOnce for the
  invite:nux:presented metric in InviteFriendsAnnouncement
- Close the drawer when tapping share-to-invite so the dialog doesn't
  open over a still-open drawer
- Lift the FollowersPromoBanner out of the empty-state early-return in
  ProfileFollowers so it renders independently of the placeholder/list
  switch
This commit is contained in:
vineyardbovines
2026-06-09 12:49:53 -04:00
parent 2e48d5c030
commit 27ab4af139
3 changed files with 49 additions and 41 deletions
@@ -3,7 +3,9 @@ import {View} from 'react-native'
import {Image} from 'expo-image'
import {Trans, useLingui} from '@lingui/react/macro'
import {useCallOnce} from '#/lib/once'
import {atoms as a, useTheme, web} from '#/alf'
import {themes} from '#/alf/themes'
import {Button, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {useNuxDialogContext} from '#/components/dialogs/nuxs'
@@ -28,11 +30,12 @@ export function InviteFriendsAnnouncement() {
Dialog.useAutoOpen(control)
useEffect(() => {
const firePresented = useCallOnce(() => {
ax.metric('invite:nux:presented', {})
// Fire once on mount - the NUX has a single lifecycle per session.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
})
useEffect(() => {
firePresented()
}, [firePresented])
const onClose = useCallback(() => {
nuxDialogs.dismissActiveNux()
@@ -87,10 +90,16 @@ export function InviteFriendsAnnouncement() {
a.align_center,
{top: 0, left: 0, right: 0, paddingTop: IS_WEB ? 24 : 20},
]}>
{/* Pinned to the light palette: the header illustration has a
fixed light background, so the tag must stay dark in any
theme to remain legible. */}
<View style={[a.flex_row, a.align_center, a.gap_xs]}>
<SparkleIcon fill={t.palette.primary_800} size="sm" />
<SparkleIcon fill={themes.lightPalette.primary_800} size="sm" />
<Text
style={[a.font_semi_bold, {color: t.palette.primary_800}]}>
style={[
a.font_semi_bold,
{color: themes.lightPalette.primary_800},
]}>
<Trans>New Feature</Trans>
</Text>
</View>
+33 -35
View File
@@ -184,15 +184,15 @@ export function ProfileFollowers({name}: {name: string}) {
!isFollowersLoading &&
!isError
if (followers.length < 1) {
return (
<>
{showFollowersPromo && (
<FollowersPromoBanner
onPress={() => navigation.navigate('FindContactsSettings')}
onDismiss={() => setFollowersPromoDismissed(true)}
/>
)}
return (
<>
{showFollowersPromo && (
<FollowersPromoBanner
onPress={() => navigation.navigate('FindContactsSettings')}
onDismiss={() => setFollowersPromoDismissed(true)}
/>
)}
{followers.length < 1 ? (
<ListMaybePlaceholder
isLoading={isDidLoading || isFollowersLoading}
isError={isError}
@@ -215,32 +215,30 @@ export function ProfileFollowers({name}: {name: string}) {
onPress: () => navigation.goBack(),
}}
/>
</>
)
}
return (
<List
data={followers}
renderItem={renderItemWithContext}
keyExtractor={keyExtractor}
refreshing={isPTRing}
onRefresh={onRefresh}
onEndReached={onEndReached}
onEndReachedThreshold={4}
onItemSeen={onItemSeen}
ListFooterComponent={
<ListFooter
isFetchingNextPage={isFetchingNextPage}
error={cleanError(error)}
onRetry={fetchNextPage}
) : (
<List
data={followers}
renderItem={renderItemWithContext}
keyExtractor={keyExtractor}
refreshing={isPTRing}
onRefresh={onRefresh}
onEndReached={onEndReached}
onEndReachedThreshold={4}
onItemSeen={onItemSeen}
ListFooterComponent={
<ListFooter
isFetchingNextPage={isFetchingNextPage}
error={cleanError(error)}
onRetry={fetchNextPage}
/>
}
// @ts-ignore our .web version only -prf
desktopFixedHeight
initialNumToRender={initialNumToRender}
windowSize={11}
sideBorders={false}
/>
}
// @ts-ignore our .web version only -prf
desktopFixedHeight
initialNumToRender={initialNumToRender}
windowSize={11}
sideBorders={false}
/>
)}
</>
)
}
+1
View File
@@ -331,6 +331,7 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => {
IS_NATIVE
? () => {
ax.metric('invite:dialog:open', {logContext: 'Drawer'})
setDrawerOpen(false)
inviteFriendsControl.open()
}
: undefined