Bluesky app fork with some witchin' additions 馃挮
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at ece6dc251cdb7eaf260819a4005b3a3e3e74ac8b 109 lines 3.4 kB view raw
1import React from 'react' 2import {View} from 'react-native' 3import {type AppBskyActorDefs} from '@atproto/api' 4import {msg} from '@lingui/core/macro' 5import {useLingui} from '@lingui/react' 6import {Trans} from '@lingui/react/macro' 7import {useNavigation} from '@react-navigation/native' 8 9import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification' 10import {type NavigationProp} from '#/lib/routes/types' 11import {useGetConvoAvailabilityQuery} from '#/state/queries/messages/get-convo-availability' 12import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members' 13import * as Toast from '#/view/com/util/Toast' 14import {atoms as a, useTheme} from '#/alf' 15import {Button, ButtonIcon} from '#/components/Button' 16import {canBeMessaged} from '#/components/dms/util' 17import {Message_Stroke2_Corner0_Rounded as Message} from '#/components/icons/Message' 18import {useAnalytics} from '#/analytics' 19 20export function MessageProfileButton({ 21 profile, 22}: { 23 profile: AppBskyActorDefs.ProfileViewDetailed 24}) { 25 const {_} = useLingui() 26 const t = useTheme() 27 const ax = useAnalytics() 28 const navigation = useNavigation<NavigationProp>() 29 const requireEmailVerification = useRequireEmailVerification() 30 31 const {data: convoAvailability} = useGetConvoAvailabilityQuery(profile.did) 32 const {mutate: initiateConvo} = useGetConvoForMembers({ 33 onSuccess: ({convo}) => { 34 ax.metric('chat:open', {logContext: 'ProfileHeader'}) 35 navigation.navigate('MessagesConversation', {conversation: convo.id}) 36 }, 37 onError: () => { 38 Toast.show(_(msg`Failed to create conversation`)) 39 }, 40 }) 41 42 const onPress = React.useCallback(() => { 43 if (!convoAvailability?.canChat) { 44 return 45 } 46 47 if (convoAvailability.convo) { 48 ax.metric('chat:open', {logContext: 'ProfileHeader'}) 49 navigation.navigate('MessagesConversation', { 50 conversation: convoAvailability.convo.id, 51 }) 52 } else { 53 ax.metric('chat:create', {logContext: 'ProfileHeader'}) 54 initiateConvo([profile.did]) 55 } 56 }, [ax, navigation, profile.did, initiateConvo, convoAvailability]) 57 58 const wrappedOnPress = requireEmailVerification(onPress, { 59 instructions: [ 60 <Trans key="message"> 61 Before you can message another user, you must first verify your email. 62 </Trans>, 63 ], 64 }) 65 66 if (!convoAvailability) { 67 // show pending state based on declaration 68 if (canBeMessaged(profile)) { 69 return ( 70 <View 71 testID="dmBtnLoading" 72 aria-hidden={true} 73 style={[ 74 a.justify_center, 75 a.align_center, 76 t.atoms.bg_contrast_25, 77 a.rounded_full, 78 // Matches size of button below to avoid layout shift 79 {width: 33, height: 33}, 80 ]}> 81 <Message style={[t.atoms.text, {opacity: 0.3}]} size="md" /> 82 </View> 83 ) 84 } else { 85 return null 86 } 87 } 88 89 if (convoAvailability.canChat) { 90 return ( 91 <> 92 <Button 93 accessibilityRole="button" 94 testID="dmBtn" 95 size="small" 96 color="secondary" 97 variant="solid" 98 shape="round" 99 label={_(msg`Message ${profile.handle}`)} 100 style={[a.justify_center]} 101 onPress={wrappedOnPress}> 102 <ButtonIcon icon={Message} size="md" /> 103 </Button> 104 </> 105 ) 106 } else { 107 return null 108 } 109}