From 5e6f56bb0087dc80ca86cf6ebe64c871f71c7ad6 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 14 May 2024 10:58:26 -0500 Subject: [PATCH] Make status checks easier, fix load state --- src/components/dms/MessageMenu.tsx | 7 ++---- .../Messages/Conversation/MessagesList.tsx | 18 +++++++------- src/screens/Messages/Conversation/index.tsx | 14 +++++------ src/state/messages/convo/index.tsx | 24 ++++++++++++++++++- src/state/messages/convo/util.ts | 9 +++++++ 5 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 src/state/messages/convo/util.ts diff --git a/src/components/dms/MessageMenu.tsx b/src/components/dms/MessageMenu.tsx index 3349b2ff89..55c3ac21b6 100644 --- a/src/components/dms/MessageMenu.tsx +++ b/src/components/dms/MessageMenu.tsx @@ -7,8 +7,7 @@ import {useLingui} from '@lingui/react' import {richTextToString} from '#/lib/strings/rich-text-helpers' import {isWeb} from 'platform/detection' -import {useConvo} from 'state/messages/convo' -import {ConvoStatus} from 'state/messages/convo/types' +import {useConvoActive} from 'state/messages/convo' import {useSession} from 'state/session' import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' @@ -34,7 +33,7 @@ export let MessageMenu = ({ const {_} = useLingui() const t = useTheme() const {currentAccount} = useSession() - const convo = useConvo() + const convo = useConvoActive() const deleteControl = usePromptControl() const retryDeleteControl = usePromptControl() const reportControl = usePromptControl() @@ -55,8 +54,6 @@ export let MessageMenu = ({ }, [_, message.text, message.facets]) const onDelete = React.useCallback(() => { - if (convo.status !== ConvoStatus.Ready) return - LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut) convo .deleteMessage(message.id) diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index 5ba82eeff9..dac534cd41 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -7,8 +7,8 @@ import {AppBskyRichtextFacet, RichText} from '@atproto/api' import {shortenLinks} from '#/lib/strings/rich-text-manip' import {isNative} from '#/platform/detection' -import {useConvo} from '#/state/messages/convo' -import {ConvoItem, ConvoStatus} from '#/state/messages/convo/types' +import {useConvoActive} from '#/state/messages/convo' +import {ConvoItem} from '#/state/messages/convo/types' import {useAgent} from '#/state/session' import {ScrollProvider} from 'lib/ScrollContext' import {isWeb} from 'platform/detection' @@ -60,7 +60,7 @@ function onScrollToIndexFailed() { } export function MessagesList() { - const convo = useConvo() + const convo = useConvoActive() const {getAgent} = useAgent() const flatListRef = useRef(null) @@ -128,7 +128,7 @@ export function MessagesList() { // The check for `hasInitiallyScrolled` prevents an initial fetch on mount. FlatList triggers `onStartReached` // immediately on mount, since we are in fact at an offset of zero, so we have to ignore those initial calls. const onStartReached = useCallback(() => { - if (convo.status === ConvoStatus.Ready && hasInitiallyScrolled.value) { + if (hasInitiallyScrolled.value) { convo.fetchMessageHistory() } }, [convo, hasInitiallyScrolled]) @@ -150,12 +150,10 @@ export function MessagesList() { return true }) - if (convo.status === ConvoStatus.Ready) { - convo.sendMessage({ - text: rt.text, - facets: rt.facets, - }) - } + convo.sendMessage({ + text: rt.text, + facets: rt.facets, + }) }, [convo, getAgent], ) diff --git a/src/screens/Messages/Conversation/index.tsx b/src/screens/Messages/Conversation/index.tsx index a783a0bd6d..70503986bd 100644 --- a/src/screens/Messages/Conversation/index.tsx +++ b/src/screens/Messages/Conversation/index.tsx @@ -15,7 +15,7 @@ import {useGate} from '#/lib/statsig/statsig' import {useCurrentConvoId} from '#/state/messages/current-convo-id' import {BACK_HITSLOP} from 'lib/constants' import {isIOS, isWeb} from 'platform/detection' -import {ConvoProvider, useConvo} from 'state/messages/convo' +import {ConvoProvider, isConvoReady, useConvo} from 'state/messages/convo' import {ConvoStatus} from 'state/messages/convo/types' import {PreviewableUserAvatar} from 'view/com/util/UserAvatar' import {CenteredView} from 'view/com/util/Views' @@ -72,14 +72,14 @@ function Inner() { React.useEffect(() => { if ( !hasInitiallyRendered && - convoState.status === ConvoStatus.Ready && + isConvoReady(convoState) && !convoState.isFetchingHistory ) { setTimeout(() => { setHasInitiallyRendered(true) }, 15) } - }, [convoState.isFetchingHistory, convoState.status, hasInitiallyRendered]) + }, [convoState, hasInitiallyRendered]) if (convoState.status === ConvoStatus.Error) { return ( @@ -108,10 +108,10 @@ function Inner() {
- {convoState.status !== ConvoStatus.Ready ? ( - - ) : ( + {isConvoReady(convoState) ? ( + ) : ( + )} {!hasInitiallyRendered && ( )} - {convoState.status === ConvoStatus.Ready && profile ? ( + {isConvoReady(convoState) && profile ? ( (null) export function useConvo() { @@ -18,6 +25,21 @@ export function useConvo() { return ctx } +export function useConvoActive() { + const ctx = useContext(ChatContext) as ConvoState & { + status: ConvoStatus.Ready | ConvoStatus.Backgrounded | ConvoStatus.Suspended + } + if (!ctx) { + throw new Error('useConvo must be used within a ConvoProvider') + } + if (!isConvoReady(ctx)) { + throw new Error( + `useConvoActive must only be rendered when the Convo is ready. Current status: ${ctx.status}`, + ) + } + return ctx +} + export function ConvoProvider({ children, convoId, diff --git a/src/state/messages/convo/util.ts b/src/state/messages/convo/util.ts new file mode 100644 index 0000000000..5a7d197b98 --- /dev/null +++ b/src/state/messages/convo/util.ts @@ -0,0 +1,9 @@ +import {ConvoState, ConvoStatus} from './types' + +export function isConvoReady(convo: ConvoState) { + return ( + convo.status === ConvoStatus.Ready || + convo.status === ConvoStatus.Backgrounded || + convo.status === ConvoStatus.Suspended + ) +}