Unverified Commit f2b2effc authored by zxhlyh's avatar zxhlyh Committed by GitHub

fix: typing delay (#2200)

parent 301e0496
...@@ -43,6 +43,7 @@ const IconWrapper: FC<{ children: React.ReactNode | string }> = ({ children }) = ...@@ -43,6 +43,7 @@ const IconWrapper: FC<{ children: React.ReactNode | string }> = ({ children }) =
} }
export type IAnswerProps = { export type IAnswerProps = {
item: IChatItem item: IChatItem
index: number
feedbackDisabled: boolean feedbackDisabled: boolean
isHideFeedbackEdit: boolean isHideFeedbackEdit: boolean
onQueryChange: (query: string) => void onQueryChange: (query: string) => void
...@@ -59,14 +60,15 @@ export type IAnswerProps = { ...@@ -59,14 +60,15 @@ export type IAnswerProps = {
supportAnnotation?: boolean supportAnnotation?: boolean
appId?: string appId?: string
question: string question: string
onAnnotationEdited?: (question: string, answer: string) => void onAnnotationEdited?: (question: string, answer: string, index: number) => void
onAnnotationAdded?: (annotationId: string, authorName: string, question: string, answer: string) => void onAnnotationAdded?: (annotationId: string, authorName: string, question: string, answer: string, index: number) => void
onAnnotationRemoved?: () => void onAnnotationRemoved?: (index: number) => void
allToolIcons?: Record<string, string | Emoji> allToolIcons?: Record<string, string | Emoji>
} }
// The component needs to maintain its own state to control whether to display input component // The component needs to maintain its own state to control whether to display input component
const Answer: FC<IAnswerProps> = ({ const Answer: FC<IAnswerProps> = ({
item, item,
index,
onQueryChange, onQueryChange,
feedbackDisabled = false, feedbackDisabled = false,
isHideFeedbackEdit = false, isHideFeedbackEdit = false,
...@@ -340,9 +342,9 @@ const Answer: FC<IAnswerProps> = ({ ...@@ -340,9 +342,9 @@ const Answer: FC<IAnswerProps> = ({
cached={hasAnnotation} cached={hasAnnotation}
query={question} query={question}
answer={content} answer={content}
onAdded={(id, authorName) => onAnnotationAdded?.(id, authorName, question, content)} onAdded={(id, authorName) => onAnnotationAdded?.(id, authorName, question, content, index)}
onEdit={() => setIsShowReplyModal(true)} onEdit={() => setIsShowReplyModal(true)}
onRemoved={onAnnotationRemoved!} onRemoved={() => onAnnotationRemoved!(index)}
/> />
)} )}
...@@ -351,8 +353,8 @@ const Answer: FC<IAnswerProps> = ({ ...@@ -351,8 +353,8 @@ const Answer: FC<IAnswerProps> = ({
onHide={() => setIsShowReplyModal(false)} onHide={() => setIsShowReplyModal(false)}
query={question} query={question}
answer={content} answer={content}
onEdited={onAnnotationEdited!} onEdited={(editedQuery, editedAnswer) => onAnnotationEdited!(editedQuery, editedAnswer, index)}
onAdded={onAnnotationAdded!} onAdded={(annotationId, authorName, editedQuery, editedAnswer) => onAnnotationAdded!(annotationId, authorName, editedQuery, editedAnswer, index)}
appId={appId!} appId={appId!}
messageId={id} messageId={id}
annotationId={annotation?.id || ''} annotationId={annotation?.id || ''}
......
'use client' 'use client'
import type { FC, ReactNode } from 'react' import type { FC, ReactNode } from 'react'
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react' import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
import Textarea from 'rc-textarea' import Textarea from 'rc-textarea'
import { useContext } from 'use-context-selector' import { useContext } from 'use-context-selector'
import cn from 'classnames' import cn from 'classnames'
...@@ -197,6 +197,76 @@ const Chat: FC<IChatProps> = ({ ...@@ -197,6 +197,76 @@ const Chat: FC<IChatProps> = ({
logError(t('common.voiceInput.notAllow')) logError(t('common.voiceInput.notAllow'))
}) })
} }
const handleQueryChangeFromAnswer = useCallback((val: string) => {
onQueryChange(val)
handleSend(val)
}, [])
const handleAnnotationEdited = useCallback((query: string, answer: string, index: number) => {
onChatListChange?.(chatList.map((item, i) => {
if (i === index - 1) {
return {
...item,
content: query,
}
}
if (i === index) {
return {
...item,
content: answer,
annotation: {
...item.annotation,
logAnnotation: undefined,
} as any,
}
}
return item
}))
}, [])
const handleAnnotationAdded = useCallback((annotationId: string, authorName: string, query: string, answer: string, index: number) => {
onChatListChange?.(chatList.map((item, i) => {
if (i === index - 1) {
return {
...item,
content: query,
}
}
if (i === index) {
const answerItem = {
...item,
content: item.content,
annotation: {
id: annotationId,
authorName,
logAnnotation: {
content: answer,
account: {
id: '',
name: authorName,
email: '',
},
},
} as Annotation,
}
return answerItem
}
return item
}))
}, [])
const handleAnnotationRemoved = useCallback((index: number) => {
onChatListChange?.(chatList.map((item, i) => {
if (i === index) {
return {
...item,
content: item.content,
annotation: {
...(item.annotation || {}),
id: '',
} as Annotation,
}
}
return item
}))
}, [])
return ( return (
<div className={cn('px-3.5', 'h-full')}> <div className={cn('px-3.5', 'h-full')}>
...@@ -210,10 +280,8 @@ const Chat: FC<IChatProps> = ({ ...@@ -210,10 +280,8 @@ const Chat: FC<IChatProps> = ({
return <Answer return <Answer
key={item.id} key={item.id}
item={item} item={item}
onQueryChange={(val) => { index={index}
onQueryChange(val) onQueryChange={handleQueryChangeFromAnswer}
handleSend(val)
}}
feedbackDisabled={feedbackDisabled} feedbackDisabled={feedbackDisabled}
isHideFeedbackEdit={isHideFeedbackEdit} isHideFeedbackEdit={isHideFeedbackEdit}
onFeedback={onFeedback} onFeedback={onFeedback}
...@@ -228,72 +296,9 @@ const Chat: FC<IChatProps> = ({ ...@@ -228,72 +296,9 @@ const Chat: FC<IChatProps> = ({
supportAnnotation={supportAnnotation} supportAnnotation={supportAnnotation}
appId={appId} appId={appId}
question={chatList[index - 1]?.content} question={chatList[index - 1]?.content}
onAnnotationEdited={(query, answer) => { onAnnotationEdited={handleAnnotationEdited}
onChatListChange?.(chatList.map((item, i) => { onAnnotationAdded={handleAnnotationAdded}
if (i === index - 1) { onAnnotationRemoved={handleAnnotationRemoved}
return {
...item,
content: query,
}
}
if (i === index) {
return {
...item,
content: answer,
annotation: {
...item.annotation,
logAnnotation: undefined,
} as any,
}
}
return item
}))
}}
onAnnotationAdded={(annotationId, authorName, query, answer) => {
onChatListChange?.(chatList.map((item, i) => {
if (i === index - 1) {
return {
...item,
content: query,
}
}
if (i === index) {
const answerItem = {
...item,
content: item.content,
annotation: {
id: annotationId,
authorName,
logAnnotation: {
content: answer,
account: {
id: '',
name: authorName,
email: '',
},
},
} as Annotation,
}
return answerItem
}
return item
}))
}}
onAnnotationRemoved={() => {
onChatListChange?.(chatList.map((item, i) => {
if (i === index) {
return {
...item,
content: item.content,
annotation: {
...(item.annotation || {}),
id: '',
} as Annotation,
}
}
return item
}))
}}
allToolIcons={allToolIcons} allToolIcons={allToolIcons}
/> />
} }
...@@ -307,8 +312,6 @@ const Chat: FC<IChatProps> = ({ ...@@ -307,8 +312,6 @@ const Chat: FC<IChatProps> = ({
item={item} item={item}
isShowPromptLog={isShowPromptLog} isShowPromptLog={isShowPromptLog}
isResponsing={isResponsing} isResponsing={isResponsing}
// ['https://placekitten.com/360/360', 'https://placekitten.com/360/640']
imgSrcs={(item.message_files && item.message_files?.length > 0) ? item.message_files.map(item => item.url) : []}
/> />
) )
})} })}
......
...@@ -13,14 +13,14 @@ import ImageGallery from '@/app/components/base/image-gallery' ...@@ -13,14 +13,14 @@ import ImageGallery from '@/app/components/base/image-gallery'
type IQuestionProps = Pick<IChatItem, 'id' | 'content' | 'more' | 'useCurrentUserAvatar'> & { type IQuestionProps = Pick<IChatItem, 'id' | 'content' | 'more' | 'useCurrentUserAvatar'> & {
isShowPromptLog?: boolean isShowPromptLog?: boolean
item: IChatItem item: IChatItem
imgSrcs?: string[]
isResponsing?: boolean isResponsing?: boolean
} }
const Question: FC<IQuestionProps> = ({ id, content, imgSrcs, more, useCurrentUserAvatar, isShowPromptLog, item, isResponsing }) => { const Question: FC<IQuestionProps> = ({ id, content, more, useCurrentUserAvatar, isShowPromptLog, item, isResponsing }) => {
const { userProfile } = useContext(AppContext) const { userProfile } = useContext(AppContext)
const userName = userProfile?.name const userName = userProfile?.name
const ref = useRef(null) const ref = useRef(null)
const imgSrcs = item.message_files?.map(item => item.url)
return ( return (
<div className={`flex items-start justify-end ${isShowPromptLog && 'first-of-type:pt-[14px]'}`} key={id} ref={ref}> <div className={`flex items-start justify-end ${isShowPromptLog && 'first-of-type:pt-[14px]'}`} key={id} ref={ref}>
......
import { useState } from 'react' import { useCallback, useState } from 'react'
import produce from 'immer' import produce from 'immer'
import { useGetState } from 'ahooks' import { useGetState } from 'ahooks'
import type { ConversationItem } from '@/models/share' import type { ConversationItem } from '@/models/share'
...@@ -11,7 +11,7 @@ function useConversation() { ...@@ -11,7 +11,7 @@ function useConversation() {
const [pinnedConversationList, setPinnedConversationList] = useState<ConversationItem[]>([]) const [pinnedConversationList, setPinnedConversationList] = useState<ConversationItem[]>([])
const [currConversationId, doSetCurrConversationId, getCurrConversationId] = useGetState<string>('-1') const [currConversationId, doSetCurrConversationId, getCurrConversationId] = useGetState<string>('-1')
// when set conversation id, we do not have set appId // when set conversation id, we do not have set appId
const setCurrConversationId = (id: string, appId: string, isSetToLocalStroge = true, newConversationName = '') => { const setCurrConversationId = useCallback((id: string, appId: string, isSetToLocalStroge = true, newConversationName = '') => {
doSetCurrConversationId(id) doSetCurrConversationId(id)
if (isSetToLocalStroge && id !== '-1') { if (isSetToLocalStroge && id !== '-1') {
// conversationIdInfo: {[appId1]: conversationId1, [appId2]: conversationId2} // conversationIdInfo: {[appId1]: conversationId1, [appId2]: conversationId2}
...@@ -19,7 +19,7 @@ function useConversation() { ...@@ -19,7 +19,7 @@ function useConversation() {
conversationIdInfo[appId] = id conversationIdInfo[appId] = id
globalThis.localStorage?.setItem(storageConversationIdKey, JSON.stringify(conversationIdInfo)) globalThis.localStorage?.setItem(storageConversationIdKey, JSON.stringify(conversationIdInfo))
} }
} }, [doSetCurrConversationId])
const getConversationIdFromStorage = (appId: string) => { const getConversationIdFromStorage = (appId: string) => {
const conversationIdInfo = globalThis.localStorage?.getItem(storageConversationIdKey) ? JSON.parse(globalThis.localStorage?.getItem(storageConversationIdKey) || '') : {} const conversationIdInfo = globalThis.localStorage?.getItem(storageConversationIdKey) ? JSON.parse(globalThis.localStorage?.getItem(storageConversationIdKey) || '') : {}
......
This diff is collapsed.
import React, { useEffect, useState } from 'react' import React, { useCallback, useEffect, useState } from 'react'
import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { import {
...@@ -76,6 +76,13 @@ const Sidebar: FC<ISidebarProps> = ({ ...@@ -76,6 +76,13 @@ const Sidebar: FC<ISidebarProps> = ({
checkHasPinned() checkHasPinned()
}, [controlUpdateList]) }, [controlUpdateList])
const handleUnpin = useCallback((id: string) => {
onUnpin(id)
}, [onUnpin])
const handlePin = useCallback((id: string) => {
onPin(id)
}, [onPin])
const maxListHeight = (isInstalledApp) ? 'max-h-[30vh]' : 'max-h-[40vh]' const maxListHeight = (isInstalledApp) ? 'max-h-[30vh]' : 'max-h-[40vh]'
return ( return (
...@@ -119,7 +126,7 @@ const Sidebar: FC<ISidebarProps> = ({ ...@@ -119,7 +126,7 @@ const Sidebar: FC<ISidebarProps> = ({
onMoreLoaded={onPinnedMoreLoaded} onMoreLoaded={onPinnedMoreLoaded}
isNoMore={isPinnedNoMore} isNoMore={isPinnedNoMore}
isPinned={true} isPinned={true}
onPinChanged={id => onUnpin(id)} onPinChanged={handleUnpin}
controlUpdate={controlUpdateList + 1} controlUpdate={controlUpdateList + 1}
onDelete={onDelete} onDelete={onDelete}
/> />
...@@ -142,7 +149,7 @@ const Sidebar: FC<ISidebarProps> = ({ ...@@ -142,7 +149,7 @@ const Sidebar: FC<ISidebarProps> = ({
onMoreLoaded={onMoreLoaded} onMoreLoaded={onMoreLoaded}
isNoMore={isNoMore} isNoMore={isNoMore}
isPinned={false} isPinned={false}
onPinChanged={id => onPin(id)} onPinChanged={handlePin}
controlUpdate={controlUpdateList + 1} controlUpdate={controlUpdateList + 1}
onDelete={onDelete} onDelete={onDelete}
/> />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment