forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {View} from 'react-native'
2import {Image} from 'expo-image'
3import {type AppBskyGraphDefs} from '@atproto/api'
4import {msg, Trans} from '@lingui/macro'
5import {useLingui} from '@lingui/react'
6
7import {useSaveImageToMediaLibrary} from '#/lib/media/save-image'
8import {shareUrl} from '#/lib/sharing'
9import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
10import {logger} from '#/logger'
11import {isNative, isWeb} from '#/platform/detection'
12import {atoms as a, useBreakpoints, useTheme} from '#/alf'
13import {Button, ButtonIcon, ButtonText} from '#/components/Button'
14import {type DialogControlProps} from '#/components/Dialog'
15import * as Dialog from '#/components/Dialog'
16import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink'
17import {Download_Stroke2_Corner0_Rounded as DownloadIcon} from '#/components/icons/Download'
18import {QrCode_Stroke2_Corner0_Rounded as QrCodeIcon} from '#/components/icons/QrCode'
19import {Loader} from '#/components/Loader'
20import {Text} from '#/components/Typography'
21
22interface Props {
23 starterPack: AppBskyGraphDefs.StarterPackView
24 link?: string
25 imageLoaded?: boolean
26 qrDialogControl: DialogControlProps
27 control: DialogControlProps
28}
29
30export function ShareDialog(props: Props) {
31 return (
32 <Dialog.Outer
33 control={props.control}
34 nativeOptions={{preventExpansion: true}}>
35 <Dialog.Handle />
36 <ShareDialogInner {...props} />
37 </Dialog.Outer>
38 )
39}
40
41function ShareDialogInner({
42 starterPack,
43 link,
44 imageLoaded,
45 qrDialogControl,
46 control,
47}: Props) {
48 const {_} = useLingui()
49 const t = useTheme()
50 const {gtMobile} = useBreakpoints()
51
52 const imageUrl = getStarterPackOgCard(starterPack)
53
54 const onShareLink = async () => {
55 if (!link) return
56 shareUrl(link)
57 logger.metric('starterPack:share', {
58 starterPack: starterPack.uri,
59 shareType: 'link',
60 })
61 control.close()
62 }
63
64 const saveImageToAlbum = useSaveImageToMediaLibrary()
65
66 const onSave = async () => {
67 await saveImageToAlbum(imageUrl)
68 }
69
70 return (
71 <>
72 <Dialog.ScrollableInner label={_(msg`Share link dialog`)}>
73 {!imageLoaded || !link ? (
74 <View style={[a.align_center, a.justify_center, {minHeight: 350}]}>
75 <Loader size="xl" />
76 </View>
77 ) : (
78 <View style={[!gtMobile && a.gap_lg]}>
79 <View style={[a.gap_sm, gtMobile && a.pb_lg]}>
80 <Text style={[a.font_semi_bold, a.text_2xl]}>
81 <Trans>Invite people to this starter pack!</Trans>
82 </Text>
83 <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
84 <Trans>
85 Share this starter pack and help people join your community on
86 Bluesky.
87 </Trans>
88 </Text>
89 </View>
90 <Image
91 source={{uri: imageUrl}}
92 style={[
93 a.rounded_sm,
94 a.aspect_card,
95 {
96 transform: [{scale: gtMobile ? 0.85 : 1}],
97 marginTop: gtMobile ? -20 : 0,
98 },
99 ]}
100 accessibilityIgnoresInvertColors={true}
101 />
102 <View
103 style={[
104 a.gap_md,
105 gtMobile && [
106 a.gap_sm,
107 a.justify_center,
108 a.flex_row,
109 a.flex_wrap,
110 ],
111 ]}>
112 <Button
113 label={isWeb ? _(msg`Copy link`) : _(msg`Share link`)}
114 color="primary_subtle"
115 size="large"
116 onPress={onShareLink}>
117 <ButtonIcon icon={ChainLinkIcon} />
118 <ButtonText>
119 {isWeb ? <Trans>Copy Link</Trans> : <Trans>Share link</Trans>}
120 </ButtonText>
121 </Button>
122 <Button
123 label={_(msg`Share QR code`)}
124 color="primary_subtle"
125 size="large"
126 onPress={() => {
127 control.close(() => {
128 qrDialogControl.open()
129 })
130 }}>
131 <ButtonIcon icon={QrCodeIcon} />
132 <ButtonText>
133 <Trans>Share QR code</Trans>
134 </ButtonText>
135 </Button>
136 {isNative && (
137 <Button
138 label={_(msg`Save image`)}
139 color="secondary"
140 size="large"
141 onPress={onSave}>
142 <ButtonIcon icon={DownloadIcon} />
143 <ButtonText>
144 <Trans>Save image</Trans>
145 </ButtonText>
146 </Button>
147 )}
148 </View>
149 </View>
150 )}
151 <Dialog.Close />
152 </Dialog.ScrollableInner>
153 </>
154 )
155}