[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
This commit is contained in:
Hailey 2024-05-01 11:48:19 -07:00 committed by GitHub
parent 8304ad91ac
commit 6f9993ca55
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 82 additions and 65 deletions

View file

@ -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 keyExtractor(item: ConvoItem) {
return item.key
}
function onScrollToEndFailed() {
// Placeholder function. You have to give FlatList something or else it will error.
}
export function MessagesList({convoId}: {convoId: string}) {
return (
<ChatProvider convoId={convoId}>
<MessagesListInner />
</ChatProvider>
)
}
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}
/>