mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
fix: improve auto-scroll behavior during API activities and streaming
- Keep auto-scroll enabled during streaming unless user explicitly scrolls up - Prevent disabling auto-scroll when expanding rows during streaming - Improve scroll-to-bottom logic to handle API activities better - Fix issue where scrollbar jumps up during long conversations Fixes #6987
This commit is contained in:
parent
12d1959bbd
commit
0c3a8ba2aa
1 changed files with 41 additions and 30 deletions
|
|
@ -465,26 +465,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
const prev = prevExpandedRowsRef.current
|
||||
let wasAnyRowExpandedByUser = false
|
||||
if (prev) {
|
||||
// Check if any row transitioned from false/undefined to true
|
||||
for (const [tsKey, isExpanded] of Object.entries(expandedRows)) {
|
||||
const ts = Number(tsKey)
|
||||
if (isExpanded && !(prev[ts] ?? false)) {
|
||||
wasAnyRowExpandedByUser = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wasAnyRowExpandedByUser) {
|
||||
disableAutoScrollRef.current = true
|
||||
}
|
||||
prevExpandedRowsRef.current = expandedRows // Store current state for next comparison
|
||||
}, [expandedRows])
|
||||
|
||||
const isStreaming = useMemo(() => {
|
||||
// Checking clineAsk isn't enough since messages effect may be called
|
||||
// again for a tool for example, set clineAsk to its value, and if the
|
||||
|
|
@ -529,6 +509,27 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
return false
|
||||
}, [modifiedMessages, clineAsk, enableButtons, primaryButtonText])
|
||||
|
||||
useEffect(() => {
|
||||
const prev = prevExpandedRowsRef.current
|
||||
let wasAnyRowExpandedByUser = false
|
||||
if (prev) {
|
||||
// Check if any row transitioned from false/undefined to true
|
||||
for (const [tsKey, isExpanded] of Object.entries(expandedRows)) {
|
||||
const ts = Number(tsKey)
|
||||
if (isExpanded && !(prev[ts] ?? false)) {
|
||||
wasAnyRowExpandedByUser = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Don't disable auto-scroll during streaming even if rows are expanded
|
||||
if (wasAnyRowExpandedByUser && !isStreaming) {
|
||||
disableAutoScrollRef.current = true
|
||||
}
|
||||
prevExpandedRowsRef.current = expandedRows // Store current state for next comparison
|
||||
}, [expandedRows, isStreaming])
|
||||
|
||||
const markFollowUpAsAnswered = useCallback(() => {
|
||||
const lastFollowUpMessage = messagesRef.current.findLast((msg: ClineMessage) => msg.ask === "followup")
|
||||
if (lastFollowUpMessage) {
|
||||
|
|
@ -1390,7 +1391,8 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
|
||||
useEffect(() => {
|
||||
let timer: ReturnType<typeof setTimeout> | undefined
|
||||
if (!disableAutoScrollRef.current) {
|
||||
// Always scroll to bottom during streaming unless user explicitly scrolled up
|
||||
if (!disableAutoScrollRef.current || isStreaming) {
|
||||
timer = setTimeout(() => scrollToBottomSmooth(), 50)
|
||||
}
|
||||
return () => {
|
||||
|
|
@ -1398,18 +1400,23 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
clearTimeout(timer)
|
||||
}
|
||||
}
|
||||
}, [groupedMessages.length, scrollToBottomSmooth])
|
||||
}, [groupedMessages.length, scrollToBottomSmooth, isStreaming])
|
||||
|
||||
const handleWheel = useCallback((event: Event) => {
|
||||
const wheelEvent = event as WheelEvent
|
||||
const handleWheel = useCallback(
|
||||
(event: Event) => {
|
||||
const wheelEvent = event as WheelEvent
|
||||
|
||||
if (wheelEvent.deltaY && wheelEvent.deltaY < 0) {
|
||||
if (scrollContainerRef.current?.contains(wheelEvent.target as Node)) {
|
||||
// User scrolled up
|
||||
disableAutoScrollRef.current = true
|
||||
if (wheelEvent.deltaY && wheelEvent.deltaY < 0) {
|
||||
if (scrollContainerRef.current?.contains(wheelEvent.target as Node)) {
|
||||
// User scrolled up - but don't disable during streaming if we're near bottom
|
||||
if (!isStreaming || !isAtBottom) {
|
||||
disableAutoScrollRef.current = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
},
|
||||
[isStreaming, isAtBottom],
|
||||
)
|
||||
|
||||
useEvent("wheel", handleWheel, window, { passive: true }) // passive improves scrolling performance
|
||||
|
||||
|
|
@ -1878,6 +1885,10 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
if (isAtBottom) {
|
||||
disableAutoScrollRef.current = false
|
||||
}
|
||||
// During streaming, always keep auto-scroll enabled unless user explicitly scrolled
|
||||
if (isStreaming && isAtBottom) {
|
||||
disableAutoScrollRef.current = false
|
||||
}
|
||||
setShowScrollToBottom(disableAutoScrollRef.current && !isAtBottom)
|
||||
}}
|
||||
atBottomThreshold={10}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue