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:
parent
43da80cba1
commit
893a04aba3
@ -91,7 +91,7 @@ const TranslateButton: FC<Props> = ({ text, onTranslated, disabled, style, isLoa
|
|||||||
const ToolbarButton = styled(Button)`
|
const ToolbarButton = styled(Button)`
|
||||||
min-width: 30px;
|
min-width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
font-size: 17px;
|
font-size: 16px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
color: var(--color-icon);
|
color: var(--color-icon);
|
||||||
|
|||||||
@ -170,6 +170,7 @@
|
|||||||
"topics.prompt.tips": "Topic Prompts: Additional supplementary prompts provided for the current topic",
|
"topics.prompt.tips": "Topic Prompts: Additional supplementary prompts provided for the current topic",
|
||||||
"topics.title": "Topics",
|
"topics.title": "Topics",
|
||||||
"topics.unpinned": "Unpinned Topics",
|
"topics.unpinned": "Unpinned Topics",
|
||||||
|
"topics.new": "New Topic",
|
||||||
"translate": "Translate",
|
"translate": "Translate",
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"prev": "Previous Message",
|
"prev": "Previous Message",
|
||||||
|
|||||||
@ -170,6 +170,7 @@
|
|||||||
"topics.prompt.tips": "トピック提示語:現在のトピックに対して追加の補足提示語を提供",
|
"topics.prompt.tips": "トピック提示語:現在のトピックに対して追加の補足提示語を提供",
|
||||||
"topics.title": "トピック",
|
"topics.title": "トピック",
|
||||||
"topics.unpinned": "固定解除",
|
"topics.unpinned": "固定解除",
|
||||||
|
"topics.new": "新しいトピック",
|
||||||
"translate": "翻訳",
|
"translate": "翻訳",
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"prev": "前のメッセージ",
|
"prev": "前のメッセージ",
|
||||||
|
|||||||
@ -170,6 +170,7 @@
|
|||||||
"topics.prompt.tips": "Тематические подсказки: Дополнительные подсказки, предоставленные для текущей темы",
|
"topics.prompt.tips": "Тематические подсказки: Дополнительные подсказки, предоставленные для текущей темы",
|
||||||
"topics.title": "Топики",
|
"topics.title": "Топики",
|
||||||
"topics.unpinned": "Открепленные темы",
|
"topics.unpinned": "Открепленные темы",
|
||||||
|
"topics.new": "Новый топик",
|
||||||
"translate": "Перевести",
|
"translate": "Перевести",
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"prev": "Предыдущее сообщение",
|
"prev": "Предыдущее сообщение",
|
||||||
|
|||||||
@ -170,6 +170,7 @@
|
|||||||
"topics.prompt.tips": "话题提示词: 针对当前话题提供额外的补充提示词",
|
"topics.prompt.tips": "话题提示词: 针对当前话题提供额外的补充提示词",
|
||||||
"topics.title": "话题",
|
"topics.title": "话题",
|
||||||
"topics.unpinned": "取消固定",
|
"topics.unpinned": "取消固定",
|
||||||
|
"topics.new": "开始新对话",
|
||||||
"translate": "翻译",
|
"translate": "翻译",
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"prev": "上一条消息",
|
"prev": "上一条消息",
|
||||||
|
|||||||
@ -170,6 +170,7 @@
|
|||||||
"topics.prompt.tips": "話題提示詞:針對目前話題提供額外的補充提示詞",
|
"topics.prompt.tips": "話題提示詞:針對目前話題提供額外的補充提示詞",
|
||||||
"topics.title": "話題",
|
"topics.title": "話題",
|
||||||
"topics.unpinned": "取消固定",
|
"topics.unpinned": "取消固定",
|
||||||
|
"topics.new": "開始新對話",
|
||||||
"translate": "翻譯",
|
"translate": "翻譯",
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"prev": "上一條訊息",
|
"prev": "上一條訊息",
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ClearOutlined,
|
ClearOutlined,
|
||||||
ColumnHeightOutlined,
|
ColumnHeightOutlined,
|
||||||
FormOutlined,
|
|
||||||
FullscreenExitOutlined,
|
FullscreenExitOutlined,
|
||||||
FullscreenOutlined,
|
FullscreenOutlined,
|
||||||
GlobalOutlined,
|
GlobalOutlined,
|
||||||
@ -71,7 +70,6 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
pasteLongTextAsFile,
|
pasteLongTextAsFile,
|
||||||
pasteLongTextThreshold,
|
pasteLongTextThreshold,
|
||||||
showInputEstimatedTokens,
|
showInputEstimatedTokens,
|
||||||
clickAssistantToShowTopic,
|
|
||||||
autoTranslateWithSpace
|
autoTranslateWithSpace
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
const [expended, setExpend] = useState(false)
|
const [expended, setExpend] = useState(false)
|
||||||
@ -127,7 +125,6 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
|
|
||||||
const inputTokenCount = showInputEstimatedTokens ? tokenCount : 0
|
const inputTokenCount = showInputEstimatedTokens ? tokenCount : 0
|
||||||
|
|
||||||
const newTopicShortcut = useShortcutDisplay('new_topic')
|
|
||||||
const cleanTopicShortcut = useShortcutDisplay('clear_topic')
|
const cleanTopicShortcut = useShortcutDisplay('clear_topic')
|
||||||
const inputEmpty = isEmpty(text.trim()) && files.length === 0
|
const inputEmpty = isEmpty(text.trim()) && files.length === 0
|
||||||
|
|
||||||
@ -325,8 +322,8 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
addTopic(topic)
|
addTopic(topic)
|
||||||
setActiveTopic(topic)
|
setActiveTopic(topic)
|
||||||
|
|
||||||
clickAssistantToShowTopic && setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 0)
|
setTimeout(() => EventEmitter.emit(EVENT_NAMES.SHOW_TOPIC_SIDEBAR), 0)
|
||||||
}, [addTopic, assistant, clickAssistantToShowTopic, setActiveTopic, setModel])
|
}, [addTopic, assistant, setActiveTopic, setModel])
|
||||||
|
|
||||||
const onPause = async () => {
|
const onPause = async () => {
|
||||||
await pauseMessages()
|
await pauseMessages()
|
||||||
@ -710,11 +707,6 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
</DragHandle>
|
</DragHandle>
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<ToolbarMenu>
|
<ToolbarMenu>
|
||||||
<Tooltip placement="top" title={t('chat.input.new_topic', { Command: newTopicShortcut })} arrow>
|
|
||||||
<ToolbarButton type="text" onClick={addNewTopic}>
|
|
||||||
<FormOutlined />
|
|
||||||
</ToolbarButton>
|
|
||||||
</Tooltip>
|
|
||||||
<MentionModelsButton
|
<MentionModelsButton
|
||||||
mentionModels={mentionModels}
|
mentionModels={mentionModels}
|
||||||
onMentionModel={(model) => onMentionModel(model, mentionFromKeyboard)}
|
onMentionModel={(model) => onMentionModel(model, mentionFromKeyboard)}
|
||||||
@ -742,7 +734,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
ToolbarButton={ToolbarButton}
|
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>
|
<Tooltip placement="top" title={t('chat.input.clear', { Command: cleanTopicShortcut })} arrow>
|
||||||
<Popconfirm
|
<Popconfirm
|
||||||
title={t('chat.input.clear.content')}
|
title={t('chat.input.clear.content')}
|
||||||
@ -778,7 +770,7 @@ const Inputbar: FC<Props> = ({ assistant: _assistant, setActiveTopic, topic }) =
|
|||||||
/>
|
/>
|
||||||
</ToolbarMenu>
|
</ToolbarMenu>
|
||||||
<ToolbarMenu>
|
<ToolbarMenu>
|
||||||
<TranslateButton text={text} onTranslated={onTranslated} isLoading={isTranslating} />
|
<AttachmentButton model={model} files={files} setFiles={setFiles} ToolbarButton={ToolbarButton} />
|
||||||
{loading && (
|
{loading && (
|
||||||
<Tooltip placement="top" title={t('chat.input.pause')} arrow>
|
<Tooltip placement="top" title={t('chat.input.pause')} arrow>
|
||||||
<ToolbarButton type="text" onClick={onPause} style={{ marginRight: -2, marginTop: 1 }}>
|
<ToolbarButton type="text" onClick={onPause} style={{ marginRight: -2, marginTop: 1 }}>
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import styled from 'styled-components'
|
|||||||
import ChatNavigation from './ChatNavigation'
|
import ChatNavigation from './ChatNavigation'
|
||||||
import MessageGroup from './MessageGroup'
|
import MessageGroup from './MessageGroup'
|
||||||
import NarrowLayout from './NarrowLayout'
|
import NarrowLayout from './NarrowLayout'
|
||||||
|
import NewTopicButton from './NewTopicButton'
|
||||||
import Prompt from './Prompt'
|
import Prompt from './Prompt'
|
||||||
|
|
||||||
interface MessagesProps {
|
interface MessagesProps {
|
||||||
@ -45,7 +46,14 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
|
|||||||
const [displayMessages, setDisplayMessages] = useState<Message[]>([])
|
const [displayMessages, setDisplayMessages] = useState<Message[]>([])
|
||||||
const [hasMore, setHasMore] = useState(false)
|
const [hasMore, setHasMore] = useState(false)
|
||||||
const [isLoadingMore, setIsLoadingMore] = 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(() => {
|
useEffect(() => {
|
||||||
const reversedMessages = [...messages].reverse()
|
const reversedMessages = [...messages].reverse()
|
||||||
@ -99,6 +107,12 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
EventEmitter.on(EVENT_NAMES.NEW_CONTEXT, async () => {
|
EventEmitter.on(EVENT_NAMES.NEW_CONTEXT, async () => {
|
||||||
|
const messages = messagesRef.current
|
||||||
|
|
||||||
|
if (messages.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const lastMessage = last(messages)
|
const lastMessage = last(messages)
|
||||||
|
|
||||||
if (lastMessage?.type === 'clear') {
|
if (lastMessage?.type === 'clear') {
|
||||||
@ -107,8 +121,6 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messages.length === 0) return
|
|
||||||
|
|
||||||
const clearMessage = getUserMessage({ assistant, topic, type: 'clear' })
|
const clearMessage = getUserMessage({ assistant, topic, type: 'clear' })
|
||||||
const newMessages = [...messages, clearMessage]
|
const newMessages = [...messages, clearMessage]
|
||||||
await updateMessages(newMessages)
|
await updateMessages(newMessages)
|
||||||
@ -181,6 +193,7 @@ const Messages: React.FC<MessagesProps> = ({ assistant, topic, setActiveTopic })
|
|||||||
ref={containerRef}
|
ref={containerRef}
|
||||||
$right={topicPosition === 'left'}>
|
$right={topicPosition === 'left'}>
|
||||||
<NarrowLayout style={{ display: 'flex', flexDirection: 'column-reverse' }}>
|
<NarrowLayout style={{ display: 'flex', flexDirection: 'column-reverse' }}>
|
||||||
|
{messages.length >= 2 && !loading && <NewTopicButton />}
|
||||||
<InfiniteScroll
|
<InfiniteScroll
|
||||||
dataLength={displayMessages.length}
|
dataLength={displayMessages.length}
|
||||||
next={loadMoreMessages}
|
next={loadMoreMessages}
|
||||||
|
|||||||
48
src/renderer/src/pages/home/Messages/NewTopicButton.tsx
Normal file
48
src/renderer/src/pages/home/Messages/NewTopicButton.tsx
Normal 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
|
||||||
Loading…
x
Reference in New Issue
Block a user