add invite friends ui

This commit is contained in:
vineyardbovines
2026-05-29 17:21:41 -04:00
parent bccca283b9
commit 42732c8bea
28 changed files with 1762 additions and 25 deletions
@@ -28,6 +28,7 @@ import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {DebugFieldDisplay} from '#/components/DebugFieldDisplay'
import {useDialogControl} from '#/components/Dialog'
import {MessageProfileButton} from '#/components/dms/MessageProfileButton'
import {ArrowShareRight_Stroke2_Corner2_Rounded as ArrowShareRight} from '#/components/icons/ArrowShareRight'
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
import {
KnownFollowers,
@@ -39,6 +40,7 @@ import {RichText} from '#/components/RichText'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {IS_IOS} from '#/env'
import {InviteFriendsDialog} from '#/features/inviteFriends'
import {useActorStatus} from '#/features/liveNow'
import {GermButton} from '../components/GermButton'
import {EditProfileDialog} from './EditProfileDialog'
@@ -247,6 +249,7 @@ export function HeaderStandardButtons({
)
const [, queueUnblock] = useProfileBlockMutationQueue(profile)
const editProfileControl = useDialogControl()
const inviteFriendsControl = useDialogControl()
const unblockPromptControl = Prompt.usePromptControl()
const isMe = currentAccount?.did === profile.did
@@ -347,7 +350,20 @@ export function HeaderStandardButtons({
<Trans>Edit Profile</Trans>
</ButtonText>
</Button>
<Button
testID="profileHeaderShareButton"
size="small"
color="secondary"
shape="round"
onPress={() => {
playHaptic('Light')
inviteFriendsControl.open()
}}
label={_(msg`Invite friends`)}>
<ButtonIcon icon={ArrowShareRight} />
</Button>
<EditProfileDialog profile={profile} control={editProfileControl} />
<InviteFriendsDialog control={inviteFriendsControl} />
</>
) : profile.viewer?.blocking ? (
profile.viewer?.blockingByList ? null : (
+18 -1
View File
@@ -39,6 +39,7 @@ import {atoms as a, tokens, useGutters, useTheme} from '#/alf'
import {Admonition} from '#/components/Admonition'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {ContactsHeroImage} from '#/components/contacts/components/HeroImage'
import {useDialogControl} from '#/components/Dialog'
import {ArrowRotateClockwise_Stroke2_Corner0_Rounded as ResyncIcon} from '#/components/icons/ArrowRotate'
import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from '#/components/icons/Trash'
@@ -50,6 +51,7 @@ import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_NATIVE} from '#/env'
import {InviteFriendsDialog} from '#/features/inviteFriends'
import type * as bsky from '#/types/bsky'
import {bulkWriteFollows} from '../Onboarding/util'
@@ -76,7 +78,7 @@ export function FindContactsSettingsScreen({}: Props) {
<Layout.Header.BackButton />
<Layout.Header.Content>
<Layout.Header.TitleText>
<Trans>Find Friends</Trans>
<Trans>Find and Invite Friends</Trans>
</Layout.Header.TitleText>
</Layout.Header.Content>
<Layout.Header.Slot />
@@ -113,6 +115,7 @@ function Intro() {
const gutter = useGutters(['base'])
const t = useTheme()
const {_} = useLingui()
const inviteFriendsControl = useDialogControl()
const {data: isAvailable, isSuccess} = useQuery({
queryKey: ['contacts-available'],
@@ -122,6 +125,9 @@ function Intro() {
return (
<Layout.Content contentContainerStyle={[gutter, a.gap_lg]}>
<ContactsHeroImage />
<Text style={[a.text_xl, a.font_bold]}>
<Trans>Find people you know</Trans>
</Text>
<Text style={[a.text_md, a.leading_snug, t.atoms.text_contrast_medium]}>
<Trans>
Find your friends on Bluesky by verifying your phone number and
@@ -161,6 +167,17 @@ function Intro() {
</Admonition>
)
)}
<Button
label={_(msg`Share my profile`)}
size="large"
color="secondary"
onPress={() => inviteFriendsControl.open()}
style={[a.flex_1, a.justify_center]}>
<ButtonText>
<Trans>Share my profile</Trans>
</ButtonText>
</Button>
<InviteFriendsDialog control={inviteFriendsControl} />
</Layout.Content>
)
}
+15
View File
@@ -64,6 +64,7 @@ import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_INTERNAL, IS_IOS, IS_NATIVE} from '#/env'
import {InviteFriendsDialog} from '#/features/inviteFriends'
import {useActorStatus} from '#/features/liveNow'
import {device, useStorage} from '#/storage'
import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged'
@@ -76,6 +77,7 @@ export function SettingsScreen({}: Props) {
const {logoutEveryAccount} = useSessionApi()
const {accounts, currentAccount} = useSession()
const switchAccountControl = useDialogControl()
const inviteFriendsControl = useDialogControl()
const signOutPromptControl = Prompt.usePromptControl()
const {data: profile} = useProfileQuery({did: currentAccount?.did})
const {data: otherProfiles} = useProfilesQuery({
@@ -208,6 +210,18 @@ export function SettingsScreen({}: Props) {
<Trans>Content and media</Trans>
</SettingsList.ItemText>
</SettingsList.LinkItem>
{IS_NATIVE && (
<SettingsList.PressableItem
label={l`Find and invite friends`}
accessibilityHint={l`Opens the invite friends sheet to share your profile`}
onPress={() => inviteFriendsControl.open()}>
<SettingsList.ItemIcon icon={ContactsIcon} />
<SettingsList.ItemText>
<Trans>Find and invite friends</Trans>
</SettingsList.ItemText>
<SettingsList.Chevron />
</SettingsList.PressableItem>
)}
{IS_NATIVE &&
findContactsEnabled &&
!ax.features.enabled(ax.features.ImportContactsSettingsDisable) && (
@@ -302,6 +316,7 @@ export function SettingsScreen({}: Props) {
/>
<SwitchAccountDialog control={switchAccountControl} />
<InviteFriendsDialog control={inviteFriendsControl} />
</Layout.Screen>
)
}