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