[Contacts] Contacts matching flow (#9486)
* add expo-contacts * add expo-sms * update copy * add basic settings screen * state machine, flow screen * phone input screen * otp screen * tweak spacing * resend code logic * add layoutanimationconfig * check availablility in settings screen * get contacts * matches screen * search, temp setup for matches UI * add a bunch of number parsing logic with libphonenumber * cast to looser type * rename sync to find FCF (Find Contacts Flow) * update geolocation hook * nicer design for settings screen * add completed state * up border contrast * update expo deps * add pending spinner * add country whitelist * add empty state screen * drop add more functionality * upload -> import * fix typo * fix permission string * copy updates * rm envelope icon * update sms copy * add inviteinfo component * woke is back * [Contacts] NUXes (#9515) * add a bunch of number parsing logic with libphonenumber * add banner nux * add announcement nux * native only nux * rm shitty animation * move isNative check * [Contacts] Onboarding step (#9489) * add a bunch of number parsing logic with libphonenumber * restructure onboarding to better support dynamic screens * integrate existing flow into onboarding * add intro step * lift state up to allow going back freely * gate onboarding by geo if unsupported country * add done button to standalone flow * [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 * [Contacts] API integration (#9487) * api integration for flow * copy tweak * tweaks after running it * wire up status page * rename toast * use api lib * rm temp code * maybe fix otp error * clear code on error/resend * add 1s delay to verify success * update package versions * Delete SyncContactsFlow.web.tsx * try and fix yarn.lock lint * even woker * fix uppercase friends * surfdude feedback Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * rm log * allow resend on invalid code * Update GetContacts.tsx * overwrite country code if possible * fix Apple's Best Feature * devenv latest * disable bounces * interactive keyboard dismiss * copy changes * national format * allow resending immediately * move success state down a bit * Update FindContactsSettings.tsx * [Contacts] More onboarding changes (#9491) * integrate existing flow into onboarding * refreshed onboarding styles, rm stepper * center content on web * Add back dismiss button for internal onboarding * Import sort --------- Co-authored-by: Eric Bailey <git@esb.lol> * add matches query to shadow * add clockwise arrow * update status design, fix dismiss, fix queries * add metrics * add more comments * Update metrics.ts * refetch both queries on PTR * fix shadow state in matches page * reduce empty space at bottom * show contact info on matches * filter out contacts without numbers at an earlier stage * Error handling ✨ * get notifs working * filter out businesses * rm log * remove TODO from learn more links * try and exclude from web bundle --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Eric Bailey <git@esb.lol>
This commit is contained in:
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -12,6 +12,7 @@ import {isWeb} from '#/platform/detection'
|
||||
import {useProfileFollowsQuery} from '#/state/queries/profile-follows'
|
||||
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
|
||||
import {useSession} from '#/state/session'
|
||||
import {FindContactsBannerNUX} from '#/components/contacts/FindContactsBannerNUX'
|
||||
import {PeopleRemove2_Stroke1_Corner0_Rounded as PeopleRemoveIcon} from '#/components/icons/PeopleRemove2'
|
||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||
import {List} from '../util/List'
|
||||
@@ -208,6 +209,7 @@ export function ProfileFollows({name}: {name: string}) {
|
||||
onEndReached={onEndReached}
|
||||
onEndReachedThreshold={4}
|
||||
onItemSeen={onItemSeen}
|
||||
ListHeaderComponent={<FindContactsBannerNUX />}
|
||||
ListFooterComponent={
|
||||
<ListFooter
|
||||
isFetchingNextPage={isFetchingNextPage}
|
||||
|
||||
@@ -37,7 +37,7 @@ import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/Do
|
||||
import {Flag_Stroke2_Corner0_Rounded as Flag} from '#/components/icons/Flag'
|
||||
import {ListSparkle_Stroke2_Corner0_Rounded as List} from '#/components/icons/ListSparkle'
|
||||
import {Live_Stroke2_Corner0_Rounded as LiveIcon} from '#/components/icons/Live'
|
||||
import {MagnifyingGlass2_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass2'
|
||||
import {MagnifyingGlass_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass'
|
||||
import {Mute_Stroke2_Corner0_Rounded as Mute} from '#/components/icons/Mute'
|
||||
import {PeopleRemove2_Stroke2_Corner0_Rounded as UserMinus} from '#/components/icons/PeopleRemove2'
|
||||
import {
|
||||
|
||||
@@ -9,7 +9,7 @@ import {useLingui} from '@lingui/react'
|
||||
import {usePalette} from '#/lib/hooks/usePalette'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as ArrowRotateCounterClockwiseIcon} from '#/components/icons/ArrowRotateCounterClockwise'
|
||||
import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as ArrowRotateCounterClockwiseIcon} from '#/components/icons/ArrowRotate'
|
||||
import * as Layout from '#/components/Layout'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user