Skip to content
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

fix: update scroll issue and copywritting #4305

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions web/containers/ModelDropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,14 @@

const handleChangeStateOpen = useCallback(
(state: boolean) => {
setOpen(state)
setModelDropdownState(state)

Check warning on line 120 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

119-120 lines are not covered with tests
},
[setModelDropdownState]
)

const isModelSupportRagAndTools = useCallback((model: Model) => {
return (

Check warning on line 126 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

126 line is not covered with tests
model?.engine === InferenceEngine.openai ||
isLocalEngine(model?.engine as InferenceEngine)
)
Expand All @@ -134,7 +134,7 @@
configuredModels
.concat(
downloadedModels.filter(
(e) => !configuredModels.some((x) => x.id === e.id)

Check warning on line 137 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

137 line is not covered with tests
)
)
.filter((e) =>
Expand All @@ -144,24 +144,24 @@
if (searchFilter === 'local') {
return isLocalEngine(e.engine)
}
if (searchFilter === 'remote') {
return !isLocalEngine(e.engine)

Check warning on line 148 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

147-148 lines are not covered with tests
}
})
.sort((a, b) => a.name.localeCompare(b.name))

Check warning on line 151 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

151 line is not covered with tests
.sort((a, b) => {
const aInDownloadedModels = downloadedModels.some(
(item) => item.id === a.id

Check warning on line 154 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

153-154 lines are not covered with tests
)
const bInDownloadedModels = downloadedModels.some(
(item) => item.id === b.id

Check warning on line 157 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

156-157 lines are not covered with tests
)
if (aInDownloadedModels && !bInDownloadedModels) {
return -1
} else if (!aInDownloadedModels && bInDownloadedModels) {
return 1

Check warning on line 162 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

159-162 lines are not covered with tests
} else {
return 0

Check warning on line 164 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

164 line is not covered with tests
}
}),
[configuredModels, searchText, searchFilter, downloadedModels]
Expand Down Expand Up @@ -198,10 +198,10 @@

const onClickModelItem = useCallback(
async (modelId: string) => {
if (!activeAssistant) return
const model = downloadedModels.find((m) => m.id === modelId)
setSelectedModel(model)
setOpen(false)

Check warning on line 204 in web/containers/ModelDropdown/index.tsx

View workflow job for this annotation

GitHub Actions / coverage-check

201-204 lines are not covered with tests

if (activeThread) {
// Change assistand tools based on model support RAG
Expand Down Expand Up @@ -378,14 +378,14 @@
!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={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
68 changes: 51 additions & 17 deletions web/screens/Thread/ThreadCenterPanel/ChatBody/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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),
Expand All @@ -77,14 +87,25 @@ 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(() => {
// Delay the scroll until the DOM is updated

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()
Expand All @@ -94,34 +115,47 @@ 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

if (!isStreamingResponse) {
isUserManuallyScrollingUp.current = false
}

if (isGeneratingResponse) {
isUserManuallyScrollingUp.current = false
}

if (prevScrollTop.current > currentScrollTop && isStreamingResponse) {
isUserManuallyScrollingUp.current = true
} else {
isUserManuallyScrollingUp.current = false
}

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, isGeneratingResponse]
)

return (
<div className="flex h-full w-full flex-col overflow-x-hidden">
Expand Down
Loading