mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

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

at tooltip 278 lines 8.7 kB view raw
1import React, {useCallback} from 'react' 2import {Keyboard, Pressable, View} from 'react-native' 3import {ChatBskyConvoDefs, ModerationCause} from '@atproto/api' 4import {msg, Trans} from '@lingui/macro' 5import {useLingui} from '@lingui/react' 6import {useNavigation} from '@react-navigation/native' 7 8import {NavigationProp} from '#/lib/routes/types' 9import {Shadow} from '#/state/cache/types' 10import { 11 useConvoQuery, 12 useMarkAsReadMutation, 13} from '#/state/queries/messages/conversation' 14import {useMuteConvo} from '#/state/queries/messages/mute-conversation' 15import {useProfileBlockMutationQueue} from '#/state/queries/profile' 16import * as Toast from '#/view/com/util/Toast' 17import {atoms as a, useTheme, ViewStyleProp} from '#/alf' 18import {BlockedByListDialog} from '#/components/dms/BlockedByListDialog' 19import {LeaveConvoPrompt} from '#/components/dms/LeaveConvoPrompt' 20import {ReportConversationPrompt} from '#/components/dms/ReportConversationPrompt' 21import {ArrowBoxLeft_Stroke2_Corner0_Rounded as ArrowBoxLeft} from '#/components/icons/ArrowBoxLeft' 22import {DotGrid_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid' 23import {Flag_Stroke2_Corner0_Rounded as Flag} from '#/components/icons/Flag' 24import {Mute_Stroke2_Corner0_Rounded as Mute} from '#/components/icons/Mute' 25import { 26 Person_Stroke2_Corner0_Rounded as Person, 27 PersonCheck_Stroke2_Corner0_Rounded as PersonCheck, 28 PersonX_Stroke2_Corner0_Rounded as PersonX, 29} from '#/components/icons/Person' 30import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as Unmute} from '#/components/icons/Speaker' 31import * as Menu from '#/components/Menu' 32import * as Prompt from '#/components/Prompt' 33import * as bsky from '#/types/bsky' 34import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '../icons/Bubble' 35import {ReportDialog} from './ReportDialog' 36 37let ConvoMenu = ({ 38 convo, 39 profile, 40 control, 41 currentScreen, 42 showMarkAsRead, 43 hideTrigger, 44 blockInfo, 45 latestReportableMessage, 46 style, 47}: { 48 convo: ChatBskyConvoDefs.ConvoView 49 profile: Shadow<bsky.profile.AnyProfileView> 50 control?: Menu.MenuControlProps 51 currentScreen: 'list' | 'conversation' 52 showMarkAsRead?: boolean 53 hideTrigger?: boolean 54 blockInfo: { 55 listBlocks: ModerationCause[] 56 userBlock?: ModerationCause 57 } 58 latestReportableMessage?: ChatBskyConvoDefs.MessageView 59 style?: ViewStyleProp['style'] 60}): React.ReactNode => { 61 const {_} = useLingui() 62 const t = useTheme() 63 64 const leaveConvoControl = Prompt.usePromptControl() 65 const reportControl = Prompt.usePromptControl() 66 const blockedByListControl = Prompt.usePromptControl() 67 68 const {listBlocks} = blockInfo 69 70 return ( 71 <> 72 <Menu.Root control={control}> 73 {!hideTrigger && ( 74 <View style={[style]}> 75 <Menu.Trigger label={_(msg`Chat settings`)}> 76 {({props, state}) => ( 77 <Pressable 78 {...props} 79 onPress={() => { 80 Keyboard.dismiss() 81 props.onPress() 82 }} 83 style={[ 84 a.p_sm, 85 a.rounded_full, 86 (state.hovered || state.pressed) && t.atoms.bg_contrast_25, 87 // make sure pfp is in the middle 88 {marginLeft: -10}, 89 ]}> 90 <DotsHorizontal size="md" style={t.atoms.text} /> 91 </Pressable> 92 )} 93 </Menu.Trigger> 94 </View> 95 )} 96 97 <Menu.Outer> 98 <MenuContent 99 profile={profile} 100 showMarkAsRead={showMarkAsRead} 101 blockInfo={blockInfo} 102 convo={convo} 103 leaveConvoControl={leaveConvoControl} 104 reportControl={reportControl} 105 blockedByListControl={blockedByListControl} 106 /> 107 </Menu.Outer> 108 </Menu.Root> 109 110 <LeaveConvoPrompt 111 control={leaveConvoControl} 112 convoId={convo.id} 113 currentScreen={currentScreen} 114 /> 115 {latestReportableMessage ? ( 116 <ReportDialog 117 currentScreen={currentScreen} 118 params={{ 119 type: 'convoMessage', 120 convoId: convo.id, 121 message: latestReportableMessage, 122 }} 123 control={reportControl} 124 /> 125 ) : ( 126 <ReportConversationPrompt control={reportControl} /> 127 )} 128 129 <BlockedByListDialog 130 control={blockedByListControl} 131 listBlocks={listBlocks} 132 /> 133 </> 134 ) 135} 136ConvoMenu = React.memo(ConvoMenu) 137 138function MenuContent({ 139 convo: initialConvo, 140 profile, 141 showMarkAsRead, 142 blockInfo, 143 leaveConvoControl, 144 reportControl, 145 blockedByListControl, 146}: { 147 convo: ChatBskyConvoDefs.ConvoView 148 profile: Shadow<bsky.profile.AnyProfileView> 149 showMarkAsRead?: boolean 150 blockInfo: { 151 listBlocks: ModerationCause[] 152 userBlock?: ModerationCause 153 } 154 leaveConvoControl: Prompt.PromptControlProps 155 reportControl: Prompt.PromptControlProps 156 blockedByListControl: Prompt.PromptControlProps 157}) { 158 const navigation = useNavigation<NavigationProp>() 159 const {_} = useLingui() 160 const {mutate: markAsRead} = useMarkAsReadMutation() 161 162 const {listBlocks, userBlock} = blockInfo 163 const isBlocking = userBlock || !!listBlocks.length 164 const isDeletedAccount = profile.handle === 'missing.invalid' 165 166 const convoId = initialConvo.id 167 const {data: convo} = useConvoQuery(initialConvo) 168 169 const onNavigateToProfile = useCallback(() => { 170 navigation.navigate('Profile', {name: profile.did}) 171 }, [navigation, profile.did]) 172 173 const {mutate: muteConvo} = useMuteConvo(convoId, { 174 onSuccess: data => { 175 if (data.convo.muted) { 176 Toast.show(_(msg({message: 'Chat muted', context: 'toast'}))) 177 } else { 178 Toast.show(_(msg({message: 'Chat unmuted', context: 'toast'}))) 179 } 180 }, 181 onError: () => { 182 Toast.show(_(msg`Could not mute chat`), 'xmark') 183 }, 184 }) 185 186 const [queueBlock, queueUnblock] = useProfileBlockMutationQueue(profile) 187 188 const toggleBlock = React.useCallback(() => { 189 if (listBlocks.length) { 190 blockedByListControl.open() 191 return 192 } 193 194 if (userBlock) { 195 queueUnblock() 196 } else { 197 queueBlock() 198 } 199 }, [userBlock, listBlocks, blockedByListControl, queueBlock, queueUnblock]) 200 201 return isDeletedAccount ? ( 202 <Menu.Item 203 label={_(msg`Leave conversation`)} 204 onPress={() => leaveConvoControl.open()}> 205 <Menu.ItemText> 206 <Trans>Leave conversation</Trans> 207 </Menu.ItemText> 208 <Menu.ItemIcon icon={ArrowBoxLeft} /> 209 </Menu.Item> 210 ) : ( 211 <> 212 <Menu.Group> 213 {showMarkAsRead && ( 214 <Menu.Item 215 label={_(msg`Mark as read`)} 216 onPress={() => markAsRead({convoId})}> 217 <Menu.ItemText> 218 <Trans>Mark as read</Trans> 219 </Menu.ItemText> 220 <Menu.ItemIcon icon={Bubble} /> 221 </Menu.Item> 222 )} 223 <Menu.Item 224 label={_(msg`Go to user's profile`)} 225 onPress={onNavigateToProfile}> 226 <Menu.ItemText> 227 <Trans>Go to profile</Trans> 228 </Menu.ItemText> 229 <Menu.ItemIcon icon={Person} /> 230 </Menu.Item> 231 <Menu.Item 232 label={_(msg`Mute conversation`)} 233 onPress={() => muteConvo({mute: !convo?.muted})}> 234 <Menu.ItemText> 235 {convo?.muted ? ( 236 <Trans>Unmute conversation</Trans> 237 ) : ( 238 <Trans>Mute conversation</Trans> 239 )} 240 </Menu.ItemText> 241 <Menu.ItemIcon icon={convo?.muted ? Unmute : Mute} /> 242 </Menu.Item> 243 </Menu.Group> 244 <Menu.Divider /> 245 <Menu.Group> 246 <Menu.Item 247 label={isBlocking ? _(msg`Unblock account`) : _(msg`Block account`)} 248 onPress={toggleBlock}> 249 <Menu.ItemText> 250 {isBlocking ? _(msg`Unblock account`) : _(msg`Block account`)} 251 </Menu.ItemText> 252 <Menu.ItemIcon icon={isBlocking ? PersonCheck : PersonX} /> 253 </Menu.Item> 254 <Menu.Item 255 label={_(msg`Report conversation`)} 256 onPress={() => reportControl.open()}> 257 <Menu.ItemText> 258 <Trans>Report conversation</Trans> 259 </Menu.ItemText> 260 <Menu.ItemIcon icon={Flag} /> 261 </Menu.Item> 262 </Menu.Group> 263 <Menu.Divider /> 264 <Menu.Group> 265 <Menu.Item 266 label={_(msg`Leave conversation`)} 267 onPress={() => leaveConvoControl.open()}> 268 <Menu.ItemText> 269 <Trans>Leave conversation</Trans> 270 </Menu.ItemText> 271 <Menu.ItemIcon icon={ArrowBoxLeft} /> 272 </Menu.Item> 273 </Menu.Group> 274 </> 275 ) 276} 277 278export {ConvoMenu}