-
Notifications
You must be signed in to change notification settings - Fork 2.7k
fix: dynamic viewport adjustment to prevent scroll jumping on small screens #7027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react" | ||
| import { useDeepCompareEffect, useEvent, useMount } from "react-use" | ||
| import { useDeepCompareEffect, useEvent, useMount, useWindowSize } from "react-use" | ||
| import debounce from "debounce" | ||
| import { Virtuoso, type VirtuosoHandle } from "react-virtuoso" | ||
| import removeMd from "remove-markdown" | ||
|
|
@@ -1743,6 +1743,22 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro | |
| } | ||
| }, [handleKeyDown]) | ||
|
|
||
| // Use window size to calculate dynamic viewport | ||
| const { height: windowHeight } = useWindowSize() | ||
|
|
||
| // Calculate dynamic bottom viewport based on window height | ||
| // For smaller screens (< 800px), use a smaller viewport to prevent jumping | ||
| // For larger screens, use a larger viewport for smoother scrolling | ||
| const dynamicBottomViewport = useMemo(() => { | ||
| if (!windowHeight) return 1000 // Default fallback | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it intentional that when is undefined, we fall back to 1000px - the same fixed value that was causing the original scrolling issues on smaller screens? Should we consider using a smaller default or calculating based on a typical small screen height? |
||
|
|
||
| // Scale the bottom viewport based on window height | ||
| // Minimum of 500px for very small screens, maximum of 2000px for large screens | ||
| const scaledViewport = Math.min(2000, Math.max(500, windowHeight * 0.8)) | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These magic numbers (0.8 for 80%, 500px min, 2000px max) work well but aren't self-documenting. Would it be helpful to extract these as named constants? |
||
|
|
||
| return Math.round(scaledViewport) | ||
| }, [windowHeight]) | ||
|
|
||
| useImperativeHandle(ref, () => ({ | ||
| acceptInput: () => { | ||
| if (enableButtons && primaryButtonText) { | ||
|
|
@@ -1870,7 +1886,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro | |
| ref={virtuosoRef} | ||
| key={task.ts} | ||
| className="scrollable grow overflow-y-scroll mb-1" | ||
| increaseViewportBy={{ top: 3_000, bottom: 1000 }} | ||
| increaseViewportBy={{ top: 3_000, bottom: dynamicBottomViewport }} | ||
| data={groupedMessages} | ||
| itemContent={itemContent} | ||
| atBottomStateChange={(isAtBottom: boolean) => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The calculation will recalculate whenever changes. Since window resize events can fire frequently during resizing, could this cause performance issues? Would it be worth considering debouncing the window size changes to reduce recalculations?