fix: history page message search

This commit is contained in:
Pleasurecruise 2025-05-19 01:42:03 +08:00
parent 7b4f79aab5
commit 2af0b87ce5
No known key found for this signature in database
GPG Key ID: E6385136096279B6
2 changed files with 56 additions and 30 deletions

View File

@ -3,6 +3,7 @@ import { HStack } from '@renderer/components/Layout'
import SearchPopup from '@renderer/components/Popups/SearchPopup' import SearchPopup from '@renderer/components/Popups/SearchPopup'
import useScrollPosition from '@renderer/hooks/useScrollPosition' import useScrollPosition from '@renderer/hooks/useScrollPosition'
import { useSettings } from '@renderer/hooks/useSettings' import { useSettings } from '@renderer/hooks/useSettings'
import { ChatProvider } from '@renderer/pages/home/Messages/ChatContext'
import { getAssistantById } from '@renderer/services/AssistantService' import { getAssistantById } from '@renderer/services/AssistantService'
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
import { isGenerating, locateToMessage } from '@renderer/services/MessagesService' import { isGenerating, locateToMessage } from '@renderer/services/MessagesService'
@ -46,31 +47,33 @@ const TopicMessages: FC<Props> = ({ topic, ...props }) => {
} }
return ( return (
<MessagesContainer {...props} ref={containerRef} onScroll={handleScroll} className={messageStyle}> <ChatProvider activeTopic={topic} isHistoryView={true}>
<ContainerWrapper style={{ paddingTop: 30, paddingBottom: 30 }}> <MessagesContainer {...props} ref={containerRef} onScroll={handleScroll} className={messageStyle}>
{topic?.messages.map((message) => ( <ContainerWrapper style={{ paddingTop: 30, paddingBottom: 30 }}>
<div key={message.id} style={{ position: 'relative' }}> {topic?.messages.map((message) => (
<MessageItem message={message} topic={topic} /> <div key={message.id} style={{ position: 'relative' }}>
<Button <MessageItem message={message} topic={topic} />
type="text" <Button
size="middle" type="text"
style={{ color: 'var(--color-text-3)', position: 'absolute', right: 0, top: 5 }} size="middle"
onClick={() => locateToMessage(navigate, message)} style={{ color: 'var(--color-text-3)', position: 'absolute', right: 0, top: 5 }}
icon={<ArrowRightOutlined />} onClick={() => locateToMessage(navigate, message)}
/> icon={<ArrowRightOutlined />}
<Divider style={{ margin: '8px auto 15px' }} variant="dashed" /> />
</div> <Divider style={{ margin: '8px auto 15px' }} variant="dashed" />
))} </div>
{isEmpty && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />} ))}
{!isEmpty && ( {isEmpty && <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />}
<HStack justifyContent="center"> {!isEmpty && (
<Button onClick={() => onContinueChat(topic)} icon={<MessageOutlined />}> <HStack justifyContent="center">
{t('history.continue_chat')} <Button onClick={() => onContinueChat(topic)} icon={<MessageOutlined />}>
</Button> {t('history.continue_chat')}
</HStack> </Button>
)} </HStack>
</ContainerWrapper> )}
</MessagesContainer> </ContainerWrapper>
</MessagesContainer>
</ChatProvider>
) )
} }

View File

@ -12,10 +12,16 @@ interface ChatContextProps {
toggleMultiSelectMode: (value: boolean) => void toggleMultiSelectMode: (value: boolean) => void
handleMultiSelectAction: (actionType: string, messageIds: string[]) => void handleMultiSelectAction: (actionType: string, messageIds: string[]) => void
activeTopic: Topic activeTopic: Topic
locateMessage: (messageId: string) => void
messageRefs: Map<string, HTMLElement> messageRefs: Map<string, HTMLElement>
registerMessageElement: (id: string, element: HTMLElement | null) => void registerMessageElement: (id: string, element: HTMLElement | null) => void
} }
interface ChatProviderProps {
children: ReactNode
activeTopic: Topic
}
const ChatContext = createContext<ChatContextProps | undefined>(undefined) const ChatContext = createContext<ChatContextProps | undefined>(undefined)
export const useChatContext = () => { export const useChatContext = () => {
@ -26,11 +32,6 @@ export const useChatContext = () => {
return context return context
} }
interface ChatProviderProps {
children: ReactNode
activeTopic: Topic
}
export const ChatProvider: FC<ChatProviderProps> = ({ children, activeTopic }) => { export const ChatProvider: FC<ChatProviderProps> = ({ children, activeTopic }) => {
const { t } = useTranslation() const { t } = useTranslation()
const dispatch = useDispatch() const dispatch = useDispatch()
@ -58,6 +59,27 @@ export const ChatProvider: FC<ChatProviderProps> = ({ children, activeTopic }) =
}) })
}, []) }, [])
const locateMessage = (messageId: string) => {
const messageElement = messageRefs.get(messageId)
if (messageElement) {
// 检查消息是否可见
const display = window.getComputedStyle(messageElement).display
if (display === 'none') {
// 如果消息隐藏,需要处理显示逻辑
// 查找消息并设置为选中状态
const message = messages.find((m) => m.id === messageId)
if (message) {
// 这里需要实现设置消息为选中状态的逻辑
// 可能需要调用其他函数或修改状态
}
}
// 滚动到消息位置
messageElement.scrollIntoView({ behavior: 'smooth', block: 'start' })
}
}
const handleMultiSelectAction = (actionType: string, messageIds: string[]) => { const handleMultiSelectAction = (actionType: string, messageIds: string[]) => {
if (messageIds.length === 0) { if (messageIds.length === 0) {
window.message.warning(t('chat.multiple.select.empty')) window.message.warning(t('chat.multiple.select.empty'))
@ -150,6 +172,7 @@ export const ChatProvider: FC<ChatProviderProps> = ({ children, activeTopic }) =
toggleMultiSelectMode, toggleMultiSelectMode,
handleMultiSelectAction, handleMultiSelectAction,
activeTopic, activeTopic,
locateMessage,
messageRefs, messageRefs,
registerMessageElement registerMessageElement
} }