forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
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}