From 13c9c79aeec77edc33b1a926843b005c14acccc7 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 2 Oct 2024 22:21:59 +0300 Subject: move files around (#5576) --- src/screens/Messages/Conversation.tsx | 205 ++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 src/screens/Messages/Conversation.tsx (limited to 'src/screens/Messages/Conversation.tsx') diff --git a/src/screens/Messages/Conversation.tsx b/src/screens/Messages/Conversation.tsx new file mode 100644 index 000000000..21fdfe0ea --- /dev/null +++ b/src/screens/Messages/Conversation.tsx @@ -0,0 +1,205 @@ +import React, {useCallback} from 'react' +import {View} from 'react-native' +import {useKeyboardController} from 'react-native-keyboard-controller' +import {AppBskyActorDefs, moderateProfile, ModerationOpts} from '@atproto/api' +import {msg} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useFocusEffect} from '@react-navigation/native' +import {NativeStackScreenProps} from '@react-navigation/native-stack' + +import {CommonNavigatorParams} from '#/lib/routes/types' +import {isWeb} from '#/platform/detection' +import {useProfileShadow} from '#/state/cache/profile-shadow' +import {ConvoProvider, isConvoActive, useConvo} from '#/state/messages/convo' +import {ConvoStatus} from '#/state/messages/convo/types' +import {useCurrentConvoId} from '#/state/messages/current-convo-id' +import {useModerationOpts} from '#/state/preferences/moderation-opts' +import {useProfileQuery} from '#/state/queries/profile' +import {useSetMinimalShellMode} from '#/state/shell' +import {CenteredView} from '#/view/com/util/Views' +import {MessagesList} from '#/screens/Messages/components/MessagesList' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' +import {MessagesListBlockedFooter} from '#/components/dms/MessagesListBlockedFooter' +import {MessagesListHeader} from '#/components/dms/MessagesListHeader' +import {Error} from '#/components/Error' +import {Loader} from '#/components/Loader' + +type Props = NativeStackScreenProps< + CommonNavigatorParams, + 'MessagesConversation' +> +export function MessagesConversationScreen({route}: Props) { + const {gtMobile} = useBreakpoints() + const setMinimalShellMode = useSetMinimalShellMode() + + const convoId = route.params.conversation + const {setCurrentConvoId} = useCurrentConvoId() + + const {setEnabled} = useKeyboardController() + useFocusEffect( + useCallback(() => { + if (isWeb) return + setEnabled(true) + return () => { + setEnabled(false) + } + }, [setEnabled]), + ) + + useFocusEffect( + useCallback(() => { + setCurrentConvoId(convoId) + + if (isWeb && !gtMobile) { + setMinimalShellMode(true) + } else { + setMinimalShellMode(false) + } + + return () => { + setCurrentConvoId(undefined) + setMinimalShellMode(false) + } + }, [gtMobile, convoId, setCurrentConvoId, setMinimalShellMode]), + ) + + return ( + + + + ) +} + +function Inner() { + const t = useTheme() + const convoState = useConvo() + const {_} = useLingui() + + const moderationOpts = useModerationOpts() + const {data: recipient} = useProfileQuery({ + did: convoState.recipients?.[0].did, + }) + + // Because we want to give the list a chance to asynchronously scroll to the end before it is visible to the user, + // we use `hasScrolled` to determine when to render. With that said however, there is a chance that the chat will be + // empty. So, we also check for that possible state as well and render once we can. + const [hasScrolled, setHasScrolled] = React.useState(false) + const readyToShow = + hasScrolled || + (isConvoActive(convoState) && + !convoState.isFetchingHistory && + convoState.items.length === 0) + + // Any time that we re-render the `Initializing` state, we have to reset `hasScrolled` to false. After entering this + // state, we know that we're resetting the list of messages and need to re-scroll to the bottom when they get added. + React.useEffect(() => { + if (convoState.status === ConvoStatus.Initializing) { + setHasScrolled(false) + } + }, [convoState.status]) + + if (convoState.status === ConvoStatus.Error) { + return ( + + + convoState.error.retry()} + sideBorders={false} + /> + + ) + } + + return ( + + {!readyToShow && } + + {moderationOpts && recipient ? ( + + ) : ( + <> + + + )} + {!readyToShow && ( + + + + + + )} + + + ) +} + +function InnerReady({ + moderationOpts, + recipient: recipientUnshadowed, + hasScrolled, + setHasScrolled, +}: { + moderationOpts: ModerationOpts + recipient: AppBskyActorDefs.ProfileViewBasic + hasScrolled: boolean + setHasScrolled: React.Dispatch> +}) { + const convoState = useConvo() + const recipient = useProfileShadow(recipientUnshadowed) + + const moderation = React.useMemo(() => { + return moderateProfile(recipient, moderationOpts) + }, [recipient, moderationOpts]) + + const blockInfo = React.useMemo(() => { + const modui = moderation.ui('profileView') + const blocks = modui.alerts.filter(alert => alert.type === 'blocking') + const listBlocks = blocks.filter(alert => alert.source.type === 'list') + const userBlock = blocks.find(alert => alert.source.type === 'user') + return { + listBlocks, + userBlock, + } + }, [moderation]) + + return ( + <> + + {isConvoActive(convoState) && ( + 0} + blockInfo={blockInfo} + /> + } + /> + )} + + ) +} -- cgit 1.4.1