mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-06 21:35:52 +08:00
feat: add event listeners and topic handling improvements #181
- Added event listeners for estimated token count and add new topic events. - Updated default topic handling when clearing messages. - Removed feature to add new topics directly in Navbar and replaced it with emitting an event to create a new topic. - Added the functionality to add new topics, clear messages, and handle topic switching with improved conditional logic. - The event constants configuration has been updated to include two new event names.
This commit is contained in:
parent
f2fe5ad4f5
commit
0026293e69
@ -248,10 +248,13 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
|
|||||||
EventEmitter.on(EVENT_NAMES.ESTIMATED_TOKEN_COUNT, ({ tokensCount, contextCount }) => {
|
EventEmitter.on(EVENT_NAMES.ESTIMATED_TOKEN_COUNT, ({ tokensCount, contextCount }) => {
|
||||||
_setEstimateTokenCount(tokensCount)
|
_setEstimateTokenCount(tokensCount)
|
||||||
setContextCount(contextCount)
|
setContextCount(contextCount)
|
||||||
|
}),
|
||||||
|
EventEmitter.on(EVENT_NAMES.ADD_NEW_TOPIC, () => {
|
||||||
|
addNewTopic()
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
return () => unsubscribes.forEach((unsub) => unsub())
|
return () => unsubscribes.forEach((unsub) => unsub())
|
||||||
}, [])
|
}, [addNewTopic])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
textareaRef.current?.focus()
|
textareaRef.current?.focus()
|
||||||
|
|||||||
@ -131,7 +131,8 @@ const Messages: FC<Props> = ({ assistant, topic, setActiveTopic }) => {
|
|||||||
EventEmitter.on(EVENT_NAMES.AI_AUTO_RENAME, autoRenameTopic),
|
EventEmitter.on(EVENT_NAMES.AI_AUTO_RENAME, autoRenameTopic),
|
||||||
EventEmitter.on(EVENT_NAMES.CLEAR_MESSAGES, () => {
|
EventEmitter.on(EVENT_NAMES.CLEAR_MESSAGES, () => {
|
||||||
setMessages([])
|
setMessages([])
|
||||||
updateTopic({ ...topic, messages: [] })
|
const defaultTopic = getDefaultTopic(assistant.id)
|
||||||
|
updateTopic({ ...topic, name: defaultTopic.name, messages: [] })
|
||||||
TopicManager.clearTopicMessages(topic.id)
|
TopicManager.clearTopicMessages(topic.id)
|
||||||
}),
|
}),
|
||||||
EventEmitter.on(EVENT_NAMES.EXPORT_TOPIC_IMAGE, async () => {
|
EventEmitter.on(EVENT_NAMES.EXPORT_TOPIC_IMAGE, async () => {
|
||||||
|
|||||||
@ -4,11 +4,9 @@ import AssistantSettingPopup from '@renderer/components/AssistantSettings'
|
|||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import { isMac, isWindows } from '@renderer/config/constant'
|
import { isMac, isWindows } from '@renderer/config/constant'
|
||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||||
import db from '@renderer/databases'
|
|
||||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore'
|
import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore'
|
||||||
import { getDefaultTopic } from '@renderer/services/assistant'
|
|
||||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
|
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
|
||||||
import { Assistant, Topic } from '@renderer/types'
|
import { Assistant, Topic } from '@renderer/types'
|
||||||
import { Switch } from 'antd'
|
import { Switch } from 'antd'
|
||||||
@ -24,8 +22,8 @@ interface Props {
|
|||||||
setActiveTopic: (topic: Topic) => void
|
setActiveTopic: (topic: Topic) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveTopic }) => {
|
const HeaderNavbar: FC<Props> = ({ activeAssistant }) => {
|
||||||
const { assistant, addTopic } = useAssistant(activeAssistant.id)
|
const { assistant } = useAssistant(activeAssistant.id)
|
||||||
const { showAssistants, toggleShowAssistants } = useShowAssistants()
|
const { showAssistants, toggleShowAssistants } = useShowAssistants()
|
||||||
const { theme, toggleTheme } = useTheme()
|
const { theme, toggleTheme } = useTheme()
|
||||||
const { topicPosition } = useSettings()
|
const { topicPosition } = useSettings()
|
||||||
@ -33,13 +31,10 @@ const HeaderNavbar: FC<Props> = ({ activeAssistant, setActiveTopic }) => {
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const addNewTopic = useCallback(() => {
|
const addNewTopic = useCallback(() => {
|
||||||
const topic = getDefaultTopic(assistant.id)
|
EventEmitter.emit(EVENT_NAMES.ADD_NEW_TOPIC)
|
||||||
addTopic(topic)
|
|
||||||
setActiveTopic(topic)
|
|
||||||
db.topics.add({ id: topic.id, messages: [] })
|
|
||||||
window.message.success({ content: t('message.topic.added'), key: 'topic-added' })
|
window.message.success({ content: t('message.topic.added'), key: 'topic-added' })
|
||||||
setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 0)
|
setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 0)
|
||||||
}, [addTopic, assistant.id, setActiveTopic, t])
|
}, [t])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Navbar>
|
<Navbar>
|
||||||
|
|||||||
@ -29,7 +29,7 @@ interface Props {
|
|||||||
|
|
||||||
const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic }) => {
|
const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic }) => {
|
||||||
const { assistants } = useAssistants()
|
const { assistants } = useAssistants()
|
||||||
const { assistant, removeTopic, moveTopic, updateTopic, updateTopics } = useAssistant(_assistant.id)
|
const { assistant, removeTopic, moveTopic, updateTopic, updateTopics, addTopic } = useAssistant(_assistant.id)
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const generating = useAppSelector((state) => state.runtime.generating)
|
const generating = useAppSelector((state) => state.runtime.generating)
|
||||||
|
|
||||||
@ -39,11 +39,9 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
window.message.warning({ content: t('message.switch.disabled'), key: 'generating' })
|
window.message.warning({ content: t('message.switch.disabled'), key: 'generating' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (assistant.topics.length > 1) {
|
const index = findIndex(assistant.topics, (t) => t.id === topic.id)
|
||||||
const index = findIndex(assistant.topics, (t) => t.id === topic.id)
|
setActiveTopic(assistant.topics[index + 1 === assistant.topics.length ? 0 : index + 1])
|
||||||
setActiveTopic(assistant.topics[index + 1 === assistant.topics.length ? 0 : index + 1])
|
removeTopic(topic)
|
||||||
removeTopic(topic)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[assistant.topics, generating, removeTopic, setActiveTopic, t]
|
[assistant.topics, generating, removeTopic, setActiveTopic, t]
|
||||||
)
|
)
|
||||||
@ -72,6 +70,12 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
[generating, setActiveTopic, t]
|
[generating, setActiveTopic, t]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const onClearMessages = useCallback(() => {
|
||||||
|
window.keyv.set(EVENT_NAMES.CHAT_COMPLETION_PAUSED, true)
|
||||||
|
store.dispatch(setGenerating(false))
|
||||||
|
EventEmitter.emit(EVENT_NAMES.CLEAR_MESSAGES)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const getTopicMenuItems = useCallback(
|
const getTopicMenuItems = useCallback(
|
||||||
(topic: Topic) => {
|
(topic: Topic) => {
|
||||||
const menus: MenuProps['items'] = [
|
const menus: MenuProps['items'] = [
|
||||||
@ -112,11 +116,7 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
window.modal.confirm({
|
window.modal.confirm({
|
||||||
title: t('chat.input.clear.content'),
|
title: t('chat.input.clear.content'),
|
||||||
centered: true,
|
centered: true,
|
||||||
onOk: async () => {
|
onOk: onClearMessages
|
||||||
window.keyv.set(EVENT_NAMES.CHAT_COMPLETION_PAUSED, true)
|
|
||||||
store.dispatch(setGenerating(false))
|
|
||||||
EventEmitter.emit(EVENT_NAMES.CLEAR_MESSAGES)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -162,7 +162,7 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
|
|
||||||
return menus
|
return menus
|
||||||
},
|
},
|
||||||
[assistant, assistants, onDeleteTopic, onMoveTopic, t, updateTopic]
|
[assistant, assistants, onClearMessages, onDeleteTopic, onMoveTopic, t, updateTopic]
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -174,11 +174,14 @@ const Topics: FC<Props> = ({ assistant: _assistant, activeTopic, setActiveTopic
|
|||||||
<Dropdown menu={{ items: getTopicMenuItems(topic) }} trigger={['contextMenu']} key={topic.id}>
|
<Dropdown menu={{ items: getTopicMenuItems(topic) }} trigger={['contextMenu']} key={topic.id}>
|
||||||
<TopicListItem className={isActive ? 'active' : ''} onClick={() => onSwitchTopic(topic)}>
|
<TopicListItem className={isActive ? 'active' : ''} onClick={() => onSwitchTopic(topic)}>
|
||||||
<TopicName className="name">{topic.name.replace('`', '')}</TopicName>
|
<TopicName className="name">{topic.name.replace('`', '')}</TopicName>
|
||||||
{assistant.topics.length > 1 && isActive && (
|
{isActive && (
|
||||||
<MenuButton
|
<MenuButton
|
||||||
className="menu"
|
className="menu"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
if (assistant.topics.length === 1) {
|
||||||
|
return onClearMessages()
|
||||||
|
}
|
||||||
onDeleteTopic(topic)
|
onDeleteTopic(topic)
|
||||||
}}>
|
}}>
|
||||||
<CloseOutlined />
|
<CloseOutlined />
|
||||||
|
|||||||
@ -19,5 +19,6 @@ export const EVENT_NAMES = {
|
|||||||
NEW_CONTEXT: 'NEW_CONTEXT',
|
NEW_CONTEXT: 'NEW_CONTEXT',
|
||||||
NEW_BRANCH: 'NEW_BRANCH',
|
NEW_BRANCH: 'NEW_BRANCH',
|
||||||
EXPORT_TOPIC_IMAGE: 'EXPORT_TOPIC_IMAGE',
|
EXPORT_TOPIC_IMAGE: 'EXPORT_TOPIC_IMAGE',
|
||||||
LOCATE_MESSAGE: 'LOCATE_MESSAGE'
|
LOCATE_MESSAGE: 'LOCATE_MESSAGE',
|
||||||
|
ADD_NEW_TOPIC: 'ADD_NEW_TOPIC'
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user