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