fix: Reset scroll state when switching between split/tabbed view
The "Back to bottom" button was incorrectly appearing after switching from split view to tabbed view because scroll-related refs weren't being reset when the session changed. Added session change detection that resets: - userScrolledAway ref - showScrollButton state - newMessageCount counter - processedMessages cache 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -182,6 +182,42 @@ export const MessageList = memo(function MessageList({ messages, isProcessing, o
|
|||||||
const [newMessageCount, setNewMessageCount] = useState(0);
|
const [newMessageCount, setNewMessageCount] = useState(0);
|
||||||
const prevMessageCount = useRef(messages.length);
|
const prevMessageCount = useRef(messages.length);
|
||||||
const userScrolledAway = useRef(false);
|
const userScrolledAway = useRef(false);
|
||||||
|
const prevHostId = useRef(hostId);
|
||||||
|
|
||||||
|
// Cache for incremental updates - avoid full rebuild on streaming content changes
|
||||||
|
// Moved up so it's available for the reset effect
|
||||||
|
const processedCacheRef = useRef({ messages: [], result: [], toolResultMap: new Map() });
|
||||||
|
|
||||||
|
// Reset scroll state when switching sessions (hostId changes or messages array replaced)
|
||||||
|
// This fixes the "scroll to bottom" button appearing incorrectly after switching from split view
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
// Detect session change by checking if hostId changed or if messages were reset
|
||||||
|
const hostChanged = prevHostId.current !== hostId;
|
||||||
|
const messagesReset = messages.length === 0 ||
|
||||||
|
(prevMessageCount.current > 0 && messages.length > 0 &&
|
||||||
|
messages[0]?.timestamp !== processedCacheRef.current.messages[0]?.timestamp);
|
||||||
|
|
||||||
|
if (hostChanged || messagesReset) {
|
||||||
|
// Reset all scroll-related state
|
||||||
|
userScrolledAway.current = false;
|
||||||
|
setShowScrollButton(false);
|
||||||
|
setNewMessageCount(0);
|
||||||
|
prevMessageCount.current = messages.length;
|
||||||
|
prevHostId.current = hostId;
|
||||||
|
|
||||||
|
// Clear processed cache to force rebuild
|
||||||
|
processedCacheRef.current = { messages: [], result: [], toolResultMap: new Map() };
|
||||||
|
|
||||||
|
// Scroll to bottom after session switch
|
||||||
|
if (containerRef.current) {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (containerRef.current) {
|
||||||
|
containerRef.current.scrollTop = containerRef.current.scrollHeight;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [hostId, messages]);
|
||||||
|
|
||||||
// Check if scrolled to bottom
|
// Check if scrolled to bottom
|
||||||
const checkIfAtBottom = useCallback(() => {
|
const checkIfAtBottom = useCallback(() => {
|
||||||
@@ -203,9 +239,6 @@ export const MessageList = memo(function MessageList({ messages, isProcessing, o
|
|||||||
}
|
}
|
||||||
}, [checkIfAtBottom]);
|
}, [checkIfAtBottom]);
|
||||||
|
|
||||||
// Cache for incremental updates - avoid full rebuild on streaming content changes
|
|
||||||
const processedCacheRef = useRef({ messages: [], result: [], toolResultMap: new Map() });
|
|
||||||
|
|
||||||
// Preprocess messages to pair tool_use with tool_result
|
// Preprocess messages to pair tool_use with tool_result
|
||||||
// Optimized: only rebuild when structure changes, not content
|
// Optimized: only rebuild when structure changes, not content
|
||||||
const processedMessages = useMemo(() => {
|
const processedMessages = useMemo(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user