Bluesky app fork with some witchin' additions 馃挮
at main 111 lines 3.6 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 {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons' 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 enableSquareButtons = useEnableSquareButtons() 32 33 const {data: convoAvailability} = useGetConvoAvailabilityQuery(profile.did) 34 const {mutate: initiateConvo} = useGetConvoForMembers({ 35 onSuccess: ({convo}) => { 36 ax.metric('chat:open', {logContext: 'ProfileHeader'}) 37 navigation.navigate('MessagesConversation', {conversation: convo.id}) 38 }, 39 onError: () => { 40 Toast.show(_(msg`Failed to create conversation`)) 41 }, 42 }) 43 44 const onPress = React.useCallback(() => { 45 if (!convoAvailability?.canChat) { 46 return 47 } 48 49 if (convoAvailability.convo) { 50 ax.metric('chat:open', {logContext: 'ProfileHeader'}) 51 navigation.navigate('MessagesConversation', { 52 conversation: convoAvailability.convo.id, 53 }) 54 } else { 55 ax.metric('chat:create', {logContext: 'ProfileHeader'}) 56 initiateConvo([profile.did]) 57 } 58 }, [ax, navigation, profile.did, initiateConvo, convoAvailability]) 59 60 const wrappedOnPress = requireEmailVerification(onPress, { 61 instructions: [ 62 <Trans key="message"> 63 Before you can message another user, you must first verify your email. 64 </Trans>, 65 ], 66 }) 67 68 if (!convoAvailability) { 69 // show pending state based on declaration 70 if (canBeMessaged(profile)) { 71 return ( 72 <View 73 testID="dmBtnLoading" 74 aria-hidden={true} 75 style={[ 76 a.justify_center, 77 a.align_center, 78 t.atoms.bg_contrast_25, 79 enableSquareButtons ? a.rounded_sm : a.rounded_full, 80 // Matches size of button below to avoid layout shift 81 {width: 33, height: 33}, 82 ]}> 83 <Message style={[t.atoms.text, {opacity: 0.3}]} size="md" /> 84 </View> 85 ) 86 } else { 87 return null 88 } 89 } 90 91 if (convoAvailability.canChat) { 92 return ( 93 <> 94 <Button 95 accessibilityRole="button" 96 testID="dmBtn" 97 size="small" 98 color="secondary" 99 variant="solid" 100 shape={enableSquareButtons ? 'square' : 'round'} 101 label={_(msg`Message ${profile.handle}`)} 102 style={[a.justify_center]} 103 onPress={wrappedOnPress}> 104 <ButtonIcon icon={Message} size="md" /> 105 </Button> 106 </> 107 ) 108 } else { 109 return null 110 } 111}