fix: scroll bottom issue (#4308)
This commit is contained in:
parent
4e43f9798d
commit
af84a3a8d9
@ -378,14 +378,14 @@ const ModelDropdown = ({
|
||||
!selectedModel && 'text-[hsla(var(--text-tertiary))]'
|
||||
)}
|
||||
>
|
||||
{selectedModel?.name || 'Select Model'}
|
||||
{selectedModel?.name || 'Select a model'}
|
||||
</span>
|
||||
</Badge>
|
||||
) : (
|
||||
<Input
|
||||
value={selectedModel?.name || ''}
|
||||
className="cursor-pointer"
|
||||
placeholder="Select Model"
|
||||
placeholder="Select a model"
|
||||
disabled={disabled}
|
||||
readOnly
|
||||
suffixIcon={
|
||||
|
||||
@ -23,9 +23,7 @@ const EmptyThread = () => {
|
||||
<LogoMark className="mx-auto mb-2 animate-wave" width={32} height={32} />
|
||||
{showOnboardingStep ? (
|
||||
<>
|
||||
<p className="mt-1 font-medium">
|
||||
{`You don't have a local model yet.`}
|
||||
</p>
|
||||
<p className="mt-1 font-medium">{`You don't have any model`}</p>
|
||||
<Button
|
||||
onClick={() => setMainViewState(MainViewState.Hub)}
|
||||
variant="soft"
|
||||
|
||||
@ -14,7 +14,11 @@ import LoadModelError from '../LoadModelError'
|
||||
import EmptyThread from './EmptyThread'
|
||||
|
||||
import { getCurrentChatMessagesAtom } from '@/helpers/atoms/ChatMessage.atom'
|
||||
import { activeThreadAtom } from '@/helpers/atoms/Thread.atom'
|
||||
import {
|
||||
activeThreadAtom,
|
||||
isGeneratingResponseAtom,
|
||||
threadStatesAtom,
|
||||
} from '@/helpers/atoms/Thread.atom'
|
||||
|
||||
const ChatConfigurator = memo(() => {
|
||||
const messages = useAtomValue(getCurrentChatMessagesAtom)
|
||||
@ -61,6 +65,12 @@ const ChatBody = memo(
|
||||
const prevScrollTop = useRef(0)
|
||||
const isUserManuallyScrollingUp = useRef(false)
|
||||
const currentThread = useAtomValue(activeThreadAtom)
|
||||
const threadStates = useAtomValue(threadStatesAtom)
|
||||
const isGeneratingResponse = useAtomValue(isGeneratingResponseAtom)
|
||||
|
||||
const isStreamingResponse = Object.values(threadStates).some(
|
||||
(threadState) => threadState.waitingForResponse
|
||||
)
|
||||
|
||||
const count = useMemo(
|
||||
() => (messages?.length ?? 0) + (loadModelError ? 1 : 0),
|
||||
@ -76,15 +86,23 @@ const ChatBody = memo(
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// Delay the scroll until the DOM is updated
|
||||
if (parentRef.current) {
|
||||
if (parentRef.current && isGeneratingResponse) {
|
||||
requestAnimationFrame(() => {
|
||||
if (parentRef.current) {
|
||||
parentRef.current.scrollTo({ top: parentRef.current.scrollHeight })
|
||||
virtualizer.scrollToIndex(count - 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [count, virtualizer, isGeneratingResponse])
|
||||
|
||||
useEffect(() => {
|
||||
isUserManuallyScrollingUp.current = false
|
||||
requestAnimationFrame(() => {
|
||||
if (parentRef.current) {
|
||||
parentRef.current.scrollTo({ top: parentRef.current.scrollHeight })
|
||||
virtualizer.scrollToIndex(count - 1)
|
||||
}
|
||||
})
|
||||
}, [count, currentThread?.id, virtualizer])
|
||||
|
||||
const items = virtualizer.getVirtualItems()
|
||||
@ -94,34 +112,38 @@ const ChatBody = memo(
|
||||
_,
|
||||
instance
|
||||
) => {
|
||||
if (isUserManuallyScrollingUp.current === true) return false
|
||||
if (isUserManuallyScrollingUp.current === true && isStreamingResponse)
|
||||
return false
|
||||
return (
|
||||
// item.start < (instance.scrollOffset ?? 0) &&
|
||||
instance.scrollDirection !== 'backward'
|
||||
)
|
||||
}
|
||||
|
||||
const handleScroll = useCallback((event: React.UIEvent<HTMLElement>) => {
|
||||
const currentScrollTop = event.currentTarget.scrollTop
|
||||
|
||||
if (prevScrollTop.current > currentScrollTop) {
|
||||
isUserManuallyScrollingUp.current = true
|
||||
} else {
|
||||
const handleScroll = useCallback(
|
||||
(event: React.UIEvent<HTMLElement>) => {
|
||||
const currentScrollTop = event.currentTarget.scrollTop
|
||||
const scrollHeight = event.currentTarget.scrollHeight
|
||||
const clientHeight = event.currentTarget.clientHeight
|
||||
|
||||
if (currentScrollTop + clientHeight >= scrollHeight) {
|
||||
isUserManuallyScrollingUp.current = false
|
||||
if (prevScrollTop.current > currentScrollTop && isStreamingResponse) {
|
||||
isUserManuallyScrollingUp.current = true
|
||||
} else {
|
||||
const currentScrollTop = event.currentTarget.scrollTop
|
||||
const scrollHeight = event.currentTarget.scrollHeight
|
||||
const clientHeight = event.currentTarget.clientHeight
|
||||
|
||||
if (currentScrollTop + clientHeight >= scrollHeight) {
|
||||
isUserManuallyScrollingUp.current = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isUserManuallyScrollingUp.current === true) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
}
|
||||
prevScrollTop.current = currentScrollTop
|
||||
}, [])
|
||||
if (isUserManuallyScrollingUp.current === true) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
}
|
||||
prevScrollTop.current = currentScrollTop
|
||||
},
|
||||
[isStreamingResponse]
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col overflow-x-hidden">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user