mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
1import {View} from 'react-native'
2import {Image} from 'expo-image'
3import {requestMediaLibraryPermissionsAsync} from 'expo-image-picker'
4import {AppBskyGraphDefs} from '@atproto/api'
5import {msg, Trans} from '@lingui/macro'
6import {useLingui} from '@lingui/react'
7
8import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
9import {saveImageToMediaLibrary} from '#/lib/media/manip'
10import {shareUrl} from '#/lib/sharing'
11import {logEvent} from '#/lib/statsig/statsig'
12import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
13import {logger} from '#/logger'
14import {isNative, isWeb} from '#/platform/detection'
15import * as Toast from '#/view/com/util/Toast'
16import {atoms as a, useTheme} from '#/alf'
17import {Button, ButtonText} from '#/components/Button'
18import {DialogControlProps} from '#/components/Dialog'
19import * as Dialog from '#/components/Dialog'
20import {Loader} from '#/components/Loader'
21import {Text} from '#/components/Typography'
22
23interface Props {
24 starterPack: AppBskyGraphDefs.StarterPackView
25 link?: string
26 imageLoaded?: boolean
27 qrDialogControl: DialogControlProps
28 control: DialogControlProps
29}
30
31export function ShareDialog(props: Props) {
32 return (
33 <Dialog.Outer control={props.control}>
34 <Dialog.Handle />
35 <ShareDialogInner {...props} />
36 </Dialog.Outer>
37 )
38}
39
40function ShareDialogInner({
41 starterPack,
42 link,
43 imageLoaded,
44 qrDialogControl,
45 control,
46}: Props) {
47 const {_} = useLingui()
48 const t = useTheme()
49 const {isTabletOrDesktop} = useWebMediaQueries()
50
51 const imageUrl = getStarterPackOgCard(starterPack)
52
53 const onShareLink = async () => {
54 if (!link) return
55 shareUrl(link)
56 logEvent('starterPack:share', {
57 starterPack: starterPack.uri,
58 shareType: 'link',
59 })
60 control.close()
61 }
62
63 const onSave = async () => {
64 const res = await requestMediaLibraryPermissionsAsync()
65
66 if (!res) {
67 Toast.show(
68 _(msg`You must grant access to your photo library to save the image.`),
69 'xmark',
70 )
71 return
72 }
73
74 try {
75 await saveImageToMediaLibrary({uri: imageUrl})
76 Toast.show(_(msg`Image saved to your camera roll!`))
77 control.close()
78 } catch (e: unknown) {
79 Toast.show(_(msg`An error occurred while saving the QR code!`), 'xmark')
80 logger.error('Failed to save QR code', {error: e})
81 return
82 }
83 }
84
85 return (
86 <>
87 <Dialog.ScrollableInner label={_(msg`Share link dialog`)}>
88 {!imageLoaded || !link ? (
89 <View style={[a.p_xl, a.align_center]}>
90 <Loader size="xl" />
91 </View>
92 ) : (
93 <View style={[!isTabletOrDesktop && a.gap_lg]}>
94 <View style={[a.gap_sm, isTabletOrDesktop && a.pb_lg]}>
95 <Text style={[a.font_bold, a.text_2xl]}>
96 <Trans>Invite people to this starter pack!</Trans>
97 </Text>
98 <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
99 <Trans>
100 Share this starter pack and help people join your community on
101 Bluesky.
102 </Trans>
103 </Text>
104 </View>
105 <Image
106 source={{uri: imageUrl}}
107 style={[
108 a.rounded_sm,
109 {
110 aspectRatio: 1200 / 630,
111 transform: [{scale: isTabletOrDesktop ? 0.85 : 1}],
112 marginTop: isTabletOrDesktop ? -20 : 0,
113 },
114 ]}
115 accessibilityIgnoresInvertColors={true}
116 />
117 <View
118 style={[
119 a.gap_md,
120 isWeb && [a.gap_sm, a.flex_row_reverse, {marginLeft: 'auto'}],
121 ]}>
122 <Button
123 label={isWeb ? _(msg`Copy link`) : _(msg`Share link`)}
124 variant="solid"
125 color="secondary"
126 size="small"
127 style={[isWeb && a.self_center]}
128 onPress={onShareLink}>
129 <ButtonText>
130 {isWeb ? <Trans>Copy Link</Trans> : <Trans>Share link</Trans>}
131 </ButtonText>
132 </Button>
133 <Button
134 label={_(msg`Share QR code`)}
135 variant="solid"
136 color="secondary"
137 size="small"
138 style={[isWeb && a.self_center]}
139 onPress={() => {
140 control.close(() => {
141 qrDialogControl.open()
142 })
143 }}>
144 <ButtonText>
145 <Trans>Share QR code</Trans>
146 </ButtonText>
147 </Button>
148 {isNative && (
149 <Button
150 label={_(msg`Save image`)}
151 variant="ghost"
152 color="secondary"
153 size="small"
154 style={[isWeb && a.self_center]}
155 onPress={onSave}>
156 <ButtonText>
157 <Trans>Save image</Trans>
158 </ButtonText>
159 </Button>
160 )}
161 </View>
162 </View>
163 )}
164 </Dialog.ScrollableInner>
165 </>
166 )
167}