import React, { useCallback, useState, useEffect, useRef, useMemo } from 'react'; import { useVirtualizer } from '@tanstack/react-virtual'; import { MessageItem } from './MessageItem'; import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events'; import { useInView } from 'react-intersection-observer' export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId, onReply, handleReaction, chatReferences, tempChatReferences }) => { const parentRef = useRef(); const [messages, setMessages] = useState(initialMessages); const [showScrollButton, setShowScrollButton] = useState(false); const hasLoadedInitialRef = useRef(false); const isAtBottomRef = useRef(true); // const [ref, inView] = useInView({ // threshold: 0.7 // }) // useEffect(() => { // if (inView) { // } // }, [inView]) // Update message list with unique signatures and tempMessages useEffect(() => { let uniqueInitialMessagesMap = new Map(); // Only add a message if it doesn't already exist in the Map initialMessages.forEach((message) => { if (!uniqueInitialMessagesMap.has(message.signature)) { uniqueInitialMessagesMap.set(message.signature, message); } }); const uniqueInitialMessages = Array.from(uniqueInitialMessagesMap.values()).sort( (a, b) => a.timestamp - b.timestamp ); const totalMessages = [...uniqueInitialMessages, ...(tempMessages || [])]; if (totalMessages.length === 0) return; setMessages(totalMessages); setTimeout(() => { const hasUnreadMessages = totalMessages.some((msg) => msg.unread && !msg?.chatReference); if (parentRef.current) { const { scrollTop, scrollHeight, clientHeight } = parentRef.current; const atBottom = scrollTop + clientHeight >= scrollHeight - 10; // Adjust threshold as needed if (!atBottom && hasUnreadMessages) { setShowScrollButton(hasUnreadMessages); } else { handleMessageSeen(); } } if (!hasLoadedInitialRef.current) { scrollToBottom(totalMessages); hasLoadedInitialRef.current = true; } }, 500); }, [initialMessages, tempMessages]); const scrollToBottom = (initialMsgs) => { const index = initialMsgs ? initialMsgs.length - 1 : messages.length - 1; if (rowVirtualizer) { rowVirtualizer.scrollToIndex(index, { align: 'end' }); } handleMessageSeen() }; const handleMessageSeen = useCallback(() => { setMessages((prevMessages) => prevMessages.map((msg) => ({ ...msg, unread: false, })) ); setShowScrollButton(false) }, []); // const scrollToBottom = (initialMsgs) => { // const index = initialMsgs ? initialMsgs.length - 1 : messages.length - 1; // if (parentRef.current) { // parentRef.current.scrollToIndex(index); // } // }; const sentNewMessageGroupFunc = useCallback(() => { scrollToBottom(); }, [messages]); useEffect(() => { subscribeToEvent('sent-new-message-group', sentNewMessageGroupFunc); return () => { unsubscribeFromEvent('sent-new-message-group', sentNewMessageGroupFunc); }; }, [sentNewMessageGroupFunc]); const lastSignature = useMemo(()=> { if(!messages || messages?.length === 0) return null const lastIndex = messages.length - 1 return messages[lastIndex]?.signature }, [messages]) // Initialize the virtualizer const rowVirtualizer = useVirtualizer({ count: messages.length, getScrollElement: () => parentRef.current, estimateSize: () => 80, // Provide an estimated height of items, adjust this as needed overscan: 10, // Number of items to render outside the visible area to improve smoothness measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 ? element => { return element?.getBoundingClientRect().height } : undefined, }); return (