fix: stop infinite scroll feedback when no more messages
Scroll handler now checks !hasMore to avoid calling fetchOlderMessages when all messages are loaded. Previously the handler would fire on every scroll event (since scrollTop stayed < 100), creating a .then() callback loop that adjusted scroll position repeatedly, causing 'stuck' scrolling.
This commit is contained in:
@@ -292,6 +292,7 @@ export function ChatArea() {
|
|||||||
);
|
);
|
||||||
const isLoading = useMessageStore((s) => s.isLoading);
|
const isLoading = useMessageStore((s) => s.isLoading);
|
||||||
const isLoadingOlder = useMessageStore((s) => s.isLoadingOlder);
|
const isLoadingOlder = useMessageStore((s) => s.isLoadingOlder);
|
||||||
|
const hasMore = useMessageStore((s) => activeChannelId ? s.hasMoreByChannel[activeChannelId] !== false : true);
|
||||||
const fetchMessages = useMessageStore((s) => s.fetchMessages);
|
const fetchMessages = useMessageStore((s) => s.fetchMessages);
|
||||||
const fetchOlderMessages = useMessageStore((s) => s.fetchOlderMessages);
|
const fetchOlderMessages = useMessageStore((s) => s.fetchOlderMessages);
|
||||||
const sendMessage = useMessageStore((s) => s.sendMessage);
|
const sendMessage = useMessageStore((s) => s.sendMessage);
|
||||||
@@ -447,17 +448,16 @@ export function ChatArea() {
|
|||||||
|
|
||||||
const handleScroll = useCallback(() => {
|
const handleScroll = useCallback(() => {
|
||||||
const el = scrollContainerRef.current;
|
const el = scrollContainerRef.current;
|
||||||
if (!el || !activeChannelId || isLoadingOlder) return;
|
if (!el || !activeChannelId || isLoadingOlder || !hasMore) return;
|
||||||
if (el.scrollTop < 100) {
|
if (el.scrollTop < 100) {
|
||||||
const prevHeight = el.scrollHeight;
|
const prevHeight = el.scrollHeight;
|
||||||
fetchOlderMessages(activeChannelId).then(() => {
|
fetchOlderMessages(activeChannelId).then(() => {
|
||||||
// ponytail: maintain scroll position after prepending older messages
|
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
el.scrollTop = el.scrollHeight - prevHeight;
|
el.scrollTop = el.scrollHeight - prevHeight;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [activeChannelId, isLoadingOlder, fetchOlderMessages]);
|
}, [activeChannelId, isLoadingOlder, hasMore, fetchOlderMessages]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
bottomRef.current?.scrollIntoView({ behavior: "auto" });
|
bottomRef.current?.scrollIntoView({ behavior: "auto" });
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ export function DMChat() {
|
|||||||
const fetchMessages = useConversationStore((s) => s.fetchMessages);
|
const fetchMessages = useConversationStore((s) => s.fetchMessages);
|
||||||
const fetchOlderMessages = useConversationStore((s) => s.fetchOlderMessages);
|
const fetchOlderMessages = useConversationStore((s) => s.fetchOlderMessages);
|
||||||
const isLoadingOlder = useConversationStore((s) => s.isLoadingOlder);
|
const isLoadingOlder = useConversationStore((s) => s.isLoadingOlder);
|
||||||
|
const hasMore = useConversationStore((s) => id ? s.hasMoreByConversation[id] !== false : true);
|
||||||
const isLoading = useConversationStore((s) => s.isLoading);
|
const isLoading = useConversationStore((s) => s.isLoading);
|
||||||
const sendMessage = useConversationStore((s) => s.sendMessage);
|
const sendMessage = useConversationStore((s) => s.sendMessage);
|
||||||
const fetchConversations = useConversationStore((s) => s.fetchConversations);
|
const fetchConversations = useConversationStore((s) => s.fetchConversations);
|
||||||
@@ -189,7 +190,7 @@ export function DMChat() {
|
|||||||
|
|
||||||
const handleScroll = useCallback(() => {
|
const handleScroll = useCallback(() => {
|
||||||
const el = scrollContainerRef.current;
|
const el = scrollContainerRef.current;
|
||||||
if (!el || !id || isLoadingOlder) return;
|
if (!el || !id || isLoadingOlder || !hasMore) return;
|
||||||
if (el.scrollTop < 100) {
|
if (el.scrollTop < 100) {
|
||||||
const prevHeight = el.scrollHeight;
|
const prevHeight = el.scrollHeight;
|
||||||
fetchOlderMessages(id).then(() => {
|
fetchOlderMessages(id).then(() => {
|
||||||
@@ -198,7 +199,7 @@ export function DMChat() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [id, isLoadingOlder, fetchOlderMessages]);
|
}, [id, isLoadingOlder, hasMore, fetchOlderMessages]);
|
||||||
const messages = id ? messagesByConv[id] || [] : [];
|
const messages = id ? messagesByConv[id] || [] : [];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user