mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-27 13:29:15 +07:00
✨ feat(wip): Add setting page
- Update dependencies and add localization settings - Modify behavior of certain components - Restructure layout and components of chat page - Add new setting page - Implement server-side translation support - Import necessary dependencies for code - Import and export JSON files as resources - Define "NS" type based on imported resources The changes aim to introduce new features to the code repository, including updates to dependencies, localization settings, modification of component behavior, restructuring of the chat page, addition of a new setting page, implementation of server-side translation support, and necessary imports for dependencies. JSON files are also imported and exported as resources, defining a new type called "NS".
This commit is contained in:
@@ -61,7 +61,7 @@
|
||||
"@ant-design/colors": "^7",
|
||||
"@ant-design/icons": "^5",
|
||||
"@commitlint/cli": "^17",
|
||||
"@lobehub/ui": "lastest",
|
||||
"@lobehub/ui": "^1",
|
||||
"@vercel/analytics": "^1",
|
||||
"ahooks": "^3",
|
||||
"antd": "^5",
|
||||
|
||||
86
public/locales/zh_CN/setting.json
Normal file
86
public/locales/zh_CN/setting.json
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"accessCode": {
|
||||
"title": "访问密码",
|
||||
"subTitle": "管理员已开启加密访问",
|
||||
"placeholder": "请输入访问密码"
|
||||
},
|
||||
"avatar": "头像",
|
||||
"compressThreshold": {
|
||||
"title": "历史消息长度压缩阈值",
|
||||
"subTitle": "当未压缩的历史消息超过该值时,将进行压缩"
|
||||
},
|
||||
"customModel": {
|
||||
"title": "自定义模型名",
|
||||
"subTitle": "增加自定义模型可选项,使用英文逗号隔开"
|
||||
},
|
||||
"danger": {
|
||||
"reset": {
|
||||
"title": "重置所有设置",
|
||||
"subTitle": "重置所有设置项回默认值",
|
||||
"action": "立即重置",
|
||||
"confirm": "确认重置所有设置?",
|
||||
"currentVersion": "当前版本"
|
||||
},
|
||||
"clear": {
|
||||
"title": "清除所有数据",
|
||||
"subTitle": "清除所有聊天、设置数据",
|
||||
"action": "立即清除",
|
||||
"confirm": "确认清除所有聊天、设置数据?"
|
||||
}
|
||||
},
|
||||
"endpoint": {
|
||||
"title": "接口地址",
|
||||
"subTitle": "除默认地址外,必须包含 http(s)://"
|
||||
},
|
||||
"fontSize": {
|
||||
"title": "字体大小",
|
||||
"subTitle": "聊天内容的字体大小"
|
||||
},
|
||||
"frequencyPenalty": {
|
||||
"title": "频率惩罚度 (frequency_penalty)",
|
||||
"subTitle": "值越大,越有可能降低重复字词"
|
||||
},
|
||||
"historyCount": {
|
||||
"title": "附带历史消息数",
|
||||
"subTitle": "每次请求携带的历史消息数"
|
||||
},
|
||||
"inputTemplate": {
|
||||
"title": "用户输入预处理",
|
||||
"subTitle": "用户最新的一条消息会填充到此模板"
|
||||
},
|
||||
"lang": {
|
||||
"name": "语言设置",
|
||||
"all": "所有语言"
|
||||
},
|
||||
"maxTokens": {
|
||||
"title": "单次回复限制 (max_tokens)",
|
||||
"subTitle": "单次交互所用的最大 Token 数"
|
||||
},
|
||||
"model": "模型 (model)",
|
||||
"presencePenalty": {
|
||||
"title": "话题新鲜度 (presence_penalty)",
|
||||
"subTitle": "值越大,越有可能扩展到新话题"
|
||||
},
|
||||
"sendKey": "发送键",
|
||||
"temperature": {
|
||||
"title": "随机性 (temperature)",
|
||||
"subTitle": "值越大,回复越随机"
|
||||
},
|
||||
"theme": "主题",
|
||||
"token": {
|
||||
"title": "API Key",
|
||||
"subTitle": "使用自己的 Key 可绕过密码访问限制",
|
||||
"placeholder": "OpenAI API Key"
|
||||
},
|
||||
"topP": {
|
||||
"title": "核采样 (top_p)",
|
||||
"subTitle": "与随机性类似,但不要和随机性一起更改"
|
||||
},
|
||||
"update": {
|
||||
"isLatest": "已是最新版本",
|
||||
"checkUpdate": "检查更新",
|
||||
"isChecking": "正在检查更新...",
|
||||
"foundUpdate": "发现新版本",
|
||||
"goToUpdate": "前往更新"
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ActionIcon, Logo, SideNav } from '@lobehub/ui';
|
||||
import { MessageSquare, Settings2, Sticker } from 'lucide-react';
|
||||
import Router from 'next/router';
|
||||
import { memo } from 'react';
|
||||
import { shallow } from 'zustand/shallow';
|
||||
|
||||
@@ -10,7 +11,7 @@ const Sidebar = memo(() => {
|
||||
return (
|
||||
<SideNav
|
||||
avatar={<Logo size={40} />}
|
||||
bottomActions={<ActionIcon icon={Settings2} />}
|
||||
bottomActions={<ActionIcon icon={Settings2} onClick={() => Router.push('/setting')} />}
|
||||
style={{ height: '100vh' }}
|
||||
topActions={
|
||||
<>
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ActionIcon, Avatar } from '@lobehub/ui';
|
||||
import { createStyles, useTheme } from 'antd-style';
|
||||
import { ActionIcon, Avatar, ChatHeader } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { ArchiveIcon, MoreVerticalIcon, Share2Icon } from 'lucide-react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { memo } from 'react';
|
||||
@@ -19,7 +19,6 @@ const useStyles = createStyles(({ css, token }) => ({
|
||||
`,
|
||||
}));
|
||||
const Header = memo(() => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation('common');
|
||||
const meta = useChatStore((s) => {
|
||||
const chat = sessionSelectors.currentSession(s);
|
||||
@@ -40,41 +39,36 @@ const Header = memo(() => {
|
||||
|
||||
const { styles } = useStyles();
|
||||
return (
|
||||
<Flexbox
|
||||
align={'center'}
|
||||
distribution={'space-between'}
|
||||
horizontal
|
||||
padding="8px 8px 8px 16px"
|
||||
style={{
|
||||
borderBottom: `1px solid ${theme.colorSplit}`,
|
||||
gridArea: 'header',
|
||||
}}
|
||||
>
|
||||
<Flexbox align={'center'} gap={12} horizontal>
|
||||
<Avatar avatar={meta && sessionSelectors.getAgentAvatar(meta)} size={40} title={'123'} />
|
||||
<Flexbox>
|
||||
<Flexbox className={styles.title}>{meta?.title || t('defaultAgent')}</Flexbox>
|
||||
<Flexbox className={styles.desc}>{meta?.description || t('noDescription')}</Flexbox>
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
<Flexbox gap={8} horizontal>
|
||||
<ActionIcon
|
||||
icon={Share2Icon}
|
||||
onClick={() => {
|
||||
// genShareUrl();
|
||||
}}
|
||||
size={{ fontSize: 24 }}
|
||||
title={t('share')}
|
||||
/>
|
||||
<ActionIcon icon={ArchiveIcon} size={{ fontSize: 24 }} title={t('archive')} />
|
||||
<ActionIcon
|
||||
icon={MoreVerticalIcon}
|
||||
onClick={toggleConfig}
|
||||
size={{ fontSize: 24 }}
|
||||
title={t('sessionSetting')}
|
||||
/>
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
<ChatHeader
|
||||
left={
|
||||
<>
|
||||
<Avatar avatar={meta && sessionSelectors.getAgentAvatar(meta)} size={40} title={'123'} />
|
||||
<Flexbox>
|
||||
<Flexbox className={styles.title}>{meta?.title || t('defaultAgent')}</Flexbox>
|
||||
<Flexbox className={styles.desc}>{meta?.description || t('noDescription')}</Flexbox>
|
||||
</Flexbox>
|
||||
</>
|
||||
}
|
||||
right={
|
||||
<>
|
||||
<ActionIcon
|
||||
icon={Share2Icon}
|
||||
onClick={() => {
|
||||
// genShareUrl();
|
||||
}}
|
||||
size={{ fontSize: 24 }}
|
||||
title={t('share')}
|
||||
/>
|
||||
<ActionIcon icon={ArchiveIcon} size={{ fontSize: 24 }} title={t('archive')} />
|
||||
<ActionIcon
|
||||
icon={MoreVerticalIcon}
|
||||
onClick={toggleConfig}
|
||||
size={{ fontSize: 24 }}
|
||||
title={t('sessionSetting')}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -8,11 +8,11 @@ import { Flexbox } from 'react-layout-kit';
|
||||
import { sessionSelectors, useChatStore } from '@/store/session';
|
||||
import { useSettings } from '@/store/settings';
|
||||
|
||||
import Sidebar from '../../Sidebar';
|
||||
import Config from '../Config';
|
||||
import Conversation from '../Conversation';
|
||||
import Header from '../Header';
|
||||
import { Sessions } from '../SessionList';
|
||||
import Sidebar from '../Sidebar';
|
||||
|
||||
const ChatLayout = memo(() => {
|
||||
const [title] = useChatStore((s) => {
|
||||
@@ -57,14 +57,7 @@ const ChatLayout = memo(() => {
|
||||
);
|
||||
});
|
||||
|
||||
export async function getServerSideProps(context: any) {
|
||||
const { locale } = context;
|
||||
return {
|
||||
props: {
|
||||
// pass the translation props to the page component
|
||||
...(await serverSideTranslations(locale)),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const getServerSideProps = async (context: any) => ({
|
||||
props: await serverSideTranslations(context.locale),
|
||||
});
|
||||
export default ChatLayout;
|
||||
|
||||
27
src/pages/setting/Header.tsx
Normal file
27
src/pages/setting/Header.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { ChatHeader } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Router from 'next/router';
|
||||
import { memo } from 'react';
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
title: css`
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: ${token.colorText};
|
||||
`,
|
||||
}));
|
||||
const Header = memo(() => {
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const { styles } = useStyles();
|
||||
return (
|
||||
<ChatHeader
|
||||
left={<div className={styles.title}>{t('setting')}</div>}
|
||||
onBackClick={() => Router.back()}
|
||||
showBackButton
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
export default Header;
|
||||
39
src/pages/setting/index.page.tsx
Normal file
39
src/pages/setting/index.page.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
|
||||
import Head from 'next/head';
|
||||
import { memo } from 'react';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
|
||||
import { sessionSelectors, useChatStore } from '@/store/session';
|
||||
|
||||
import Sidebar from '../Sidebar';
|
||||
import { Sessions } from '../chat/SessionList';
|
||||
import Header from './Header';
|
||||
|
||||
const SettingLayout = memo(() => {
|
||||
const [title] = useChatStore((s) => {
|
||||
const context = sessionSelectors.currentSession(s);
|
||||
return [context?.meta.title];
|
||||
}, isEqual);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{title ? `${title} - LobeChat` : 'LobeChat'}</title>
|
||||
</Head>
|
||||
<Flexbox horizontal width={'100%'}>
|
||||
<Sidebar />
|
||||
<Sessions />
|
||||
<Flexbox flex={1}>
|
||||
<Header />
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export const getServerSideProps = async (context: any) => ({
|
||||
props: await serverSideTranslations(context.locale, ['common', 'setting']),
|
||||
});
|
||||
|
||||
export default SettingLayout;
|
||||
@@ -1,7 +1,11 @@
|
||||
import common from '@/../public/locales/zh_CN/common.json';
|
||||
import setting from '@/../public/locales/zh_CN/setting.json';
|
||||
|
||||
const resources = {
|
||||
common,
|
||||
setting,
|
||||
} as const;
|
||||
|
||||
export default resources;
|
||||
|
||||
export type NS = keyof typeof resources;
|
||||
|
||||
Reference in New Issue
Block a user