Description
In source-detail-panel.tsx, when opening the panel to a cited chunk, multiple setTimeouts are fired at staggered delays (50ms, 150ms, 300ms, 600ms, 1000ms) to scroll to the cited chunk. None of these are tracked or cleared — if the user closes the panel before all fire, setHasScrolledToCited and setActiveChunkIndex are called on a closed/unmounted panel.
File to change
surfsense_web/components/new-chat/source-detail-panel.tsx (lines 230-245)
Current code
const scrollAttempts = [50, 150, 300, 600, 1000];
scrollAttempts.forEach((delay) => {
setTimeout(() => { scrollToCitedChunk(); }, delay);
});
setTimeout(() => {
setHasScrolledToCited(true);
setActiveChunkIndex(citedChunkIndex);
}, scrollAttempts[scrollAttempts.length - 1] + 50);
What to do
- Store timeout IDs in a ref:
const scrollTimersRef = useRef<ReturnType<typeof setTimeout>[]>([]);
- Push each
setTimeout return value into scrollTimersRef.current
- Clear all timers when
open becomes false or on unmount:
useEffect(() => {
if (!open) {
scrollTimersRef.current.forEach(clearTimeout);
scrollTimersRef.current = [];
}
return () => {
scrollTimersRef.current.forEach(clearTimeout);
scrollTimersRef.current = [];
};
}, [open]);
Acceptance criteria
- All scroll timeouts are cleared when the panel closes or unmounts
- Scroll-to-cited-chunk still works when panel stays open
Description
In
source-detail-panel.tsx, when opening the panel to a cited chunk, multiplesetTimeouts are fired at staggered delays (50ms, 150ms, 300ms, 600ms, 1000ms) to scroll to the cited chunk. None of these are tracked or cleared — if the user closes the panel before all fire,setHasScrolledToCitedandsetActiveChunkIndexare called on a closed/unmounted panel.File to change
surfsense_web/components/new-chat/source-detail-panel.tsx(lines 230-245)Current code
What to do
const scrollTimersRef = useRef<ReturnType<typeof setTimeout>[]>([]);setTimeoutreturn value intoscrollTimersRef.currentopenbecomes false or on unmount:Acceptance criteria