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