about summary refs log tree commit diff
path: root/src/screens/Messages/Conversation/MessagesList.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/screens/Messages/Conversation/MessagesList.tsx')
-rw-r--r--src/screens/Messages/Conversation/MessagesList.tsx180
1 files changed, 61 insertions, 119 deletions
diff --git a/src/screens/Messages/Conversation/MessagesList.tsx b/src/screens/Messages/Conversation/MessagesList.tsx
index 25aaf28c4..ca32a6d68 100644
--- a/src/screens/Messages/Conversation/MessagesList.tsx
+++ b/src/screens/Messages/Conversation/MessagesList.tsx
@@ -1,24 +1,15 @@
-import React, {useCallback, useMemo, useRef, useState} from 'react'
+import React, {useCallback, useMemo, useRef} from 'react'
 import {FlatList, View, ViewToken} from 'react-native'
-import {Alert} from 'react-native'
 import {KeyboardAvoidingView} from 'react-native-keyboard-controller'
 
-import {isWeb} from '#/platform/detection'
+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'
 import {MessageItem} from '#/screens/Messages/Conversation/MessageItem'
-import {
-  useChat,
-  useChatLogQuery,
-  useSendMessageMutation,
-} from '#/screens/Messages/Temp/query/query'
 import {Loader} from '#/components/Loader'
 import {Text} from '#/components/Typography'
-import * as TempDmChatDefs from '#/temp/dm/defs'
-
-type MessageWithNext = {
-  message: TempDmChatDefs.MessageView | TempDmChatDefs.DeletedMessage
-  next: TempDmChatDefs.MessageView | TempDmChatDefs.DeletedMessage | null
-}
 
 function MaybeLoader({isLoading}: {isLoading: boolean}) {
   return (
@@ -34,47 +25,43 @@ function MaybeLoader({isLoading}: {isLoading: boolean}) {
   )
 }
 
-function renderItem({item}: {item: MessageWithNext}) {
-  if (TempDmChatDefs.isMessageView(item.message))
-    return <MessageItem item={item.message} next={item.next} />
-
-  if (TempDmChatDefs.isDeletedMessage(item)) return <Text>Deleted message</Text>
+function renderItem({item}: {item: ConvoItem}) {
+  if (item.type === 'message') {
+    return <MessageItem item={item.message} next={item.nextMessage} />
+  } else if (item.type === 'deleted-message') {
+    return <Text>Deleted message</Text>
+  } else if (item.type === 'pending-message') {
+    return <Text>{item.message.text}</Text>
+  }
 
   return null
 }
 
-// TODO rm
-// TEMP: This is a temporary function to generate unique keys for mutation placeholders
-const generateUniqueKey = () => `_${Math.random().toString(36).substr(2, 9)}`
-
 function onScrollToEndFailed() {
   // Placeholder function. You have to give FlatList something or else it will error.
 }
 
-export function MessagesList({chatId}: {chatId: string}) {
-  const flatListRef = useRef<FlatList>(null)
-
-  // Whenever we reach the end (visually the top), we don't want to keep calling it. We will set `isFetching` to true
-  // once the request for new posts starts. Then, we will change it back to false after the content size changes.
-  const isFetching = useRef(false)
+export function MessagesList({convoId}: {convoId: string}) {
+  return (
+    <ChatProvider convoId={convoId}>
+      <MessagesListInner />
+    </ChatProvider>
+  )
+}
 
+export function MessagesListInner() {
+  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)
+  // const totalMessages = useRef(10)
 
   // TODO later
 
-  const [_, setShowSpinner] = useState(false)
-
-  // Query Data
-  const {data: chat} = useChat(chatId)
-  const {mutate: sendMessage} = useSendMessageMutation(chatId)
-  useChatLogQuery()
-
   const [onViewableItemsChanged, viewabilityConfig] = useMemo(() => {
     return [
       (info: {viewableItems: Array<ViewToken>; changed: Array<ViewToken>}) => {
@@ -93,23 +80,11 @@ export function MessagesList({chatId}: {chatId: string}) {
     if (isAtBottom.current) {
       flatListRef.current?.scrollToOffset({offset: 0, animated: true})
     }
-
-    isFetching.current = false
-    setShowSpinner(false)
   }, [])
 
   const onEndReached = useCallback(() => {
-    if (isFetching.current) return
-    isFetching.current = true
-    setShowSpinner(true)
-
-    // Eventually we will add more here when we hit the top through RQuery
-    // We wouldn't actually use a timeout, but there would be a delay while loading
-    setTimeout(() => {
-      // Do something
-      setShowSpinner(false)
-    }, 1000)
-  }, [])
+    chat.service.fetchMessageHistory()
+  }, [chat])
 
   const onInputFocus = useCallback(() => {
     if (!isAtBottom.current) {
@@ -117,84 +92,51 @@ export function MessagesList({chatId}: {chatId: string}) {
     }
   }, [])
 
-  const onSendMessage = useCallback(
-    async (message: string) => {
-      if (!message) return
-
-      try {
-        sendMessage({
-          message,
-          tempId: generateUniqueKey(),
-        })
-      } catch (e: any) {
-        Alert.alert(e.toString())
-      }
-    },
-    [sendMessage],
-  )
-
   const onInputBlur = useCallback(() => {}, [])
 
-  const messages = useMemo(() => {
-    if (!chat) return []
-
-    const filtered = chat.messages
-      .filter(
-        (
-          message,
-        ): message is
-          | TempDmChatDefs.MessageView
-          | TempDmChatDefs.DeletedMessage => {
-          return (
-            TempDmChatDefs.isMessageView(message) ||
-            TempDmChatDefs.isDeletedMessage(message)
-          )
-        },
-      )
-      .reduce((acc, message) => {
-        // convert [n1, n2, n3, ...] to [{message: n1, next: n2}, {message: n2, next: n3}, {message: n3, next: n4}, ...]
-
-        return [...acc, {message, next: acc.at(-1)?.message ?? null}]
-      }, [] as MessageWithNext[])
-    totalMessages.current = filtered.length
-
-    return filtered
-  }, [chat])
-
   return (
     <KeyboardAvoidingView
       style={{flex: 1, marginBottom: isWeb ? 20 : 85}}
       behavior="padding"
       keyboardVerticalOffset={70}
       contentContainerStyle={{flex: 1}}>
-      <FlatList
-        data={messages}
-        keyExtractor={item => item.message.id}
-        renderItem={renderItem}
-        contentContainerStyle={{paddingHorizontal: 10}}
-        inverted={true}
-        // 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}
-        removeClippedSubviews={true}
-        onEndReached={onEndReached}
-        onScrollToIndexFailed={onScrollToEndFailed}
-        onContentSizeChange={onContentSizeChange}
-        onViewableItemsChanged={onViewableItemsChanged}
-        viewabilityConfig={viewabilityConfig}
-        maintainVisibleContentPosition={{
-          minIndexForVisible: 1,
-        }}
-        ListFooterComponent={<MaybeLoader isLoading={false} />}
-        ref={flatListRef}
-        keyboardDismissMode="none"
-      />
+      {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"
+        />
+      )}
+
       <View style={{paddingHorizontal: 10}}>
         <MessageInput
-          onSendMessage={onSendMessage}
+          onSendMessage={text => {
+            chat.service.sendMessage({
+              text,
+            })
+          }}
           onFocus={onInputFocus}
           onBlur={onInputBlur}
         />