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:
2025-12-20 17:44:46 +01:00
parent e5d17bfad3
commit 8d33294cc5

View File

@@ -182,6 +182,42 @@ export const MessageList = memo(function MessageList({ messages, isProcessing, o
const [newMessageCount, setNewMessageCount] = useState(0);
const prevMessageCount = useRef(messages.length);
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
const checkIfAtBottom = useCallback(() => {
@@ -203,9 +239,6 @@ export const MessageList = memo(function MessageList({ messages, isProcessing, o
}
}, [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
// Optimized: only rebuild when structure changes, not content
const processedMessages = useMemo(() => {