|
1 | 1 | import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react" |
2 | | -import { useDeepCompareEffect, useEvent, useMount } from "react-use" |
| 2 | +import { useDeepCompareEffect, useEvent, useMount, useWindowSize } from "react-use" |
3 | 3 | import debounce from "debounce" |
4 | 4 | import { Virtuoso, type VirtuosoHandle } from "react-virtuoso" |
5 | 5 | import removeMd from "remove-markdown" |
@@ -1743,6 +1743,22 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro |
1743 | 1743 | } |
1744 | 1744 | }, [handleKeyDown]) |
1745 | 1745 |
|
| 1746 | + // Use window size to calculate dynamic viewport |
| 1747 | + const { height: windowHeight } = useWindowSize() |
| 1748 | + |
| 1749 | + // Calculate dynamic bottom viewport based on window height |
| 1750 | + // For smaller screens (< 800px), use a smaller viewport to prevent jumping |
| 1751 | + // For larger screens, use a larger viewport for smoother scrolling |
| 1752 | + const dynamicBottomViewport = useMemo(() => { |
| 1753 | + if (!windowHeight) return 1000 // Default fallback |
| 1754 | + |
| 1755 | + // Scale the bottom viewport based on window height |
| 1756 | + // Minimum of 500px for very small screens, maximum of 2000px for large screens |
| 1757 | + const scaledViewport = Math.min(2000, Math.max(500, windowHeight * 0.8)) |
| 1758 | + |
| 1759 | + return Math.round(scaledViewport) |
| 1760 | + }, [windowHeight]) |
| 1761 | + |
1746 | 1762 | useImperativeHandle(ref, () => ({ |
1747 | 1763 | acceptInput: () => { |
1748 | 1764 | if (enableButtons && primaryButtonText) { |
@@ -1870,7 +1886,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro |
1870 | 1886 | ref={virtuosoRef} |
1871 | 1887 | key={task.ts} |
1872 | 1888 | className="scrollable grow overflow-y-scroll mb-1" |
1873 | | - increaseViewportBy={{ top: 3_000, bottom: 1000 }} |
| 1889 | + increaseViewportBy={{ top: 3_000, bottom: dynamicBottomViewport }} |
1874 | 1890 | data={groupedMessages} |
1875 | 1891 | itemContent={itemContent} |
1876 | 1892 | atBottomStateChange={(isAtBottom: boolean) => { |
|
0 commit comments