MCPcopy Create free account
hub / github.com/codeaashu/claude-code / VirtualMessageList

Function VirtualMessageList

web/components/chat/VirtualMessageList.tsx:39–114  ·  view source on GitHub ↗
({ messages, isStreaming }: VirtualMessageListProps)

Source from the content-addressed store, hash-verified

37}
38
39export function VirtualMessageList({ messages, isStreaming }: VirtualMessageListProps) {
40 const scrollRef = useRef<HTMLDivElement>(null);
41 const isAtBottomRef = useRef(true);
42
43 const virtualizer = useVirtualizer({
44 count: messages.length,
45 getScrollElement: () => scrollRef.current,
46 estimateSize: (index) => estimateMessageHeight(messages[index]),
47 overscan: 5,
48 });
49
50 // Track whether the user has scrolled away from the bottom
51 const handleScroll = useCallback(() => {
52 const el = scrollRef.current;
53 if (!el) return;
54 const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
55 isAtBottomRef.current = distanceFromBottom < 80;
56 }, []);
57
58 // Auto-scroll to bottom when new messages arrive (if already at bottom)
59 useEffect(() => {
60 if (!isAtBottomRef.current) return;
61 const el = scrollRef.current;
62 if (!el) return;
63 if (isStreaming) {
64 // Instant scroll during streaming to keep up with tokens
65 el.scrollTop = el.scrollHeight;
66 } else {
67 el.scrollTo({ top: el.scrollHeight, behavior: "smooth" });
68 }
69 }, [messages.length, isStreaming]);
70
71 // Also scroll when the last streaming message content changes
72 useEffect(() => {
73 if (!isStreaming || !isAtBottomRef.current) return;
74 const el = scrollRef.current;
75 if (el) el.scrollTop = el.scrollHeight;
76 });
77
78 const items = virtualizer.getVirtualItems();
79
80 return (
81 <div
82 ref={scrollRef}
83 className="flex-1 overflow-y-auto"
84 onScroll={handleScroll}
85 >
86 {/* Spacer that gives the virtualizer its total height */}
87 <div
88 style={{ height: virtualizer.getTotalSize(), position: "relative" }}
89 className="max-w-3xl mx-auto px-4 py-6"
90 >
91 {items.map((virtualItem) => {
92 const message = messages[virtualItem.index];
93 return (
94 <div
95 key={virtualItem.key}
96 data-index={virtualItem.index}

Callers

nothing calls this directly

Calls 1

estimateMessageHeightFunction · 0.85

Tested by

no test coverage detected