60 lines
1.6 KiB
TypeScript
60 lines
1.6 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
|
|
type ChatScrollProps = {
|
|
chatRef: React.RefObject<HTMLDivElement>;
|
|
bottomRef: React.RefObject<HTMLDivElement>;
|
|
shouldLoadMore: boolean;
|
|
loadMore: () => void;
|
|
count: number;
|
|
}
|
|
|
|
export const useChatScroll = ({
|
|
chatRef,
|
|
bottomRef,
|
|
shouldLoadMore,
|
|
loadMore,
|
|
count,
|
|
}: ChatScrollProps) => {
|
|
const [hasInitialized, setHasInitialized] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const topDiv = chatRef?.current;
|
|
const hadleScroll = () => {
|
|
const scrollTop = topDiv?.scrollTop;
|
|
|
|
if (scrollTop === 0 && shouldLoadMore) {
|
|
loadMore();
|
|
}
|
|
};
|
|
|
|
topDiv?.addEventListener("scroll", hadleScroll);
|
|
|
|
return () => {
|
|
topDiv?.removeEventListener("scroll", hadleScroll);
|
|
}
|
|
}, [shouldLoadMore, loadMore, chatRef]);
|
|
|
|
useEffect(() => {
|
|
const bottomDiv = bottomRef?.current;
|
|
const topDiv = chatRef?.current;
|
|
const shouldAutoScroll= () => {
|
|
if (!hasInitialized && bottomDiv){
|
|
setHasInitialized(true);
|
|
return true;
|
|
}
|
|
|
|
if (!topDiv) {
|
|
return false;
|
|
}
|
|
|
|
const distanceFromBottom = topDiv.scrollHeight - topDiv.clientHeight;
|
|
return distanceFromBottom <= 100;
|
|
}
|
|
|
|
if (shouldAutoScroll()) {
|
|
setTimeout(() => {
|
|
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
}, 100);
|
|
}
|
|
}, [bottomRef, chatRef, hasInitialized, count]);
|
|
} |