✨ feat: Add topic empty
Add new translations, modify titles and descriptions, and add new components to the project. Changes involve localization files, image files, and code files.
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"topic": {
|
||||
"desc": "Click the button on the left to save the current conversation as a historical topic and start a new conversation",
|
||||
"title": "Topic List"
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,10 @@
|
||||
"title": "Enable History Message Length Compression Threshold"
|
||||
},
|
||||
"enableHistoryCount": {
|
||||
"title": "Enable History Message Count Limit"
|
||||
"title": "Enable History Message Count Limit",
|
||||
"alias": "Unlimited",
|
||||
"limited": "Only include {{number}} chat messages",
|
||||
"unlimited": "Unlimited chat history"
|
||||
},
|
||||
"historyCount": {
|
||||
"desc": "Number of history messages carried in each request",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"topic": {
|
||||
"desc": "点击发送左侧按钮可将当前会话保存为历史话题,并开启新一轮会话",
|
||||
"title": "话题列表"
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,10 @@
|
||||
"title": "是否开启历史消息长度压缩阈值"
|
||||
},
|
||||
"enableHistoryCount": {
|
||||
"title": "是否开启携带的历史消息数限制"
|
||||
"alias": "不限制",
|
||||
"limited": "只包含 {{number}} 条会话消息",
|
||||
"title": "限制历史消息数",
|
||||
"unlimited": "不限历史消息数"
|
||||
},
|
||||
"historyCount": {
|
||||
"desc": "每次请求携带的历史消息数",
|
||||
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
@@ -0,0 +1,34 @@
|
||||
import { ActionIcon } from '@lobehub/ui';
|
||||
import { X } from 'lucide-react';
|
||||
import { memo, useState } from 'react';
|
||||
|
||||
import { useStyles } from './style';
|
||||
|
||||
interface EmptyProps {
|
||||
cover: string;
|
||||
desc: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const Empty = memo<EmptyProps>(({ cover, title, desc }) => {
|
||||
const [visiable, setVisiable] = useState(true);
|
||||
const { styles } = useStyles();
|
||||
if (!visiable) return null;
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<ActionIcon
|
||||
className={styles.close}
|
||||
icon={X}
|
||||
onClick={() => setVisiable(false)}
|
||||
size={{ blockSize: 24, fontSize: 16 }}
|
||||
/>
|
||||
{cover && <img alt="empty" src={cover} width="100%" />}
|
||||
<div className={styles.content}>
|
||||
{title && <h3>{title}</h3>}
|
||||
{desc && <p className={styles.desc}>{desc}</p>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Empty;
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
export const useStyles = createStyles(({ css, token, isDarkMode }) => ({
|
||||
close: css`
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
`,
|
||||
container: css`
|
||||
position: relative;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
${isDarkMode ? token.colorBgElevated : token.colorBgLayout},
|
||||
${token.colorBgContainer}
|
||||
);
|
||||
border: 1px solid ${token.colorBorderSecondary};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
`,
|
||||
content: css`
|
||||
padding: 0 16px 16px;
|
||||
`,
|
||||
desc: css`
|
||||
color: ${token.colorTextDescription};
|
||||
`,
|
||||
}));
|
||||
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
topic: {
|
||||
desc: '点击发送左侧按钮可将当前会话保存为历史话题,并开启新一轮会话',
|
||||
title: '话题列表',
|
||||
},
|
||||
};
|
||||
@@ -1,3 +1,15 @@
|
||||
const resources = {} as const;
|
||||
import common from '../../../locales/en_US/common.json';
|
||||
import empty from '../../../locales/en_US/empty.json';
|
||||
import error from '../../../locales/en_US/error.json';
|
||||
import plugin from '../../../locales/en_US/plugin.json';
|
||||
import setting from '../../../locales/en_US/setting.json';
|
||||
|
||||
const resources = {
|
||||
common,
|
||||
empty,
|
||||
error,
|
||||
plugin,
|
||||
setting,
|
||||
} as const;
|
||||
|
||||
export default resources;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import common from '../default/common';
|
||||
import empty from '../default/empty';
|
||||
import error from '../default/error';
|
||||
import plugin from '../default/plugin';
|
||||
import setting from '../default/setting';
|
||||
|
||||
const resources = {
|
||||
common,
|
||||
empty,
|
||||
error,
|
||||
plugin,
|
||||
setting,
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
import { useThemeMode } from 'antd-style';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
|
||||
import Empty from '@/components/Empty';
|
||||
import { topicSelectors, useSessionStore } from '@/store/session';
|
||||
|
||||
import TopicItem from './TopicItem';
|
||||
|
||||
export const Topic = () => {
|
||||
const topics = useSessionStore(topicSelectors.currentTopics);
|
||||
const { isDarkMode } = useThemeMode();
|
||||
const [activeTopicId] = useSessionStore((s) => [s.activeTopicId], shallow);
|
||||
const { t } = useTranslation('empty');
|
||||
return (
|
||||
<Flexbox gap={8}>
|
||||
{topics?.length === 0 && (
|
||||
<Empty
|
||||
cover={`/images/empty_topic_${isDarkMode ? 'dark' : 'light'}.webp`}
|
||||
desc={t('topic.desc')}
|
||||
title={t('topic.title')}
|
||||
/>
|
||||
)}
|
||||
|
||||
<TopicItem active={!activeTopicId} fav={false} title={'默认话题'} />
|
||||
|
||||
{topics.map(({ id, favorite, title }) => (
|
||||
|
||||