[Contacts] Add contact-match notification type to feed (#9519)

* add a bunch of number parsing logic with libphonenumber

* add contact-joined notif type

* update string, api package

* Update NotificationFeedItem.tsx

* Update NotificationFeedItem.tsx

* Delete SyncContactsFlow.web.tsx

* fix follow back btn for this case
This commit is contained in:
Samuel Newman
2025-12-10 22:00:08 +02:00
parent d4dedf463a
commit 2f06eff36c
6 changed files with 173 additions and 120 deletions
+4
View File
@@ -3,3 +3,7 @@ import {createSinglePathSVG} from './TEMPLATE'
export const Contacts_Stroke2_Corner2_Rounded = createSinglePathSVG({
path: 'M7 4a1 1 0 0 0-1 1v12.05q.243-.05.5-.05H18V4H7Zm5 7c.894 0 1.57.188 2.068.513.445.29.683.647.806.937l.046.12c.285.836-.43 1.43-1.03 1.43h-3.78c-.6 0-1.315-.594-1.03-1.43l.046-.12c.123-.29.361-.647.806-.937C10.43 11.188 11.106 11 12 11Zm0-4a1.75 1.75 0 1 1 0 3.5A1.75 1.75 0 0 1 12 7Zm8 11a1 1 0 0 1-1 1H6.5a.5.5 0 0 0 0 1H19a1 1 0 1 1 0 2H6.5A2.5 2.5 0 0 1 4 19.5V5a3 3 0 0 1 3-3h11a2 2 0 0 1 2 2v14Z',
})
export const Contacts_Filled_Corner2_Rounded = createSinglePathSVG({
path: 'M7 2a3 3 0 0 0-3 3v14.5A2.5 2.5 0 0 0 6.5 22H19a1 1 0 1 0 0-2H6.5a.5.5 0 0 1 0-1H19a1 1 0 0 0 1-1V4a2 2 0 0 0-2-2H7Zm5 5a1.75 1.75 0 1 0 0 3.5A1.75 1.75 0 0 0 12 7Zm0 4c-.894 0-1.57.188-2.068.512a2.07 2.07 0 0 0-.852 1.058c-.286.838.432 1.43 1.03 1.43h3.78c.598 0 1.316-.592 1.03-1.43a2.07 2.07 0 0 0-.852-1.058C13.57 11.189 12.894 11 12 11Z',
})
+1
View File
@@ -49,6 +49,7 @@ type OtherNotificationType =
| 'like-via-repost'
| 'repost-via-repost'
| 'subscribed-post'
| 'contact-match'
| 'unknown'
type FeedNotificationBase = {
@@ -1,11 +1,4 @@
import {
memo,
type ReactElement,
useCallback,
useEffect,
useMemo,
useState,
} from 'react'
import {memo, useCallback, useEffect, useMemo, useState} from 'react'
import {
Animated,
type GestureResponderEvent,
@@ -61,6 +54,7 @@ import {
ChevronBottom_Stroke2_Corner0_Rounded as ChevronDownIcon,
ChevronTop_Stroke2_Corner0_Rounded as ChevronUpIcon,
} from '#/components/icons/Chevron'
import {Contacts_Filled_Corner2_Rounded as ContactsIconFilled} from '#/components/icons/Contacts'
import {Heart2_Filled_Stroke2_Corner0_Rounded as HeartIconFilled} from '#/components/icons/Heart2'
import {PersonPlus_Filled_Stroke2_Corner0_Rounded as PersonPlusIcon} from '#/components/icons/Person'
import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus'
@@ -116,6 +110,7 @@ let NotificationFeedItem = ({
break
}
case 'follow':
case 'contact-match':
case 'verified':
case 'unverified': {
return makeProfileLink(item.notification.author)
@@ -279,7 +274,7 @@ let NotificationFeedItem = ({
: ''
let a11yLabel = ''
let notificationContent: ReactElement<any>
let notificationContent: React.ReactElement<any>
let icon = (
<HeartIconFilled
size="xl"
@@ -373,6 +368,14 @@ let NotificationFeedItem = ({
)
}
icon = <PersonPlusIcon size="xl" style={{color: t.palette.primary_500}} />
} else if (item.type === 'contact-match') {
a11yLabel = _(msg`Your contact ${firstAuthorName} is on Bluesky`)
notificationContent = (
<Trans>Your contact {firstAuthorLink} is on Bluesky</Trans>
)
icon = (
<ContactsIconFilled size="xl" style={{color: t.palette.primary_500}} />
)
} else if (item.type === 'feedgen-like') {
a11yLabel = hasMultipleAuthors
? _(
@@ -438,7 +441,7 @@ let NotificationFeedItem = ({
notificationContent = hasMultipleAuthors ? (
<Trans>
{firstAuthorLink} and{' '}
<Text style={[pal.text, s.bold]}>
<Text style={[a.text_md, a.font_semi_bold, a.leading_snug]}>
<Plural
value={additionalAuthorsCount}
one={`${formattedAuthorsCount} other`}
@@ -463,7 +466,7 @@ let NotificationFeedItem = ({
notificationContent = hasMultipleAuthors ? (
<Trans>
{firstAuthorLink} and{' '}
<Text style={[pal.text, s.bold]}>
<Text style={[a.text_md, a.font_semi_bold, a.leading_snug]}>
<Plural
value={additionalAuthorsCount}
one={`${formattedAuthorsCount} other`}
@@ -670,7 +673,9 @@ let NotificationFeedItem = ({
</TimeElapsed>
</Text>
</ExpandListPressable>
{item.type === 'follow' && !hasMultipleAuthors && !isFollowBack ? (
{(item.type === 'follow' && !hasMultipleAuthors && !isFollowBack) ||
(item.type === 'contact-match' &&
!item.notification.author.viewer?.following) ? (
<FollowBackButton profile={item.notification.author} />
) : null}
{item.type === 'post-like' ||
@@ -809,6 +814,7 @@ function FollowBackButton({profile}: {profile: AppBskyActorDefs.ProfileView}) {
}
const isFollowing = profileShadow.viewer.following
const isFollowedBy = profileShadow.viewer.followedBy
const followingLabel = _(
msg({
message: 'Following',
@@ -832,14 +838,14 @@ function FollowBackButton({profile}: {profile: AppBskyActorDefs.ProfileView}) {
</Button>
) : (
<Button
label={_(msg`Follow back`)}
label={isFollowedBy ? _(msg`Follow back`) : _(msg`Follow`)}
color="primary"
size="small"
style={[a.self_start]}
onPress={onPressFollow}>
<ButtonIcon icon={PlusIcon} />
<ButtonText>
<Trans>Follow back</Trans>
{isFollowedBy ? <Trans>Follow back</Trans> : <Trans>Follow</Trans>}
</ButtonText>
</Button>
)}