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:
2026-07-21 09:05:39 -04:00
parent 738b9b17ff
commit cca6ea0e37
2 changed files with 6 additions and 5 deletions
+3 -3
View File
@@ -292,6 +292,7 @@ export function ChatArea() {
);
const isLoading = useMessageStore((s) => s.isLoading);
const isLoadingOlder = useMessageStore((s) => s.isLoadingOlder);
const hasMore = useMessageStore((s) => activeChannelId ? s.hasMoreByChannel[activeChannelId] !== false : true);
const fetchMessages = useMessageStore((s) => s.fetchMessages);
const fetchOlderMessages = useMessageStore((s) => s.fetchOlderMessages);
const sendMessage = useMessageStore((s) => s.sendMessage);
@@ -447,17 +448,16 @@ export function ChatArea() {
const handleScroll = useCallback(() => {
const el = scrollContainerRef.current;
if (!el || !activeChannelId || isLoadingOlder) return;
if (!el || !activeChannelId || isLoadingOlder || !hasMore) return;
if (el.scrollTop < 100) {
const prevHeight = el.scrollHeight;
fetchOlderMessages(activeChannelId).then(() => {
// ponytail: maintain scroll position after prepending older messages
requestAnimationFrame(() => {
el.scrollTop = el.scrollHeight - prevHeight;
});
});
}
}, [activeChannelId, isLoadingOlder, fetchOlderMessages]);
}, [activeChannelId, isLoadingOlder, hasMore, fetchOlderMessages]);
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: "auto" });
+3 -2
View File
@@ -156,6 +156,7 @@ export function DMChat() {
const fetchMessages = useConversationStore((s) => s.fetchMessages);
const fetchOlderMessages = useConversationStore((s) => s.fetchOlderMessages);
const isLoadingOlder = useConversationStore((s) => s.isLoadingOlder);
const hasMore = useConversationStore((s) => id ? s.hasMoreByConversation[id] !== false : true);
const isLoading = useConversationStore((s) => s.isLoading);
const sendMessage = useConversationStore((s) => s.sendMessage);
const fetchConversations = useConversationStore((s) => s.fetchConversations);
@@ -189,7 +190,7 @@ export function DMChat() {
const handleScroll = useCallback(() => {
const el = scrollContainerRef.current;
if (!el || !id || isLoadingOlder) return;
if (!el || !id || isLoadingOlder || !hasMore) return;
if (el.scrollTop < 100) {
const prevHeight = el.scrollHeight;
fetchOlderMessages(id).then(() => {
@@ -198,7 +199,7 @@ export function DMChat() {
});
});
}
}, [id, isLoadingOlder, fetchOlderMessages]);
}, [id, isLoadingOlder, hasMore, fetchOlderMessages]);
const messages = id ? messagesByConv[id] || [] : [];
useEffect(() => {