folks, I am building a chat app. Currently, I am working on a feature in which when the user scrolls a sticky date is shown to the top, based on the date of the messages visible in the viewport area. But I don't know how to get the index of the last item visible in the viewport.
Here is the codesandbox
Here is the code
const MessageComponent = () => {
const { id } = useParams();
const {
data: messageData,
isSuccess,
isError,
isLoading,
isFetching,
hasMoreData,
firstData,
isUninitialized,
} = useGetData(id);
const { loadMore } = useGetScrollData(messageData, id);
const user = User();
const chatId =
messageData[0]?.type == "date"
? messageData[1]?.chat?._id
: messageData[0]?.chat?._id;
const islastItemChatId: boolean = messageData.length > 0 && chatId != id;
const scrollRef = useScrollRef(islastItemChatId, id);
const scrollFunc = (e: any) => {
// let m = e.target.scrollHeight + e.target.scrollTop;
// let i = e.target.scrollHeight - m;
// console.log({ i, e });
if (!scrollRef.current) return;
const containerMiddle =
scrollRef.current.scrollTop +
scrollRef.current.getBoundingClientRect().height / 2;
const infiniteScrollItems = scrollRef.current.children[0].children;
console.log({ containerMiddle, infiniteScrollItems, e: e.target });
};
return (
<>
{messageData.length > 0 && (
<div
id="scrollableDiv"
style={{
height: "80%",
overflow: "auto",
display: "flex",
flexDirection: "column-reverse",
padding: "10px 0px",
}}
ref={scrollRef}
>
<InfiniteScroll
dataLength={messageData.length}
hasMore={hasMoreData}
onScroll={scrollFunc}
loader={
<div className="loading-container">
<div className="lds-ring">
<div></div>
</div>
</div>
}
endMessage={
<div className="message-container date">
<div className={`text-container sender large-margin`}>
<span>You have seen all the messages</span>
</div>
</div>
}
style={{ display: "flex", flexDirection: "column-reverse" }}
next={loadMore}
inverse={true}
scrollableTarget="scrollableDiv"
>
{messageData.map((item, index: number) => {
const isUserChat = item?.sender?._id === user._id;
const className =
item?.type == "date"
? "date"
: isUserChat
? "user-message"
: "sender-message";
const prevItem: IMessageData | null =
index < messageData?.length ? messageData[index - 1] : null;
const nextItem: IMessageData | null =
index < messageData?.length ? messageData[index + 1] : null;
return (
<Message
key={item._id}
item={item}
prevItem={prevItem}
className={className}
isUserChat={isUserChat}
index={index}
nextItem={nextItem}
/>
);
})}
</InfiniteScroll>
</div>
)}
</>
);
};