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