diff options
author | Hailey <me@haileyok.com> | 2024-05-01 11:48:19 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-01 11:48:19 -0700 |
commit | 6f9993ca55f0c01509c1a159b225d73f75ed8778 (patch) | |
tree | a332c2d3305aceef30f76ceabc92b0ceea56fb6e /src | |
parent | 8304ad91ac3862becca5b3f4f7fd90b8b39d1dea (diff) | |
download | voidsky-6f9993ca55f0c01509c1a159b225d73f75ed8778.tar.zst |
[Clipclops] Fix list, rework structure (#3799)
* proper min index * move keyextractor out of react * move onSendMessage out * don't render the flatlist conditionally * add loader * rework structure * remove some unneeded logic
Diffstat (limited to 'src')
-rw-r--r-- | src/screens/Messages/Conversation/MessagesList.tsx | 100 | ||||
-rw-r--r-- | src/screens/Messages/Conversation/index.tsx | 43 |
2 files changed, 80 insertions, 63 deletions
diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx index ca32a6d68..ec7147e3c 100644 --- a/src/screens/Messages/Conversation/MessagesList.tsx +++ b/src/screens/Messages/Conversation/MessagesList.tsx @@ -3,7 +3,6 @@ import {FlatList, View, ViewToken} from 'react-native' import {KeyboardAvoidingView} from 'react-native-keyboard-controller' import {useChat} from '#/state/messages' -import {ChatProvider} from '#/state/messages' import {ConvoItem, ConvoStatus} from '#/state/messages/convo' import {isWeb} from 'platform/detection' import {MessageInput} from '#/screens/Messages/Conversation/MessageInput' @@ -37,31 +36,20 @@ function renderItem({item}: {item: ConvoItem}) { return null } -function onScrollToEndFailed() { - // Placeholder function. You have to give FlatList something or else it will error. +function keyExtractor(item: ConvoItem) { + return item.key } -export function MessagesList({convoId}: {convoId: string}) { - return ( - <ChatProvider convoId={convoId}> - <MessagesListInner /> - </ChatProvider> - ) +function onScrollToEndFailed() { + // Placeholder function. You have to give FlatList something or else it will error. } -export function MessagesListInner() { +export function MessagesList() { const chat = useChat() const flatListRef = useRef<FlatList>(null) // We use this to know if we should scroll after a new clop is added to the list const isAtBottom = useRef(false) - // Because the viewableItemsChanged callback won't have access to the updated state, we use a ref to store the - // total number of clops - // TODO this needs to be set to whatever the initial number of messages is - // const totalMessages = useRef(10) - - // TODO later - const [onViewableItemsChanged, viewabilityConfig] = useMemo(() => { return [ (info: {viewableItems: Array<ViewToken>; changed: Array<ViewToken>}) => { @@ -94,49 +82,59 @@ export function MessagesListInner() { const onInputBlur = useCallback(() => {}, []) + const onSendMessage = useCallback( + (text: string) => { + chat.service.sendMessage({ + text, + }) + }, + [chat.service], + ) + return ( <KeyboardAvoidingView style={{flex: 1, marginBottom: isWeb ? 20 : 85}} behavior="padding" keyboardVerticalOffset={70} contentContainerStyle={{flex: 1}}> - {chat.state.status === ConvoStatus.Ready && ( - <FlatList - data={chat.state.items} - keyExtractor={item => item.key} - renderItem={renderItem} - contentContainerStyle={{paddingHorizontal: 10}} - // In the future, we might want to adjust this value. Not very concerning right now as long as we are only - // dealing with text. But whenever we have images or other media and things are taller, we will want to lower - // this...probably. - initialNumToRender={20} - // Same with the max to render per batch. Let's be safe for now though. - maxToRenderPerBatch={25} - inverted={true} - onEndReached={onEndReached} - onScrollToIndexFailed={onScrollToEndFailed} - onContentSizeChange={onContentSizeChange} - onViewableItemsChanged={onViewableItemsChanged} - viewabilityConfig={viewabilityConfig} - maintainVisibleContentPosition={{ - minIndexForVisible: 0, - }} - ListFooterComponent={ - <MaybeLoader isLoading={chat.state.isFetchingHistory} /> - } - removeClippedSubviews={true} - ref={flatListRef} - keyboardDismissMode="none" - /> - )} + <FlatList + data={ + chat.state.status === ConvoStatus.Ready ? chat.state.items : undefined + } + keyExtractor={keyExtractor} + renderItem={renderItem} + contentContainerStyle={{paddingHorizontal: 10}} + // In the future, we might want to adjust this value. Not very concerning right now as long as we are only + // dealing with text. But whenever we have images or other media and things are taller, we will want to lower + // this...probably. + initialNumToRender={20} + // Same with the max to render per batch. Let's be safe for now though. + maxToRenderPerBatch={25} + inverted={true} + onEndReached={onEndReached} + onScrollToIndexFailed={onScrollToEndFailed} + onContentSizeChange={onContentSizeChange} + onViewableItemsChanged={onViewableItemsChanged} + viewabilityConfig={viewabilityConfig} + maintainVisibleContentPosition={{ + minIndexForVisible: 1, + }} + ListFooterComponent={ + <MaybeLoader + isLoading={ + chat.state.status === ConvoStatus.Ready && + chat.state.isFetchingHistory + } + /> + } + removeClippedSubviews={true} + ref={flatListRef} + keyboardDismissMode="none" + /> <View style={{paddingHorizontal: 10}}> <MessageInput - onSendMessage={text => { - chat.service.sendMessage({ - text, - }) - }} + onSendMessage={onSendMessage} onFocus={onInputFocus} onBlur={onInputBlur} /> diff --git a/src/screens/Messages/Conversation/index.tsx b/src/screens/Messages/Conversation/index.tsx index 9c5fd7912..79c49f051 100644 --- a/src/screens/Messages/Conversation/index.tsx +++ b/src/screens/Messages/Conversation/index.tsx @@ -9,9 +9,10 @@ import {NativeStackScreenProps} from '@react-navigation/native-stack' import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types' import {useGate} from '#/lib/statsig/statsig' -import {useConvoQuery} from '#/state/queries/messages/conversation' import {BACK_HITSLOP} from 'lib/constants' import {isWeb} from 'platform/detection' +import {ChatProvider, useChat} from 'state/messages' +import {ConvoStatus} from 'state/messages/convo' import {useSession} from 'state/session' import {UserAvatar} from 'view/com/util/UserAvatar' import {CenteredView} from 'view/com/util/Views' @@ -30,33 +31,49 @@ type Props = NativeStackScreenProps< export function MessagesConversationScreen({route}: Props) { const gate = useGate() const convoId = route.params.conversation + + if (!gate('dms')) return <ClipClopGate /> + + return ( + <ChatProvider convoId={convoId}> + <Inner /> + </ChatProvider> + ) +} + +function Inner() { + const chat = useChat() const {currentAccount} = useSession() const myDid = currentAccount?.did - const {data: chat, isError: isError} = useConvoQuery(convoId) const otherProfile = React.useMemo(() => { - return chat?.members?.find(m => m.did !== myDid) - }, [chat?.members, myDid]) + if (chat.state.status !== ConvoStatus.Ready) return + return chat.state.convo.members.find(m => m.did !== myDid) + }, [chat.state, myDid]) - if (!gate('dms')) return <ClipClopGate /> - - if (!chat || !otherProfile) { + // TODO whenever we have error messages, we should use them in here -hailey + if (chat.state.status !== ConvoStatus.Ready || !otherProfile) { return ( - <CenteredView style={{flex: 1}} sideBorders> - <ListMaybePlaceholder isLoading={true} isError={isError} /> - </CenteredView> + <ListMaybePlaceholder + isLoading={true} + isError={chat.state.status === ConvoStatus.Error} + /> ) } return ( <CenteredView style={{flex: 1}} sideBorders> <Header profile={otherProfile} /> - <MessagesList convoId={convoId} /> + <MessagesList /> </CenteredView> ) } -function Header({profile}: {profile: AppBskyActorDefs.ProfileViewBasic}) { +let Header = ({ + profile, +}: { + profile: AppBskyActorDefs.ProfileViewBasic +}): React.ReactNode => { const t = useTheme() const {_} = useLingui() const {gtTablet} = useBreakpoints() @@ -126,3 +143,5 @@ function Header({profile}: {profile: AppBskyActorDefs.ProfileViewBasic}) { </View> ) } + +Header = React.memo(Header) |