add inviteinfo component

This commit is contained in:
Samuel Newman
2025-12-10 11:56:46 +02:00
parent ff393d608e
commit a13fd7a789
2 changed files with 109 additions and 5 deletions
@@ -0,0 +1,85 @@
import {type StyleProp, type TextStyle} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {HITSLOP_20} from '#/lib/constants'
import {android, atoms as a} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {CircleInfo_Stroke2_Corner0_Rounded as InfoIcon} from '#/components/icons/CircleInfo'
import {Text} from '#/components/Typography'
export function InviteInfo({
iconStyle,
iconOffset = 0,
}: {
iconStyle: StyleProp<TextStyle>
/**
* Adjust the vertical position of the icon via `translateY`
*
* @platform android
*/
iconOffset?: number
}) {
const {_} = useLingui()
const control = Dialog.useDialogControl()
const style = [a.text_md, a.leading_snug, a.mt_xs]
return (
<>
<Button
label={_(msg`Learn more about how inviting friends works`)}
onPress={control.open}
hitSlop={HITSLOP_20}
style={android({transform: [{translateY: iconOffset}]})}>
<InfoIcon style={iconStyle} size="sm" />
</Button>
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
<Dialog.Handle />
<Dialog.ScrollableInner label={_(msg`Invite Friends`)}>
<Text style={[a.text_2xl, a.font_bold]}>
<Trans>Invite Friends</Trans>
</Text>
<Text style={style}>
<Trans>
It looks like some of your contacts have not tried to find you
here yet. You can personally invite them by customizing a draft
message we will provide.
</Trans>
</Text>
<Text style={[style, a.font_medium, a.mt_lg]}>
<Trans>How it works:</Trans>
</Text>
<Text style={style}>
&bull; <Trans>Choose who to invite</Trans>
</Text>
<Text style={style}>
&bull; <Trans>Personalize the message</Trans>
</Text>
<Text style={style}>
&bull; <Trans>Send the message from your phone</Trans>
</Text>
<Text style={style}>
&bull;{' '}
<Trans>
We don't store your friends' phone numbers or send any messages
</Trans>
</Text>
<Button
label={_(msg`Done`)}
onPress={() => control.close()}
size="large"
color="primary"
style={[a.mt_2xl]}>
<ButtonText>
<Trans>Done</Trans>
</ButtonText>
</Button>
</Dialog.ScrollableInner>
</Dialog.Outer>
</>
)
}
@@ -35,6 +35,7 @@ import * as ProfileCard from '#/components/ProfileCard'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import type * as bsky from '#/types/bsky'
import {InviteInfo} from '../components/InviteInfo'
import {type Action, type Contact, type State} from '../state'
type Item =
@@ -71,6 +72,7 @@ export function ViewMatches({
state: Extract<State, {step: '4: view matches'}>
dispatch: React.ActionDispatch<[Action]>
}) {
const t = useTheme()
const {_} = useLingui()
const gutter = useGutters([0, 'wide'])
const moderationOpts = useModerationOpts()
@@ -278,15 +280,32 @@ export function ViewMatches({
</Header>
)
case 'contacts header':
return <Header titleText={_(msg`Invite friends`)} hasContentAbove />
return (
<Header
titleText={
<Trans>
Invite friends{' '}
<InviteInfo iconStyle={t.atoms.text} iconOffset={1} />
</Trans>
}
hasContentAbove
/>
)
case 'no matches header':
return (
<Header
titleText={_(msg`You got here first`)}
largeTitle
subtitleText={_(
msg`Bluesky is more fun with friends. Do you want to invite some of yours?`,
)}
subtitleText={
<Trans>
Bluesky is more fun with friends. Do you want to invite some of
yours?{' '}
<InviteInfo
iconStyle={t.atoms.text_contrast_medium}
iconOffset={2}
/>
</Trans>
}
/>
)
case 'search empty state':
@@ -402,7 +421,7 @@ function ContactItem({contact}: {contact: Contact}) {
const {_} = useLingui()
const {currentAccount} = useSession()
const name = contact.firstName ?? contact.lastName
const name = contact.firstName ?? contact.lastName ?? contact.name
const phone =
contact.phoneNumbers?.find(phone => phone.isPrimary) ??
contact.phoneNumbers?.[0]