refactor(Inputbar, Messages): simplify clear topic functionality and improve message display logic

- Removed unused QuestionCircleOutlined icon and Popconfirm from Inputbar, replacing it with a direct button click for clearing topics.
- Refactored message display logic in Messages component to enhance clarity and maintainability, while preserving existing functionality.
This commit is contained in:
kangfenmao 2025-04-12 16:07:40 +08:00
parent d4bf8da225
commit 0e7c4e4bdd
2 changed files with 66 additions and 69 deletions

View File

@ -9,7 +9,6 @@ import {
HolderOutlined,
PaperClipOutlined,
PauseCircleOutlined,
QuestionCircleOutlined,
ThunderboltOutlined,
TranslationOutlined
} from '@ant-design/icons'
@ -40,7 +39,7 @@ import { Assistant, FileType, KnowledgeBase, KnowledgeItem, MCPServer, Message,
import { classNames, delay, formatFileSize, getFileExtension } from '@renderer/utils'
import { getFilesFromDropEvent } from '@renderer/utils/input'
import { documentExts, imageExts, textExts } from '@shared/config/constant'
import { Button, Popconfirm, Tooltip } from 'antd'
import { Button, Tooltip } from 'antd'
import TextArea, { TextAreaRef } from 'antd/es/input/TextArea'
import dayjs from 'dayjs'
import Logger from 'electron-log/renderer'
@ -695,9 +694,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
textareaRef.current?.focus()
})
useShortcut('clear_topic', () => {
clearTopic()
})
useShortcut('clear_topic', clearTopic)
useEffect(() => {
const _setEstimateTokenCount = debounce(setEstimateTokenCount, 100, { leading: false, trailing: true })
@ -991,17 +988,9 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
ToolbarButton={ToolbarButton}
/>
<Tooltip placement="top" title={t('chat.input.clear', { Command: cleanTopicShortcut })} arrow>
<Popconfirm
title={t('chat.input.clear.content')}
placement="top"
onConfirm={clearTopic}
okButtonProps={{ danger: true }}
icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
okText={t('chat.input.clear.title')}>
<ToolbarButton type="text">
<ToolbarButton type="text" onClick={clearTopic}>
<ClearOutlined style={{ fontSize: 17 }} />
</ToolbarButton>
</Popconfirm>
</Tooltip>
<Tooltip placement="top" title={isExpended ? t('chat.input.collapse') : t('chat.input.expand')} arrow>
<ToolbarButton type="text" onClick={onToggleExpended}>

View File

@ -38,42 +38,6 @@ interface MessagesProps {
setActiveTopic: (topic: Topic) => void
}
const computeDisplayMessages = (messages: Message[], startIndex: number, displayCount: number) => {
const reversedMessages = [...messages].reverse()
// 如果剩余消息数量小于 displayCount直接返回所有剩余消息
if (reversedMessages.length - startIndex <= displayCount) {
return reversedMessages.slice(startIndex)
}
const userIdSet = new Set() // 用户消息 id 集合
const assistantIdSet = new Set() // 助手消息 askId 集合
const displayMessages: Message[] = []
// 处理单条消息的函数
const processMessage = (message: Message) => {
if (!message) return
const idSet = message.role === 'user' ? userIdSet : assistantIdSet
const messageId = message.role === 'user' ? message.id : message.askId
if (!idSet.has(messageId)) {
idSet.add(messageId)
displayMessages.push(message)
return
}
// 如果是相同 askId 的助手消息,也要显示
displayMessages.push(message)
}
// 遍历消息直到满足显示数量要求
for (let i = startIndex; i < reversedMessages.length && userIdSet.size + assistantIdSet.size < displayCount; i++) {
processMessage(reversedMessages[i])
}
return displayMessages
}
const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic }) => {
const { t } = useTranslation()
const { showTopics, topicPosition, showAssistants, messageNavigation } = useSettings()
@ -118,10 +82,8 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
}
}, [])
useEffect(() => {
const unsubscribes = [
EventEmitter.on(EVENT_NAMES.SEND_MESSAGE, scrollToBottom),
EventEmitter.on(EVENT_NAMES.CLEAR_MESSAGES, async (data: Topic) => {
const clearTopic = useCallback(
async (data: Topic) => {
const defaultTopic = getDefaultTopic(assistant.id)
if (data && data.id !== topic.id) {
@ -131,11 +93,25 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
}
await clearTopicMessages()
setDisplayMessages([])
const _topic = getTopic(assistant, topic.id)
if (_topic) {
updateTopic({ ..._topic, name: defaultTopic.name } as Topic)
}
_topic && updateTopic({ ..._topic, name: defaultTopic.name } as Topic)
},
[assistant, clearTopicMessages, topic.id, updateTopic]
)
useEffect(() => {
const unsubscribes = [
EventEmitter.on(EVENT_NAMES.SEND_MESSAGE, scrollToBottom),
EventEmitter.on(EVENT_NAMES.CLEAR_MESSAGES, async (data: Topic) => {
window.modal.confirm({
title: t('chat.input.clear.title'),
content: t('chat.input.clear.content'),
centered: true,
onOk: () => clearTopic(data)
})
}),
EventEmitter.on(EVENT_NAMES.COPY_TOPIC_IMAGE, async () => {
await captureScrollableDivAsBlob(containerRef, async (blob) => {
@ -280,11 +256,43 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
)
}
interface LoaderProps {
$loading: boolean
const computeDisplayMessages = (messages: Message[], startIndex: number, displayCount: number) => {
const reversedMessages = [...messages].reverse()
// 如果剩余消息数量小于 displayCount直接返回所有剩余消息
if (reversedMessages.length - startIndex <= displayCount) {
return reversedMessages.slice(startIndex)
}
const LoaderContainer = styled.div<LoaderProps>`
const userIdSet = new Set() // 用户消息 id 集合
const assistantIdSet = new Set() // 助手消息 askId 集合
const displayMessages: Message[] = []
// 处理单条消息的函数
const processMessage = (message: Message) => {
if (!message) return
const idSet = message.role === 'user' ? userIdSet : assistantIdSet
const messageId = message.role === 'user' ? message.id : message.askId
if (!idSet.has(messageId)) {
idSet.add(messageId)
displayMessages.push(message)
return
}
// 如果是相同 askId 的助手消息,也要显示
displayMessages.push(message)
}
// 遍历消息直到满足显示数量要求
for (let i = startIndex; i < reversedMessages.length && userIdSet.size + assistantIdSet.size < displayCount; i++) {
processMessage(reversedMessages[i])
}
return displayMessages
}
const LoaderContainer = styled.div<{ $loading: boolean }>`
display: flex;
justify-content: center;
padding: 10px;