feat: Add new translations, update existing translations, add functionality to components, modify styling, and adjust placeholder text

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.
This commit is contained in:
canisminor1990
2023-07-27 00:56:39 +08:00
parent 11caba6a89
commit da4ae724c1
12 changed files with 268 additions and 71 deletions

View File

@@ -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"
}

View File

@@ -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": {

View File

@@ -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": "更新提示词"
}

View File

@@ -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": {

View File

@@ -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: '将当前会话保存为话题',

View File

@@ -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<SessionItemProps> = memo(({ id, active = true, loading }) => {
const SessionItem: FC<SessionItemProps> = 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<SessionItemProps> = memo(({ id, active = true, loading })
];
}, shallow);
// TODO: 动作绑定
const items: MenuProps['items'] = useMemo(
() => [
{
icon: <Icon icon={pin ? PinOff : Pin} />,
key: 'pin',
label: t(pin ? 'pinOff' : 'pin'),
},
{
children: [
{
key: 'agent',
label: <div>{t('exportType.agent')}</div>,
},
{
key: 'agentWithMessage',
label: <div>{t('exportType.agentWithMessage')}</div>,
},
],
icon: <Icon icon={FolderOutput} />,
key: 'export',
label: t('export'),
},
{
icon: <Icon icon={Trash} />,
key: 'delete',
label: t('delete'),
onClick: () => setPopOpen(true),
},
],
[id],
);
const showModel = model !== defaultModel;
const showChatLength = chatLength > 0;
return (
<div ref={ref}>
<Flexbox className={styles.container} style={{ position: 'relative' }}>
<Flexbox className={cx(styles.container, pin && styles.pin)} style={{ position: 'relative' }}>
<Item
active={active}
avatar={
@@ -72,6 +109,7 @@ const SessionItem: FC<SessionItemProps> = 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<SessionItemProps> = 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')}
>
<ActionIcon
className="session-remove"
icon={X}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
}}
size={'small'}
/>
<Dropdown
arrow={false}
menu={{ items }}
onOpenChange={setDropdownOpen}
open={dropdownOpen}
trigger={['click']}
>
<ActionIcon
className="session-remove"
icon={MoreVertical}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
}}
size={{
blockSize: 28,
fontSize: 16,
}}
/>
</Dropdown>
</Popconfirm>
</Flexbox>
</div>

View File

@@ -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;
`,

View File

@@ -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}
/>
<Flexbox gap={12} style={{ padding: 16 }}>
<SearchBar placeholder={t('topic.searchPlaceholder')} type={'block'} />
<Flexbox gap={16} style={{ padding: 16 }}>
<SearchBar placeholder={t('topic.searchPlaceholder')} spotlight type={'ghost'} />
<Topic />
</Flexbox>
</DraggablePanelBody>

View File

@@ -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<ConfigCellProps>(({ 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: <Icon icon={PencilLine} />,
key: 'rename',
label: t('rename'),
},
{
icon: <Icon icon={Share2} />,
key: 'share',
label: t('share'),
},
{
icon: <Icon icon={Trash} />,
key: 'delete',
label: t('delete'),
},
],
[],
);
return (
<Flexbox
@@ -56,23 +92,43 @@ const TopicItem = memo<ConfigCellProps>(({ title, active, id, showFav, fav }) =>
onClick={() => {
toggleTopic(id);
}}
padding={'10px 12px'}
>
{title}
{!showFav ? undefined : (
<Flexbox align={'center'} gap={8} horizontal>
{!showFav ? (
<Flexbox align={'center'} height={24} justify={'center'} width={24}>
<Icon color={theme.colorTextDescription} icon={MessageSquareDashed} />
</Flexbox>
) : (
<ActionIcon
color={fav ? theme.colorWarning : undefined}
fill={fav ? theme.colorWarning : 'transparent'}
icon={Star}
onClick={() => {
if (!id) return;
dispatchTopic({ id, key: 'favorite', type: 'updateChatTopic', value: !fav });
}}
size={'small'}
/>
)}
<Paragraph ellipsis={{ rows: 2 }} style={{ margin: 0 }}>
{title}
</Paragraph>
{id ? '' : <Tag>{t('temp')}</Tag>}
</Flexbox>
<Dropdown
arrow={false}
menu={{ items }}
onOpenChange={setDropdownOpen}
open={dropdownOpen}
trigger={['click']}
>
<ActionIcon
icon={starIcon}
onClick={() => {
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 } : {}}
/>
)}
</Dropdown>
</Flexbox>
);
});

View File

@@ -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}
/>
);

View File

@@ -24,7 +24,11 @@ const Token = memo<{ input: string }>(({ input }) => {
return (
<Tooltip title={t('tokenDetail', { chatsToken, systemRoleToken })}>
<TokenTag maxValue={ModelTokens[model]} value={totalToken + inputTokenCount} />
<TokenTag
maxValue={ModelTokens[model]}
text={{ overload: t('overload') }}
value={totalToken + inputTokenCount}
/>
</Tooltip>
);
});

View File

@@ -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}
/>