forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 💫
1import {useCallback} from 'react'
2import {View} from 'react-native'
3import {Image} from 'expo-image'
4import {LinearGradient} from 'expo-linear-gradient'
5import {msg} from '@lingui/core/macro'
6import {useLingui} from '@lingui/react'
7import {Trans} from '@lingui/react/macro'
8
9import {atoms as a, useTheme, web} from '#/alf'
10import {Button, ButtonText} from '#/components/Button'
11import {isFindContactsFeatureEnabled} from '#/components/contacts/country-allowlist'
12import * as Dialog from '#/components/Dialog'
13import {useNuxDialogContext} from '#/components/dialogs/nuxs'
14import {
15 createIsEnabledCheck,
16 isExistingUserAsOf,
17} from '#/components/dialogs/nuxs/utils'
18import {Text} from '#/components/Typography'
19import {useAnalytics} from '#/analytics'
20import {IS_E2E, IS_NATIVE, IS_WEB} from '#/env'
21import {navigate} from '#/Navigation'
22
23export const enabled = createIsEnabledCheck(props => {
24 return (
25 !IS_E2E &&
26 IS_NATIVE &&
27 isExistingUserAsOf(
28 '2025-12-16T00:00:00.000Z',
29 props.currentProfile.createdAt,
30 ) &&
31 isFindContactsFeatureEnabled(props.geolocation.countryCode)
32 )
33})
34
35export function FindContactsAnnouncement() {
36 const t = useTheme()
37 const {_} = useLingui()
38 const ax = useAnalytics()
39 const nuxDialogs = useNuxDialogContext()
40 const control = Dialog.useDialogControl()
41
42 Dialog.useAutoOpen(control)
43
44 const onClose = useCallback(() => {
45 nuxDialogs.dismissActiveNux()
46 }, [nuxDialogs])
47
48 return (
49 <Dialog.Outer
50 control={control}
51 onClose={onClose}
52 nativeOptions={{preventExpansion: true}}>
53 <Dialog.Handle />
54
55 <Dialog.ScrollableInner
56 label={_(msg`Introducing finding friends via contacts`)}
57 style={[web({maxWidth: 440})]}
58 contentContainerStyle={[
59 {
60 paddingTop: 0,
61 paddingLeft: 0,
62 paddingRight: 0,
63 },
64 ]}>
65 <View style={[a.align_center, a.pt_3xl]}>
66 <LinearGradient
67 colors={[t.palette.primary_200, t.atoms.bg.backgroundColor]}
68 locations={[0, 1]}
69 start={{x: 0, y: 0}}
70 end={{x: 0, y: 1}}
71 style={[a.absolute, a.inset_0]}
72 />
73 <View style={[a.w_full, a.pt_sm, a.px_5xl, a.pb_4xl]}>
74 <Image
75 accessibilityIgnoresInvertColors
76 source={require('../../../../assets/images/find_friends_illustration.webp')}
77 style={[a.w_full, {aspectRatio: 1278 / 661}]}
78 alt={_(
79 msg`An illustration depicting user avatars flowing from a contact book into the Bluesky app`,
80 )}
81 />
82 </View>
83 </View>
84 <View style={[a.align_center, a.px_xl, a.gap_5xl]}>
85 <View style={[a.gap_sm, a.align_center]}>
86 <Text
87 style={[
88 a.text_4xl,
89 a.leading_tight,
90 a.font_bold,
91 a.text_center,
92 {
93 fontSize: IS_WEB ? 28 : 32,
94 maxWidth: 300,
95 },
96 ]}>
97 <Trans>Find your friends</Trans>
98 </Text>
99 <Text
100 style={[
101 a.text_md,
102 t.atoms.text_contrast_medium,
103 a.leading_snug,
104 a.text_center,
105 {maxWidth: 340},
106 ]}>
107 <Trans>
108 Bluesky is more fun with friends! Import your contacts to see
109 who’s already here.
110 </Trans>
111 </Text>
112 </View>
113
114 <Button
115 label={_(msg`Import Contacts`)}
116 size="large"
117 color="primary"
118 onPress={() => {
119 ax.metric('contacts:nux:ctaPressed', {})
120 control.close(() => {
121 navigate('FindContactsFlow')
122 })
123 }}
124 style={[a.w_full]}>
125 <ButtonText>
126 <Trans>Import Contacts</Trans>
127 </ButtonText>
128 </Button>
129 </View>
130
131 <Dialog.Close />
132 </Dialog.ScrollableInner>
133 </Dialog.Outer>
134 )
135}