feat: add new topic button and update translations

- Introduced a NewTopicButton component to facilitate adding new topics.
- Updated translations for new topic functionality in English, Japanese, Russian, Simplified Chinese, and Traditional Chinese.
- Adjusted font size in TranslateButton for better UI consistency.
- Removed unused new topic shortcut from Inputbar component.
This commit is contained in:
kangfenmao 2025-03-15 16:07:20 +08:00
parent 43da80cba1
commit 893a04aba3
9 changed files with 74 additions and 16 deletions

View File

@ -91,7 +91,7 @@ const TranslateButton: FC<Props> = ({ text, onTranslated, disabled, style, isLoa
const ToolbarButton = styled(Button)`
min-width: 30px;
height: 30px;
font-size: 17px;
font-size: 16px;
border-radius: 50%;
transition: all 0.3s ease;
color: var(--color-icon);

View File

@ -170,6 +170,7 @@
"topics.prompt.tips": "Topic Prompts: Additional supplementary prompts provided for the current topic",
"topics.title": "Topics",
"topics.unpinned": "Unpinned Topics",
"topics.new": "New Topic",
"translate": "Translate",
"navigation": {
"prev": "Previous Message",

View File

@ -170,6 +170,7 @@
"topics.prompt.tips": "トピック提示語:現在のトピックに対して追加の補足提示語を提供",
"topics.title": "トピック",
"topics.unpinned": "固定解除",
"topics.new": "新しいトピック",
"translate": "翻訳",
"navigation": {
"prev": "前のメッセージ",

View File

@ -170,6 +170,7 @@
"topics.prompt.tips": "Тематические подсказки: Дополнительные подсказки, предоставленные для текущей темы",
"topics.title": "Топики",
"topics.unpinned": "Открепленные темы",
"topics.new": "Новый топик",
"translate": "Перевести",
"navigation": {
"prev": "Предыдущее сообщение",

View File

@ -170,6 +170,7 @@
"topics.prompt.tips": "话题提示词: 针对当前话题提供额外的补充提示词",
"topics.title": "话题",
"topics.unpinned": "取消固定",
"topics.new": "开始新对话",
"translate": "翻译",
"navigation": {
"prev": "上一条消息",

View File

@ -170,6 +170,7 @@
"topics.prompt.tips": "話題提示詞:針對目前話題提供額外的補充提示詞",
"topics.title": "話題",
"topics.unpinned": "取消固定",
"topics.new": "開始新對話",
"translate": "翻譯",
"navigation": {
"prev": "上一條訊息",

View File

@ -1,7 +1,6 @@
import {
ClearOutlined,
ColumnHeightOutlined,
FormOutlined,
FullscreenExitOutlined,
FullscreenOutlined,
GlobalOutlined,
@ -71,7 +70,6 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
pasteLongTextAsFile,
pasteLongTextThreshold,
showInputEstimatedTokens,
clickAssistantToShowTopic,
autoTranslateWithSpace
} = useSettings()
const [expended, setExpend] = useState(false)
@ -127,7 +125,6 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
const inputTokenCount = showInputEstimatedTokens ? tokenCount : 0
const newTopicShortcut = useShortcutDisplay('new_topic')
const cleanTopicShortcut = useShortcutDisplay('clear_topic')
const inputEmpty = isEmpty(text.trim()) && files.length === 0
@ -325,8 +322,8 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
addTopic(topic)
setActiveTopic(topic)
clickAssistantToShowTopic && setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 0)
}, [addTopic, assistant, clickAssistantToShowTopic, setActiveTopic, setModel])
setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 0)
}, [addTopic, assistant, setActiveTopic, setModel])
const onPause = async () => {
await pauseMessages()
@ -710,11 +707,6 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
</DragHandle>
<Toolbar>
<ToolbarMenu>
<Tooltip placement="top" title={t('chat.input.new_topic', { Command: newTopicShortcut })} arrow>
<ToolbarButton type="text" onClick={addNewTopic}>
<FormOutlined />
</ToolbarButton>
</Tooltip>
<MentionModelsButton
mentionModels={mentionModels}
onMentionModel={(model) => onMentionModel(model, mentionFromKeyboard)}
@ -742,7 +734,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
ToolbarButton={ToolbarButton}
/>
)}
<AttachmentButton model={model} files={files} setFiles={setFiles} ToolbarButton={ToolbarButton} />
<TranslateButton text={text} onTranslated={onTranslated} isLoading={isTranslating} />
<Tooltip placement="top" title={t('chat.input.clear', { Command: cleanTopicShortcut })} arrow>
<Popconfirm
title={t('chat.input.clear.content')}
@ -778,7 +770,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
/>
</ToolbarMenu>
<ToolbarMenu>
<TranslateButton text={text} onTranslated={onTranslated} isLoading={isTranslating} />
<AttachmentButton model={model} files={files} setFiles={setFiles} ToolbarButton={ToolbarButton} />
{loading && (
<Tooltip placement="top" title={t('chat.input.pause')} arrow>
<ToolbarButton type="text" onClick={onPause} style={{ marginRight: -2, marginTop: 1 }}>

View File

@ -28,6 +28,7 @@ import styled from 'styled-components'
import ChatNavigation from './ChatNavigation'
import MessageGroup from './MessageGroup'
import NarrowLayout from './NarrowLayout'
import NewTopicButton from './NewTopicButton'
import Prompt from './Prompt'
interface MessagesProps {
@ -45,7 +46,14 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
const [displayMessages, setDisplayMessages] = useState<Message[]>([])
const [hasMore, setHasMore] = useState(false)
const [isLoadingMore, setIsLoadingMore] = useState(false)
const { messages, displayCount, updateMessages, clearTopicMessages, deleteMessage } = useMessageOperations(topic)
const { messages, displayCount, loading, updateMessages, clearTopicMessages, deleteMessage } =
useMessageOperations(topic)
const messagesRef = useRef<Message[]>(messages)
useEffect(() => {
messagesRef.current = messages
}, [messages])
useEffect(() => {
const reversedMessages = [...messages].reverse()
@ -99,6 +107,12 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
}
}),
EventEmitter.on(EVENT_NAMES.NEW_CONTEXT, async () => {
const messages = messagesRef.current
if (messages.length === 0) {
return
}
const lastMessage = last(messages)
if (lastMessage?.type === 'clear') {
@ -107,8 +121,6 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
return
}
if (messages.length === 0) return
const clearMessage = getUserMessage({ assistant, topic, type: 'clear' })
const newMessages = [...messages, clearMessage]
await updateMessages(newMessages)
@ -181,6 +193,7 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
ref={containerRef}
$right={topicPosition === 'left'}>
<NarrowLayout style={{ display: 'flex', flexDirection: 'column-reverse' }}>
{messages.length >= 2 && !loading && <NewTopicButton />}
<InfiniteScroll
dataLength={displayMessages.length}
next={loadMoreMessages}

View File

@ -0,0 +1,48 @@
import { FormOutlined } from '@ant-design/icons'
import { EventEmitter } from '@renderer/services/EventService'
import { EVENT_NAMES } from '@renderer/services/EventService'
import { Button as AntdButton } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
const NewTopicButton: FC = () => {
const { t } = useTranslation()
const addNewTopic = () => {
EventEmitter.emit(EVENT_NAMES.ADD_NEW_TOPIC)
}
return (
<Container>
<Button size="small" color="primary" icon={<FormOutlined />} onClick={addNewTopic}>
{t('chat.topics.new')}
</Button>
</Container>
)
}
const Container = styled.div`
display: flex;
justify-content: center;
align-items: center;
`
const Button = styled(AntdButton)`
border-radius: 20px;
padding: 0 12px;
height: 34px !important;
font-size: 12px;
opacity: 0.8;
transition: all 0.3s ease;
background-color: var(--color-background-soft);
color: var(--color-text-2);
&:hover {
opacity: 0.9;
background-color: var(--color-background-mute) !important;
color: var(--color-text-1) !important;
border-color: var(--color-border-mute) !important;
}
`
export default NewTopicButton