diff options
Diffstat (limited to 'src/screens/Messages')
-rw-r--r-- | src/screens/Messages/ChatList.tsx | 15 | ||||
-rw-r--r-- | src/screens/Messages/Conversation.tsx | 61 | ||||
-rw-r--r-- | src/screens/Messages/components/RequestButtons.tsx | 34 | ||||
-rw-r--r-- | src/screens/Messages/components/RequestListItem.tsx | 2 |
4 files changed, 87 insertions, 25 deletions
diff --git a/src/screens/Messages/ChatList.tsx b/src/screens/Messages/ChatList.tsx index 2846ed828..9fd54f1b0 100644 --- a/src/screens/Messages/ChatList.tsx +++ b/src/screens/Messages/ChatList.tsx @@ -9,6 +9,7 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack' import {useAppState} from '#/lib/hooks/useAppState' import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' +import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification' import {type MessagesTabNavigatorParams} from '#/lib/routes/types' import {cleanError} from '#/lib/strings/errors' import {logger} from '#/logger' @@ -321,6 +322,18 @@ export function MessagesScreen({navigation, route}: Props) { function Header({newChatControl}: {newChatControl: DialogControlProps}) { const {_} = useLingui() const {gtMobile} = useBreakpoints() + const requireEmailVerification = useRequireEmailVerification() + + const openChatControl = useCallback(() => { + newChatControl.open() + }, [newChatControl]) + const wrappedOpenChatControl = requireEmailVerification(openChatControl, { + instructions: [ + <Trans key="new-chat"> + Before you can message another user, you must first verify your email. + </Trans>, + ], + }) const settingsLink = ( <Link @@ -352,7 +365,7 @@ function Header({newChatControl}: {newChatControl: DialogControlProps}) { color="primary" size="small" variant="solid" - onPress={newChatControl.open}> + onPress={wrappedOpenChatControl}> <ButtonIcon icon={PlusIcon} position="left" /> <ButtonText> <Trans>New chat</Trans> diff --git a/src/screens/Messages/Conversation.tsx b/src/screens/Messages/Conversation.tsx index 2222084ce..90547a8d4 100644 --- a/src/screens/Messages/Conversation.tsx +++ b/src/screens/Messages/Conversation.tsx @@ -1,11 +1,11 @@ -import React, {useCallback} from 'react' +import React, {useCallback, useEffect} from 'react' import {View} from 'react-native' import { type AppBskyActorDefs, moderateProfile, type ModerationDecision, } from '@atproto/api' -import {msg} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import { type RouteProp, @@ -17,6 +17,7 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack' import {useEmail} from '#/lib/hooks/useEmail' import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController' +import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import { type CommonNavigatorParams, type NavigationProp, @@ -31,8 +32,10 @@ import {useProfileQuery} from '#/state/queries/profile' import {useSetMinimalShellMode} from '#/state/shell' import {MessagesList} from '#/screens/Messages/components/MessagesList' import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' -import {useDialogControl} from '#/components/Dialog' -import {VerifyEmailDialog} from '#/components/dialogs/VerifyEmailDialog' +import { + EmailDialogScreenID, + useEmailDialogControl, +} from '#/components/dialogs/EmailDialog' import {MessagesListBlockedFooter} from '#/components/dms/MessagesListBlockedFooter' import {MessagesListHeader} from '#/components/dms/MessagesListHeader' import {Error} from '#/components/Error' @@ -183,19 +186,50 @@ function InnerReady({ hasScrolled: boolean setHasScrolled: React.Dispatch<React.SetStateAction<boolean>> }) { - const {_} = useLingui() const convoState = useConvo() const navigation = useNavigation<NavigationProp>() const {params} = useRoute<RouteProp<CommonNavigatorParams, 'MessagesConversation'>>() - const verifyEmailControl = useDialogControl() const {needsEmailVerification} = useEmail() + const emailDialogControl = useEmailDialogControl() - React.useEffect(() => { + /** + * Must be non-reactive, otherwise the update to open the global dialog will + * cause a re-render loop. + */ + const maybeBlockForEmailVerification = useNonReactiveCallback(() => { if (needsEmailVerification) { - verifyEmailControl.open() + /* + * HACKFIX + * + * Load bearing timeout, to bump this state update until the after the + * `navigator.addListener('state')` handler closes elements from + * `shell/index.*.tsx` - sfn & esb + */ + setTimeout(() => + emailDialogControl.open({ + id: EmailDialogScreenID.Verify, + instructions: [ + <Trans key="pre-compose"> + Before you can message another user, you must first verify your + email. + </Trans>, + ], + onCloseWithoutVerifying: () => { + if (navigation.canGoBack()) { + navigation.goBack() + } else { + navigation.navigate('Messages', {animation: 'pop'}) + } + }, + }), + ) } - }, [needsEmailVerification, verifyEmailControl]) + }) + + useEffect(() => { + maybeBlockForEmailVerification() + }, [maybeBlockForEmailVerification]) return ( <> @@ -216,15 +250,6 @@ function InnerReady({ } /> )} - <VerifyEmailDialog - reasonText={_( - msg`Before you may message another user, you must first verify your email.`, - )} - control={verifyEmailControl} - onCloseWithoutVerifying={() => { - navigation.navigate('Home') - }} - /> </> ) } diff --git a/src/screens/Messages/components/RequestButtons.tsx b/src/screens/Messages/components/RequestButtons.tsx index 62db09600..3490bec0d 100644 --- a/src/screens/Messages/components/RequestButtons.tsx +++ b/src/screens/Messages/components/RequestButtons.tsx @@ -1,11 +1,12 @@ import {useCallback} from 'react' -import {ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api' +import {type 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 {useEmail} from '#/lib/hooks/useEmail' +import {type 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' @@ -13,8 +14,17 @@ 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 { + Button, + ButtonIcon, + type ButtonProps, + ButtonText, +} from '#/components/Button' import {useDialogControl} from '#/components/Dialog' +import { + EmailDialogScreenID, + useEmailDialogControl, +} from '#/components/dialogs/EmailDialog' 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' @@ -186,6 +196,8 @@ export function AcceptChatButton({ const {_} = useLingui() const queryClient = useQueryClient() const navigation = useNavigation<NavigationProp>() + const {needsEmailVerification} = useEmail() + const emailDialogControl = useEmailDialogControl() const {mutate: acceptConvo, isPending} = useAcceptConversation(convo.id, { onMutate: () => { @@ -216,8 +228,20 @@ export function AcceptChatButton({ }) const onPressAccept = useCallback(() => { - acceptConvo() - }, [acceptConvo]) + if (needsEmailVerification) { + emailDialogControl.open({ + id: EmailDialogScreenID.Verify, + instructions: [ + <Trans key="request-btn"> + Before you can accept this chat request, you must first verify your + email. + </Trans>, + ], + }) + } else { + acceptConvo() + } + }, [acceptConvo, needsEmailVerification, emailDialogControl]) return ( <Button diff --git a/src/screens/Messages/components/RequestListItem.tsx b/src/screens/Messages/components/RequestListItem.tsx index 654691a01..5e09dd2e3 100644 --- a/src/screens/Messages/components/RequestListItem.tsx +++ b/src/screens/Messages/components/RequestListItem.tsx @@ -1,5 +1,5 @@ import {View} from 'react-native' -import {ChatBskyConvoDefs} from '@atproto/api' +import {type ChatBskyConvoDefs} from '@atproto/api' import {Trans} from '@lingui/macro' import {useModerationOpts} from '#/state/preferences/moderation-opts' |