From c995eb2f2fa3e73dcc6943078c85cd6a68f5370b Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Tue, 4 Mar 2025 13:54:19 +0000 Subject: DMs inbox (#7778) * improve error screen * add chat request prompt * mock up inbox * bigger button * use two-button layout * get inbox working somewhat * fix type errors * fetch both pages for badge * don't include read convos in preview * in-chat ui for non-accepted convos (part 1) * add chatstatusinfo * fix status info not disappearing * get chat status info working * change min item height * move files around * add updated sdk * improve badge behaviour * mock up mark all as read * update sdk to 0.14.4 * hide chat status info if initiating convo * fix unread count for deleted accounts * add toasts after rejection * add prompt to delete * adjust badge on desktop * requests -> chat requests * fix height flicker * add mark as read button to header * add mark all as read APIs * separate avatarstack into two components (#7845) * fix messages being hidden behind chatstatusinfo * show inbox preview on empty state * fix empty state again * Use new convo availability API (#7812) * [Inbox] Accept button on convo screen (#7795) * accept button on convo screen * fix types * fix type error * improve spacing * [DMs] Implement new log types (#7835) * optimise badge state * add read message log * add isLogAcceptConvo * mute/unmute convo logs * use setqueriesdata * always show label on button * optimistically update badge * change incorrect unread count change * Update src/screens/Messages/Inbox.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/screens/Messages/components/RequestButtons.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/screens/Messages/components/RequestButtons.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update src/screens/Messages/components/RequestListItem.tsx Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * fix race condition with accepting convo * fix back button on web * filter left convos from badge * update atproto to fix CI * Add accept override external to convo (#7891) * Add accept override external to convo * rm log --------- Co-authored-by: Samuel Newman --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> Co-authored-by: Eric Bailey --- src/screens/Messages/components/RequestButtons.tsx | 254 +++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 src/screens/Messages/components/RequestButtons.tsx (limited to 'src/screens/Messages/components/RequestButtons.tsx') diff --git a/src/screens/Messages/components/RequestButtons.tsx b/src/screens/Messages/components/RequestButtons.tsx new file mode 100644 index 000000000..023cbff2d --- /dev/null +++ b/src/screens/Messages/components/RequestButtons.tsx @@ -0,0 +1,254 @@ +import {useCallback} from 'react' +import {ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {StackActions, useNavigation} from '@react-navigation/native' +import {useQueryClient} from '@tanstack/react-query' + +import {NavigationProp} from '#/lib/routes/types' +import {useProfileShadow} from '#/state/cache/profile-shadow' +import {useAcceptConversation} from '#/state/queries/messages/accept-conversation' +import {precacheConvoQuery} from '#/state/queries/messages/conversation' +import {useLeaveConvo} from '#/state/queries/messages/leave-conversation' +import {useProfileBlockMutationQueue} from '#/state/queries/profile' +import * as Toast from '#/view/com/util/Toast' +import {atoms as a} from '#/alf' +import {Button, ButtonIcon, ButtonProps, ButtonText} from '#/components/Button' +import {useDialogControl} from '#/components/Dialog' +import {ReportDialog} from '#/components/dms/ReportDialog' +import {CircleX_Stroke2_Corner0_Rounded} from '#/components/icons/CircleX' +import {Flag_Stroke2_Corner0_Rounded as FlagIcon} from '#/components/icons/Flag' +import {PersonX_Stroke2_Corner0_Rounded as PersonXIcon} from '#/components/icons/Person' +import {Loader} from '#/components/Loader' +import * as Menu from '#/components/Menu' + +export function RejectMenu({ + convo, + profile, + size = 'tiny', + variant = 'outline', + color = 'secondary', + label, + showDeleteConvo, + currentScreen, + ...props +}: Omit & { + label?: string + convo: ChatBskyConvoDefs.ConvoView + profile: ChatBskyActorDefs.ProfileViewBasic + showDeleteConvo?: boolean + currentScreen: 'list' | 'conversation' +}) { + const {_} = useLingui() + const shadowedProfile = useProfileShadow(profile) + const navigation = useNavigation() + const {mutate: leaveConvo} = useLeaveConvo(convo.id, { + onMutate: () => { + if (currentScreen === 'conversation') { + navigation.dispatch(StackActions.pop()) + } + }, + onError: () => { + Toast.show(_('Failed to delete chat'), 'xmark') + }, + }) + const [queueBlock] = useProfileBlockMutationQueue(shadowedProfile) + + const onPressDelete = useCallback(() => { + Toast.show(_('Chat deleted'), 'check') + leaveConvo() + }, [leaveConvo, _]) + + const onPressBlock = useCallback(() => { + Toast.show(_('Account blocked'), 'check') + // block and also delete convo + queueBlock() + leaveConvo() + }, [queueBlock, leaveConvo, _]) + + const reportControl = useDialogControl() + + const lastMessage = ChatBskyConvoDefs.isMessageView(convo.lastMessage) + ? convo.lastMessage + : null + + return ( + <> + + + {({props: triggerProps}) => ( + + )} + + + + {showDeleteConvo && ( + + + Delete conversation + + + + )} + + + Block account + + + + {/* note: last message will almost certainly be defined, since you can't + delete messages for other people andit's impossible for a convo on this + screen to have a message sent by you */} + {lastMessage && ( + + + Report conversation + + + + )} + + + + {lastMessage && ( + + )} + + ) +} + +export function AcceptChatButton({ + convo, + size = 'tiny', + variant = 'solid', + color = 'secondary_inverted', + label, + currentScreen, + onAcceptConvo, + ...props +}: Omit & { + label?: string + convo: ChatBskyConvoDefs.ConvoView + onAcceptConvo?: () => void + currentScreen: 'list' | 'conversation' +}) { + const {_} = useLingui() + const queryClient = useQueryClient() + const navigation = useNavigation() + + const {mutate: acceptConvo, isPending} = useAcceptConversation(convo.id, { + onMutate: () => { + onAcceptConvo?.() + if (currentScreen === 'list') { + precacheConvoQuery(queryClient, {...convo, status: 'accepted'}) + navigation.navigate('MessagesConversation', { + conversation: convo.id, + accept: true, + }) + } + }, + onError: () => { + // Should we show a toast here? They'll be on the convo screen, and it'll make + // no difference if the request failed - when they send a message, the convo will be accepted + // automatically. The only difference is that when they back out of the convo (without sending a message), the conversation will be rejected. + // the list will still have this chat in it -sfn + Toast.show(_('Failed to accept chat'), 'xmark') + }, + }) + + const onPressAccept = useCallback(() => { + acceptConvo() + }, [acceptConvo]) + + return ( + + ) +} + +export function DeleteChatButton({ + convo, + size = 'tiny', + variant = 'outline', + color = 'secondary', + label, + currentScreen, + ...props +}: Omit & { + label?: string + convo: ChatBskyConvoDefs.ConvoView + currentScreen: 'list' | 'conversation' +}) { + const {_} = useLingui() + const navigation = useNavigation() + + const {mutate: leaveConvo} = useLeaveConvo(convo.id, { + onMutate: () => { + if (currentScreen === 'conversation') { + navigation.dispatch(StackActions.pop()) + } + }, + onError: () => { + Toast.show(_('Failed to delete chat'), 'xmark') + }, + }) + + const onPressDelete = useCallback(() => { + Toast.show(_('Chat deleted'), 'check') + leaveConvo() + }, [leaveConvo, _]) + + return ( + + ) +} -- cgit 1.4.1