From da4ae724c10f33924297ffd0c80ce8396213b574 Mon Sep 17 00:00:00 2001 From: canisminor1990 Date: Thu, 27 Jul 2023 00:56:39 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20Add=20new=20translations,?= =?UTF-8?q?=20update=20existing=20translations,=20add=20functionality=20to?= =?UTF-8?q?=20components,=20modify=20styling,=20and=20adjust=20placeholder?= =?UTF-8?q?=20text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit introduces new translations, updates existing translations, adds functionality to components, modifies styling, and adjusts placeholder text. These changes aim to improve the user experience and enhance the overall functionality of the software project. --- locales/en_US/common.json | 26 +++++ locales/en_US/setting.json | 18 +++- locales/zh_CN/common.json | 30 +++++- locales/zh_CN/setting.json | 17 ++- src/locales/default/common.ts | 9 ++ .../chat/SessionList/List/SessionItem.tsx | 88 +++++++++++---- src/pages/chat/SessionList/List/style.ts | 26 ++--- src/pages/chat/[id]/Config/SideBar.tsx | 6 +- src/pages/chat/[id]/Config/TopicItem.tsx | 100 ++++++++++++++---- src/pages/chat/[id]/Conversation/ChatList.tsx | 11 ++ .../chat/[id]/Conversation/Input/Token.tsx | 6 +- .../chat/[id]/edit/AgentPrompt/index.tsx | 2 +- 12 files changed, 268 insertions(+), 71 deletions(-) diff --git a/locales/en_US/common.json b/locales/en_US/common.json index 1ae4ca0627..816ce30c84 100644 --- a/locales/en_US/common.json +++ b/locales/en_US/common.json @@ -1,5 +1,6 @@ { "DefaultSession": "Default Session", + "about": "About", "advanceSettings": "Advanced Settings", "agentMaxToken": "Max Token Length", "agentModel": "Model", @@ -9,25 +10,50 @@ "autoGenerate": "Auto Generate", "autoGenerateTooltip": "Auto generate assistant description based on prompts", "cancel": "Cancel", + "changelog": "Changelog", "clearCurrentMessages": "Clear Current Session Messages", "close": "Close", "confirmClearCurrentMessages": "You are about to clear the current session messages. Once cleared, they cannot be recovered. Please confirm your action.", "confirmRemoveSessionItemAlert": "You are about to delete this assistant. Once deleted, it cannot be recovered. Please confirm your action.", + "copy": "Copy", + "copySuccess": "Copy Success", "defaultAgent": "Default Assistant", "defaultSession": "Default Session", + "delete": "Delete", "edit": "Edit", "export": "Export", + "exportType": { + "agent": "Export Agent Settings", + "agentWithMessage": "Export Agent Settings and Messages", + "all": "Export Global Settings and All Agent Data", + "allAgent": "Export All Agent Settings", + "allAgentWithMessage": "Export All Agent Settings and Messages", + "globalSetting": "Export Global Settings" + }, + "feedback": "Feedback", + "import": "Import Configuration", "newAgent": "New Assistant", "noDescription": "No description available", "ok": "OK", + "overload": "Exceed Limit", + "pin": "Pin", + "pinOff": "Unpin", + "regenerate": "Regenerate", + "rename": "Rename", "reset": "Reset", + "roleAndArchive": "Roles and Archives", "searchAgentPlaceholder": "Search assistants and sessions...", "send": "Send", "sendPlaceholder": "Enter chat content...", "sessionSetting": "Session Settings", "setting": "Settings", "share": "Share", + "temp": "Temporary", "tokenDetail": "System Role Token: {{systemRoleToken}} Chats Token: {{chatsToken}}", + "topic": { + "saveCurrentMessages": "Save Current Conversation as Topic", + "searchPlaceholder": "Search Topics..." + }, "updateAgent": "Update Assistant Profile", "updatePrompt": "Update Prompts" } diff --git a/locales/en_US/setting.json b/locales/en_US/setting.json index 00cb728c92..08c6cc5f36 100644 --- a/locales/en_US/setting.json +++ b/locales/en_US/setting.json @@ -15,7 +15,11 @@ "title": "Reset All Settings" } }, - "header": "Settings", + "header": { + "global": "Global Settings", + "session": "Session Settings", + "sessionWithName": "Session Settings · {{name}}" + }, "settingAgent": { "avatar": { "title": "Avatar" @@ -61,7 +65,14 @@ "title": "User Input Preprocessing", "placeholder": "Enter pre-processing template, {text} will be replaced with real-time input information" }, - "title": "Chat Settings" + "title": "Chat Settings", + "chatStyleType": { + "title": "Chat Window Style", + "type": { + "chat": "Chat Mode", + "docs": "Document Mode" + } + } }, "settingModel": { "enableMaxTokens": { @@ -91,7 +102,8 @@ }, "temperature": { "desc": "The higher the value, the more random the reply", - "title": "Randomness" + "title": "Randomness", + "titleWithValue": "Randomness {{value}}" }, "title": "Model Settings", "topP": { diff --git a/locales/zh_CN/common.json b/locales/zh_CN/common.json index 10b18aabc3..14a1324f0b 100644 --- a/locales/zh_CN/common.json +++ b/locales/zh_CN/common.json @@ -1,32 +1,56 @@ { + "about": "关于", "advanceSettings": "高级设置", "agentMaxToken": "会话最大长度", "agentModel": "模型", "agentProfile": "助手信息", "archive": "归档", - "archiveCurrentMessages": "归档当前会话", "autoGenerate": "自动补全", "autoGenerateTooltip": "基于提示词自动补全助手描述", "cancel": "取消", + "changelog": "更新日志", "clearCurrentMessages": "清空当前会话消息", "close": "关闭", "confirmClearCurrentMessages": "即将清空当前会话消息,清空后将无法找回,请确认你的操作", "confirmRemoveSessionItemAlert": "即将删除该助手,删除后该将无法找回,请确认你的操作", + "copy": "复制", + "copySuccess": "复制成功", "defaultAgent": "默认助手", "defaultSession": "默认对话", + "delete": "删除", "edit": "编辑", - "export": "导出", + "export": "导出配置", + "exportType": { + "agent": "导出助手设定", + "agentWithMessage": "导出助手和消息", + "all": "导出全局设置和所有助手数据", + "allAgent": "导出所有助手设定", + "allAgentWithMessage": "导出所有助手和消息", + "globalSetting": "导出全局设置" + }, + "feedback": "反馈与建议", + "import": "导入配置", "newAgent": "新建助手", "noDescription": "暂无描述", "ok": "确定", + "overload": "超过限制", + "pin": "置顶", + "pinOff": "取消置顶", + "regenerate": "重新生成", + "rename": "重命名", "reset": "重置", + "roleAndArchive": "角色与记录", "searchAgentPlaceholder": "搜索助手和对话...", "send": "发送", "sendPlaceholder": "输入聊天内容...", - "sessionSetting": "会话设置", "setting": "设置", "share": "分享", + "temp": "临时", "tokenDetail": "系统设定: {{systemRoleToken}} 历史消息: {{chatsToken}}", + "topic": { + "saveCurrentMessages": "将当前会话保存为话题", + "searchPlaceholder": "搜索话题..." + }, "updateAgent": "更新助理信息", "updatePrompt": "更新提示词" } diff --git a/locales/zh_CN/setting.json b/locales/zh_CN/setting.json index 4172e424ca..7615a78802 100644 --- a/locales/zh_CN/setting.json +++ b/locales/zh_CN/setting.json @@ -1,5 +1,4 @@ { - "agentHeader": "编辑助手信息", "danger": { "clear": { "action": "立即清除", @@ -15,7 +14,11 @@ "title": "重置所有设置" } }, - "header": "设置", + "header": { + "global": "全局设置", + "session": "会话设置", + "sessionWithName": "会话设置 · {{name}}" + }, "settingAgent": { "avatar": { "title": "头像" @@ -42,6 +45,13 @@ "title": "助手信息" }, "settingChat": { + "chatStyleType": { + "title": "聊天窗口样式", + "type": { + "chat": "对话模式", + "docs": "文档模式" + } + }, "compressThreshold": { "desc": "当未压缩的历史消息超过该值时,将进行压缩", "title": "历史消息长度压缩阈值" @@ -91,7 +101,8 @@ }, "temperature": { "desc": "值越大,回复越随机", - "title": "随机性" + "title": "随机性", + "titleWithValue": "随机性 {{value}}" }, "title": "模型设置", "topP": { diff --git a/src/locales/default/common.ts b/src/locales/default/common.ts index 60bff58fb9..e91aadb148 100644 --- a/src/locales/default/common.ts +++ b/src/locales/default/common.ts @@ -13,8 +13,11 @@ export default { close: '关闭', confirmClearCurrentMessages: '即将清空当前会话消息,清空后将无法找回,请确认你的操作', confirmRemoveSessionItemAlert: '即将删除该助手,删除后该将无法找回,请确认你的操作', + copy: '复制', + copySuccess: '复制成功', defaultAgent: '默认助手', defaultSession: '默认对话', + delete: '删除', edit: '编辑', export: '导出配置', exportType: { @@ -30,6 +33,11 @@ export default { newAgent: '新建助手', noDescription: '暂无描述', ok: '确定', + overload: '超过限制', + pin: '置顶', + pinOff: '取消置顶', + regenerate: '重新生成', + rename: '重命名', reset: '重置', roleAndArchive: '角色与记录', searchAgentPlaceholder: '搜索助手和对话...', @@ -37,6 +45,7 @@ export default { sendPlaceholder: '输入聊天内容...', setting: '设置', share: '分享', + temp: '临时', tokenDetail: '系统设定: {{systemRoleToken}} 历史消息: {{chatsToken}}', topic: { saveCurrentMessages: '将当前会话保存为话题', diff --git a/src/pages/chat/SessionList/List/SessionItem.tsx b/src/pages/chat/SessionList/List/SessionItem.tsx index fc39d721a1..9ff00358e6 100644 --- a/src/pages/chat/SessionList/List/SessionItem.tsx +++ b/src/pages/chat/SessionList/List/SessionItem.tsx @@ -1,8 +1,8 @@ -import { ActionIcon, Avatar, List } from '@lobehub/ui'; +import { ActionIcon, Avatar, Icon, List } from '@lobehub/ui'; import { useHover } from 'ahooks'; -import { Popconfirm, Tag } from 'antd'; -import { X } from 'lucide-react'; -import { FC, memo, useRef } from 'react'; +import { Dropdown, type MenuProps, Popconfirm, Tag } from 'antd'; +import { FolderOutput, MoreVertical, Pin, PinOff, Trash } from 'lucide-react'; +import { FC, memo, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Flexbox } from 'react-layout-kit'; import { shallow } from 'zustand/shallow'; @@ -15,16 +15,20 @@ import { useStyles } from './style'; const { Item } = List; interface SessionItemProps { - active: boolean; + active?: boolean; id: string; - loading: boolean; + loading?: boolean; + pin?: boolean; } -const SessionItem: FC = memo(({ id, active = true, loading }) => { +const SessionItem: FC = memo(({ id, active = true, loading, pin }) => { const ref = useRef(null); const isHovering = useHover(ref); + const [popOpen, setPopOpen] = useState(false); + const [dropdownOpen, setDropdownOpen] = useState(false); const { t } = useTranslation('common'); - const { styles, theme, cx } = useStyles(); + const isHighlight = isHovering || dropdownOpen; + const { styles, theme, cx } = useStyles(isHighlight); const [defaultModel] = useSettings((s) => [s.settings.model], shallow); const [ @@ -54,12 +58,45 @@ const SessionItem: FC = memo(({ id, active = true, loading }) ]; }, shallow); + // TODO: 动作绑定 + const items: MenuProps['items'] = useMemo( + () => [ + { + icon: , + key: 'pin', + label: t(pin ? 'pinOff' : 'pin'), + }, + { + children: [ + { + key: 'agent', + label:
{t('exportType.agent')}
, + }, + { + key: 'agentWithMessage', + label:
{t('exportType.agentWithMessage')}
, + }, + ], + icon: , + key: 'export', + label: t('export'), + }, + { + icon: , + key: 'delete', + label: t('delete'), + onClick: () => setPopOpen(true), + }, + ], + [id], + ); + const showModel = model !== defaultModel; const showChatLength = chatLength > 0; return (
- + = memo(({ id, active = true, loading }) title={title} /> } + className={isHighlight ? styles.hover : undefined} classNames={{ time: cx('session-time', styles.time) }} date={updateAt} description={ @@ -107,22 +145,36 @@ const SessionItem: FC = memo(({ id, active = true, loading }) cancelText={t('cancel')} okButtonProps={{ danger: true }} okText={t('ok')} + onCancel={() => setPopOpen(false)} onConfirm={(e) => { e?.stopPropagation(); removeSession(id); + setPopOpen(false); }} + open={popOpen} overlayStyle={{ width: 280 }} title={t('confirmRemoveSessionItemAlert')} > - { - e.preventDefault(); - e.stopPropagation(); - }} - size={'small'} - /> + + { + e.preventDefault(); + e.stopPropagation(); + }} + size={{ + blockSize: 28, + fontSize: 16, + }} + /> +
diff --git a/src/pages/chat/SessionList/List/style.ts b/src/pages/chat/SessionList/List/style.ts index 15214a8d9d..1967070a6f 100644 --- a/src/pages/chat/SessionList/List/style.ts +++ b/src/pages/chat/SessionList/List/style.ts @@ -1,7 +1,7 @@ import { createStyles } from 'antd-style'; import { rgba } from 'polished'; -export const useStyles = createStyles(({ css, token }) => { +export const useStyles = createStyles(({ css, token }, isHighlight: boolean) => { return { active: css` display: flex; @@ -22,7 +22,6 @@ export const useStyles = createStyles(({ css, token }) => { background: ${rgba(token.colorBgLayout, 0.5)}; backdrop-filter: blur(8px); `, - container: css` position: relative; @@ -32,24 +31,11 @@ export const useStyles = createStyles(({ css, token }) => { right: 16px; transform: translateY(-50%); - width: 16px; - height: 16px; - - font-size: 10px; - - opacity: 0; - background-color: ${token.colorFillTertiary}; - - transition: color 600ms ${token.motionEaseOut}, scale 400ms ${token.motionEaseOut}, - background-color 100ms ${token.motionEaseOut}, opacity 100ms ${token.motionEaseOut}; - - &:hover { - background-color: ${token.colorFill}; - } + opacity: ${isHighlight ? 1 : 0}; } .session-time { - opacity: 1; + opacity: ${isHighlight ? 0 : 1}; transition: opacity 100ms ${token.motionEaseOut}; } @@ -63,6 +49,12 @@ export const useStyles = createStyles(({ css, token }) => { } } `, + hover: css` + background-color: ${token.colorFillSecondary}; + `, + pin: css` + background-color: ${token.colorFillTertiary}; + `, time: css` align-self: flex-start; `, diff --git a/src/pages/chat/[id]/Config/SideBar.tsx b/src/pages/chat/[id]/Config/SideBar.tsx index c2cb1a9939..0f5471917b 100644 --- a/src/pages/chat/[id]/Config/SideBar.tsx +++ b/src/pages/chat/[id]/Config/SideBar.tsx @@ -28,7 +28,7 @@ const useStyles = createStyles(({ css, token }) => ({ opacity: 0.75; border-bottom: 1px solid ${token.colorBorder}; - transition: 200ms ${token.motionEaseOut}; + transition: opacity 200ms ${token.motionEaseOut}; &:hover { opacity: 1; @@ -79,8 +79,8 @@ const SideBar = memo(() => { }} value={systemRole} /> - - + + diff --git a/src/pages/chat/[id]/Config/TopicItem.tsx b/src/pages/chat/[id]/Config/TopicItem.tsx index 85f6022478..791c40a4b7 100644 --- a/src/pages/chat/[id]/Config/TopicItem.tsx +++ b/src/pages/chat/[id]/Config/TopicItem.tsx @@ -1,16 +1,20 @@ -import { StarFilled, StarOutlined } from '@ant-design/icons'; -import { ActionIcon } from '@lobehub/ui'; +import { ActionIcon, Icon } from '@lobehub/ui'; +import { Dropdown, type MenuProps, Tag, Typography } from 'antd'; import { createStyles } from 'antd-style'; -import { LucideIcon } from 'lucide-react'; -import { memo } from 'react'; +import { MessageSquareDashed, MoreVertical, PencilLine, Share2, Star, Trash } from 'lucide-react'; +import { memo, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { Flexbox } from 'react-layout-kit'; import { shallow } from 'zustand/shallow'; import { useSessionStore } from '@/store/session'; -const useStyles = createStyles(({ css, token }) => ({ +const { Paragraph } = Typography; + +const useStyles = createStyles(({ css, token, isDarkMode }) => ({ active: css` - background: ${token.colorFill}; + background: ${isDarkMode ? token.colorFillTertiary : token.colorFillSecondary}; + transition: background 200ms ${token.motionEaseOut}; &:hover { background: ${token.colorFill}; @@ -18,11 +22,20 @@ const useStyles = createStyles(({ css, token }) => ({ `, container: css` cursor: pointer; - background: ${token.colorFillTertiary}; - border-radius: 6px; + padding: 12px 8px; + border-radius: ${token.borderRadius}px; + + .topic-more { + opacity: 0; + transition: opacity 400ms ${token.motionEaseOut}; + } &:hover { background: ${token.colorFillSecondary}; + + .topic-more { + opacity: 1; + } } `, split: css` @@ -39,13 +52,36 @@ export interface ConfigCellProps { } const TopicItem = memo(({ title, active, id, showFav, fav }) => { + const [dropdownOpen, setDropdownOpen] = useState(false); const { styles, theme, cx } = useStyles(); + const { t } = useTranslation('common'); const [dispatchTopic, toggleTopic] = useSessionStore( (s) => [s.dispatchTopic, s.toggleTopic], shallow, ); - const starIcon = (fav ? StarFilled : StarOutlined) as LucideIcon; + + // TODO: 动作绑定 + const items: MenuProps['items'] = useMemo( + () => [ + { + icon: , + key: 'rename', + label: t('rename'), + }, + { + icon: , + key: 'share', + label: t('share'), + }, + { + icon: , + key: 'delete', + label: t('delete'), + }, + ], + [], + ); return ( (({ title, active, id, showFav, fav }) => onClick={() => { toggleTopic(id); }} - padding={'10px 12px'} > - {title} - {!showFav ? undefined : ( + + {!showFav ? ( + + + + ) : ( + { + if (!id) return; + dispatchTopic({ id, key: 'favorite', type: 'updateChatTopic', value: !fav }); + }} + size={'small'} + /> + )} + + {title} + + {id ? '' : {t('temp')}} + + { - if (!id) return; - - dispatchTopic({ id, key: 'favorite', type: 'updateChatTopic', value: !fav }); - }} + className="topic-more" + icon={MoreVertical} size={'small'} - style={{ - color: fav ? theme.yellow : undefined, - }} + style={dropdownOpen ? { opacity: 1 } : {}} /> - )} + ); }); diff --git a/src/pages/chat/[id]/Conversation/ChatList.tsx b/src/pages/chat/[id]/Conversation/ChatList.tsx index 6ed7bb3520..e7551e6feb 100644 --- a/src/pages/chat/[id]/Conversation/ChatList.tsx +++ b/src/pages/chat/[id]/Conversation/ChatList.tsx @@ -1,6 +1,7 @@ import { ChatList, ChatMessage } from '@lobehub/ui'; import isEqual from 'fast-deep-equal'; import { ReactNode, memo } from 'react'; +import { useTranslation } from 'react-i18next'; import { shallow } from 'zustand/shallow'; import { agentSelectors, chatSelectors, useSessionStore } from '@/store/session'; @@ -10,6 +11,7 @@ import FunctionMessage from './FunctionMessage'; import MessageExtra from './MessageExtra'; const List = () => { + const { t } = useTranslation('common'); const data = useSessionStore(chatSelectors.currentChats, isEqual); const [displayMode, deleteMessage, resendMessage, dispatchMessage] = useSessionStore( (s) => [ @@ -50,6 +52,15 @@ const List = () => { renderMessage={renderMessage} renderMessageExtra={MessageExtra} style={{ marginTop: 24 }} + text={{ + cancel: t('cancel'), + confirm: t('ok'), + copy: t('copy'), + copySuccess: t('copySuccess'), + delete: t('delete'), + edit: t('edit'), + regenerate: t('regenerate'), + }} type={displayMode} /> ); diff --git a/src/pages/chat/[id]/Conversation/Input/Token.tsx b/src/pages/chat/[id]/Conversation/Input/Token.tsx index be47c66b92..a45cdff617 100644 --- a/src/pages/chat/[id]/Conversation/Input/Token.tsx +++ b/src/pages/chat/[id]/Conversation/Input/Token.tsx @@ -24,7 +24,11 @@ const Token = memo<{ input: string }>(({ input }) => { return ( - + ); }); diff --git a/src/pages/chat/[id]/edit/AgentPrompt/index.tsx b/src/pages/chat/[id]/edit/AgentPrompt/index.tsx index c9d22f242f..5578cd5fae 100644 --- a/src/pages/chat/[id]/edit/AgentPrompt/index.tsx +++ b/src/pages/chat/[id]/edit/AgentPrompt/index.tsx @@ -37,7 +37,7 @@ const AgentPrompt = memo(() => { }} placeholder={t('settingAgent.name.placeholder')} resize={false} - style={{ marginBottom: 16, marginTop: 16 }} + style={{ marginTop: 16 }} type={'pure'} value={systemRole} />