@lobehub/chat 0.53.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/locales/en_US/setting.json +1 -1
- package/locales/zh_CN/setting.json +1 -1
- package/package.json +1 -1
- package/public/images/theme_auto.webp +0 -0
- package/src/components/SelectWithImg/index.tsx +77 -0
- package/src/components/SelectWithImg/styles.ts +27 -0
- package/src/features/AgentSetting/AgentConfig/index.tsx +27 -7
- package/src/locales/default/setting.ts +1 -1
- package/src/pages/chat/SessionList/CollapseGroup.tsx +3 -0
- package/src/pages/chat/features/Conversation/ChatList/Error/style.tsx +1 -1
- package/src/pages/settings/Header.tsx +2 -4
- package/src/pages/settings/Settings/Common.tsx +27 -11
- package/src/pages/settings/Settings/index.tsx +68 -17
- /package/public/images/{chatmode_doc_dark.webp → chatmode_docs_dark.webp} +0 -0
- /package/public/images/{chatmode_doc_light.webp → chatmode_docs_light.webp} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 0.54.0](https://github.com/lobehub/lobe-chat/compare/v0.53.0...v0.54.0)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-08-15**</sup>
|
|
8
|
+
|
|
9
|
+
#### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **misc**: Add new features and improve user interface and functionality.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's improved
|
|
19
|
+
|
|
20
|
+
- **misc**: Add new features and improve user interface and functionality ([1543bd1](https://github.com/lobehub/lobe-chat/commit/1543bd1))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
5
30
|
## [Version 0.53.0](https://github.com/lobehub/lobe-chat/compare/v0.52.1...v0.53.0)
|
|
6
31
|
|
|
7
32
|
<sup>Released on **2023-08-15**</sup>
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
},
|
|
73
73
|
"inputTemplate": {
|
|
74
74
|
"desc": "The latest user message will be filled into this template",
|
|
75
|
-
"placeholder": "
|
|
75
|
+
"placeholder": "{{text}} will be replaced with real-time input information",
|
|
76
76
|
"title": "User Input Preprocessing"
|
|
77
77
|
},
|
|
78
78
|
"title": "Chat Settings"
|
package/package.json
CHANGED
|
Binary file
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Icon, IconProps } from '@lobehub/ui';
|
|
2
|
+
import { SelectProps } from 'antd';
|
|
3
|
+
import { type CSSProperties, ReactNode, memo, useEffect, useState } from 'react';
|
|
4
|
+
import { Flexbox } from 'react-layout-kit';
|
|
5
|
+
|
|
6
|
+
import { useStyles } from './styles';
|
|
7
|
+
|
|
8
|
+
export interface SelectWithImgOptionItem {
|
|
9
|
+
icon?: IconProps['icon'];
|
|
10
|
+
img: string;
|
|
11
|
+
label: ReactNode;
|
|
12
|
+
value: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SelectWithImgProps {
|
|
16
|
+
className?: string;
|
|
17
|
+
defaultValue?: SelectProps['defaultValue'];
|
|
18
|
+
imgClassName?: string;
|
|
19
|
+
imgStyle?: CSSProperties;
|
|
20
|
+
onChange?: (value: this['value']) => void;
|
|
21
|
+
options?: SelectWithImgOptionItem[];
|
|
22
|
+
size?: number;
|
|
23
|
+
style?: CSSProperties;
|
|
24
|
+
value?: SelectProps['value'];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const SelectWithImg = memo<SelectWithImgProps>(
|
|
28
|
+
({
|
|
29
|
+
className,
|
|
30
|
+
style,
|
|
31
|
+
value,
|
|
32
|
+
defaultValue,
|
|
33
|
+
onChange,
|
|
34
|
+
options,
|
|
35
|
+
size = 100,
|
|
36
|
+
imgStyle,
|
|
37
|
+
imgClassName,
|
|
38
|
+
}) => {
|
|
39
|
+
const [currentValue, setCurrentValue] = useState(value || defaultValue);
|
|
40
|
+
const { styles, cx } = useStyles();
|
|
41
|
+
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
onChange?.(currentValue);
|
|
44
|
+
}, [currentValue]);
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<Flexbox className={className} gap={8} horizontal style={style}>
|
|
48
|
+
{options?.map((item) => {
|
|
49
|
+
const isActive = value ? item.value === value : item.value === currentValue;
|
|
50
|
+
return (
|
|
51
|
+
<Flexbox
|
|
52
|
+
align={'center'}
|
|
53
|
+
className={cx(styles.container, isActive && styles.active)}
|
|
54
|
+
gap={4}
|
|
55
|
+
key={item.value}
|
|
56
|
+
onClick={() => setCurrentValue(item.value)}
|
|
57
|
+
>
|
|
58
|
+
<img
|
|
59
|
+
alt={item.value}
|
|
60
|
+
className={imgClassName}
|
|
61
|
+
src={item.img}
|
|
62
|
+
style={imgStyle}
|
|
63
|
+
width={size}
|
|
64
|
+
/>
|
|
65
|
+
<Flexbox align={'center'} gap={4} horizontal>
|
|
66
|
+
{item.icon && <Icon icon={item.icon} />}
|
|
67
|
+
{item.label}
|
|
68
|
+
</Flexbox>
|
|
69
|
+
</Flexbox>
|
|
70
|
+
);
|
|
71
|
+
})}
|
|
72
|
+
</Flexbox>
|
|
73
|
+
);
|
|
74
|
+
},
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
export default SelectWithImg;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createStyles } from 'antd-style';
|
|
2
|
+
|
|
3
|
+
export const useStyles = createStyles(({ css, token }) => ({
|
|
4
|
+
active: css`
|
|
5
|
+
color: ${token.colorText};
|
|
6
|
+
|
|
7
|
+
> img {
|
|
8
|
+
box-shadow: 0 0 0 1px ${token.colorTextDescription};
|
|
9
|
+
}
|
|
10
|
+
`,
|
|
11
|
+
container: css`
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
color: ${token.colorTextDescription};
|
|
14
|
+
|
|
15
|
+
> img {
|
|
16
|
+
overflow: hidden;
|
|
17
|
+
border-radius: ${token.borderRadius}px;
|
|
18
|
+
box-shadow: 0 0 0 1px ${token.colorBorder};
|
|
19
|
+
transition: all 100ms ${token.motionEaseOut};
|
|
20
|
+
|
|
21
|
+
&:hover {
|
|
22
|
+
border-color: ${token.colorText};
|
|
23
|
+
box-shadow: 0 0 0 2px ${token.colorText};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`,
|
|
27
|
+
}));
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Form, ItemGroup, SliderWithInput } from '@lobehub/ui';
|
|
2
|
-
import { ConfigProvider, Input,
|
|
3
|
-
import { useTheme } from 'antd-style';
|
|
2
|
+
import { ConfigProvider, Input, Select, Switch } from 'antd';
|
|
3
|
+
import { useTheme, useThemeMode } from 'antd-style';
|
|
4
4
|
import { debounce } from 'lodash-es';
|
|
5
|
-
import { BrainCog, MessagesSquare } from 'lucide-react';
|
|
5
|
+
import { BrainCog, LayoutList, MessageSquare, MessagesSquare } from 'lucide-react';
|
|
6
6
|
import { memo, useMemo } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
|
|
9
|
+
import SelectWithImg from '@/components/SelectWithImg';
|
|
9
10
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
10
11
|
import { AgentAction } from '@/store/session/slices/agentConfig';
|
|
11
12
|
import { LanguageModel } from '@/types/llm';
|
|
@@ -26,17 +27,36 @@ export interface AgentConfigProps {
|
|
|
26
27
|
const AgentConfig = memo<AgentConfigProps>(({ config, updateConfig }) => {
|
|
27
28
|
const { t } = useTranslation('setting');
|
|
28
29
|
const theme = useTheme();
|
|
30
|
+
const { isDarkMode } = useThemeMode();
|
|
29
31
|
|
|
30
32
|
const chat: SettingItemGroup = useMemo(
|
|
31
33
|
() => ({
|
|
32
34
|
children: [
|
|
33
35
|
{
|
|
34
36
|
children: (
|
|
35
|
-
<
|
|
37
|
+
<SelectWithImg
|
|
38
|
+
imgStyle={{
|
|
39
|
+
background: `linear-gradient(
|
|
40
|
+
to bottom,
|
|
41
|
+
${isDarkMode ? theme.colorBgElevated : theme.colorBgLayout},
|
|
42
|
+
${theme.colorBgContainer}
|
|
43
|
+
)`,
|
|
44
|
+
}}
|
|
36
45
|
options={[
|
|
37
|
-
{
|
|
38
|
-
|
|
46
|
+
{
|
|
47
|
+
icon: MessagesSquare,
|
|
48
|
+
img: `/images/chatmode_chat_${isDarkMode ? 'dark' : 'light'}.webp`,
|
|
49
|
+
label: t('settingChat.chatStyleType.type.chat'),
|
|
50
|
+
value: 'chat',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
icon: LayoutList,
|
|
54
|
+
img: `/images/chatmode_docs_${isDarkMode ? 'dark' : 'light'}.webp`,
|
|
55
|
+
label: t('settingChat.chatStyleType.type.docs'),
|
|
56
|
+
value: 'docs',
|
|
57
|
+
},
|
|
39
58
|
]}
|
|
59
|
+
size={144}
|
|
40
60
|
/>
|
|
41
61
|
),
|
|
42
62
|
label: t('settingChat.chatStyleType.title'),
|
|
@@ -80,7 +100,7 @@ const AgentConfig = memo<AgentConfigProps>(({ config, updateConfig }) => {
|
|
|
80
100
|
name: 'compressThreshold',
|
|
81
101
|
},
|
|
82
102
|
],
|
|
83
|
-
icon:
|
|
103
|
+
icon: MessageSquare,
|
|
84
104
|
title: t('settingChat.title'),
|
|
85
105
|
}),
|
|
86
106
|
[config],
|
|
@@ -16,6 +16,9 @@ const useStyles = createStyles(({ css, prefixCls, token }) => ({
|
|
|
16
16
|
background: ${token.colorFillTertiary};
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
.${prefixCls}-collapse-content {
|
|
20
|
+
border-radius: 0 !important;
|
|
21
|
+
}
|
|
19
22
|
.${prefixCls}-collapse-content-box {
|
|
20
23
|
padding: 0 !important;
|
|
21
24
|
}
|
|
@@ -35,7 +35,7 @@ export const FormAction = memo<{
|
|
|
35
35
|
|
|
36
36
|
return (
|
|
37
37
|
<Center gap={16} style={{ maxWidth: 300 }}>
|
|
38
|
-
<Avatar avatar={avatar} background={theme.
|
|
38
|
+
<Avatar avatar={avatar} background={theme.colorFillContent} gap={12} size={80} />
|
|
39
39
|
<Flexbox style={{ fontSize: 20 }}>{title}</Flexbox>
|
|
40
40
|
<Flexbox className={styles.desc}>{description}</Flexbox>
|
|
41
41
|
{children}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { ChatHeader, ChatHeaderTitle
|
|
1
|
+
import { ChatHeader, ChatHeaderTitle } from '@lobehub/ui';
|
|
2
2
|
import Router from 'next/router';
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
|
|
6
|
-
import pkg from '@/../package.json';
|
|
7
|
-
|
|
8
6
|
const Header = memo(() => {
|
|
9
7
|
const { t } = useTranslation('setting');
|
|
10
8
|
|
|
11
9
|
return (
|
|
12
10
|
<ChatHeader
|
|
13
|
-
left={<ChatHeaderTitle
|
|
11
|
+
left={<ChatHeaderTitle title={t('header.global')} />}
|
|
14
12
|
onBackClick={() => Router.back()}
|
|
15
13
|
showBackButton
|
|
16
14
|
/>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Form, type ItemGroup, SliderWithInput
|
|
1
|
+
import { Form, type ItemGroup, SliderWithInput } from '@lobehub/ui';
|
|
2
2
|
import { Form as AntForm, App, Button, Input, Select } from 'antd';
|
|
3
3
|
import isEqual from 'fast-deep-equal';
|
|
4
4
|
import { changeLanguage } from 'i18next';
|
|
5
5
|
import { debounce } from 'lodash-es';
|
|
6
|
-
import { AppWindow, Palette, Webhook } from 'lucide-react';
|
|
6
|
+
import { AppWindow, Monitor, Moon, Palette, Sun, Webhook } from 'lucide-react';
|
|
7
7
|
import { memo, useCallback, useMemo } from 'react';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
|
10
|
+
import SelectWithImg from '@/components/SelectWithImg';
|
|
10
11
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
11
12
|
import { DEFAULT_SETTINGS } from '@/const/settings';
|
|
12
13
|
import AvatarWithUpload from '@/features/AvatarWithUpload';
|
|
@@ -76,18 +77,33 @@ const Common = memo(() => {
|
|
|
76
77
|
},
|
|
77
78
|
{
|
|
78
79
|
children: (
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
<SelectWithImg
|
|
81
|
+
defaultValue={settings.themeMode}
|
|
82
|
+
onChange={setThemeMode}
|
|
83
|
+
options={[
|
|
84
|
+
{
|
|
85
|
+
icon: Sun,
|
|
86
|
+
img: '/images/theme_light.webp',
|
|
87
|
+
label: t('settingTheme.themeMode.light'),
|
|
88
|
+
value: 'light',
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
icon: Moon,
|
|
92
|
+
img: '/images/theme_dark.webp',
|
|
93
|
+
label: t('settingTheme.themeMode.dark'),
|
|
94
|
+
value: 'dark',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
icon: Monitor,
|
|
98
|
+
img: '/images/theme_auto.webp',
|
|
99
|
+
label: t('settingTheme.themeMode.auto'),
|
|
100
|
+
value: 'auto',
|
|
101
|
+
},
|
|
102
|
+
]}
|
|
88
103
|
/>
|
|
89
104
|
),
|
|
90
105
|
label: t('settingTheme.themeMode.title'),
|
|
106
|
+
minWidth: undefined,
|
|
91
107
|
},
|
|
92
108
|
{
|
|
93
109
|
children: (
|
|
@@ -1,46 +1,97 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { GridBackground, Icon, Logo, TabsNav } from '@lobehub/ui';
|
|
2
2
|
import { createStyles } from 'antd-style';
|
|
3
|
+
import { PackageCheck } from 'lucide-react';
|
|
4
|
+
import { rgba } from 'polished';
|
|
3
5
|
import { memo, useState } from 'react';
|
|
4
6
|
import { useTranslation } from 'react-i18next';
|
|
5
|
-
import { Center } from 'react-layout-kit';
|
|
7
|
+
import { Center, Flexbox } from 'react-layout-kit';
|
|
8
|
+
|
|
9
|
+
import pkg from '@/../package.json';
|
|
6
10
|
|
|
7
11
|
import Agent from './Agent';
|
|
8
12
|
import Common from './Common';
|
|
9
13
|
|
|
10
|
-
const useStyles = createStyles(({ css, token }) => ({
|
|
14
|
+
const useStyles = createStyles(({ css, token, isDarkMode }) => ({
|
|
15
|
+
background: css`
|
|
16
|
+
position: absolute;
|
|
17
|
+
bottom: -10%;
|
|
18
|
+
left: 0;
|
|
19
|
+
width: 100%;
|
|
20
|
+
`,
|
|
21
|
+
logo: css`
|
|
22
|
+
position: absolute;
|
|
23
|
+
top: 50%;
|
|
24
|
+
left: 32px;
|
|
25
|
+
transform: translateY(-50%);
|
|
26
|
+
`,
|
|
11
27
|
tabs: css`
|
|
28
|
+
position: relative;
|
|
29
|
+
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
|
|
32
|
+
width: 100%;
|
|
33
|
+
max-width: 1024px;
|
|
34
|
+
height: 160px;
|
|
12
35
|
padding: 4px;
|
|
36
|
+
|
|
37
|
+
background: radial-gradient(
|
|
38
|
+
120% 120% at 20% 100%,
|
|
39
|
+
${isDarkMode ? rgba(token.colorBgContainer, 0.5) : token.colorBgContainer} 32%,
|
|
40
|
+
${isDarkMode ? token.colorPrimaryBgHover : rgba(token.colorPrimaryBgHover, 0.3)} 50%,
|
|
41
|
+
${isDarkMode ? token.colorPrimaryHover : rgba(token.colorPrimaryHover, 0.3)} 100%
|
|
42
|
+
);
|
|
13
43
|
border: 1px solid ${token.colorBorderSecondary};
|
|
14
44
|
border-radius: ${token.borderRadiusLG}px;
|
|
45
|
+
`,
|
|
46
|
+
tag: css`
|
|
47
|
+
position: absolute;
|
|
48
|
+
top: 6px;
|
|
49
|
+
right: 12px;
|
|
50
|
+
|
|
51
|
+
font-family: ${token.fontFamilyCode};
|
|
52
|
+
font-size: 12px;
|
|
53
|
+
color: ${isDarkMode ? token.colorPrimaryBg : token.colorPrimaryActive};
|
|
15
54
|
|
|
16
|
-
|
|
17
|
-
border-color: ${token.colorBorder};
|
|
18
|
-
}
|
|
55
|
+
opacity: 0.5;
|
|
19
56
|
`,
|
|
20
57
|
}));
|
|
21
58
|
|
|
22
59
|
enum Tabs {
|
|
23
|
-
|
|
24
|
-
|
|
60
|
+
agent = 'agent',
|
|
61
|
+
common = 'common',
|
|
25
62
|
}
|
|
26
63
|
|
|
27
64
|
const Settings = memo(() => {
|
|
28
65
|
const [tab, setTab] = useState<Tabs>(Tabs.common);
|
|
29
|
-
const { styles } = useStyles();
|
|
66
|
+
const { styles, theme } = useStyles();
|
|
30
67
|
const { t } = useTranslation('setting');
|
|
31
68
|
|
|
32
69
|
return (
|
|
33
70
|
<Center gap={16} width={'100%'}>
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
71
|
+
<Flexbox align={'flex-end'} className={styles.tabs} horizontal justify={'center'}>
|
|
72
|
+
<GridBackground
|
|
73
|
+
animation
|
|
74
|
+
className={styles.background}
|
|
75
|
+
colorBack={theme.colorFillSecondary}
|
|
76
|
+
colorFront={theme.colorPrimary}
|
|
77
|
+
random
|
|
78
|
+
/>
|
|
79
|
+
<TabsNav
|
|
80
|
+
activeKey={tab}
|
|
81
|
+
items={[
|
|
82
|
+
{ key: Tabs.common, label: t('tab.common') },
|
|
83
|
+
{ key: Tabs.agent, label: t('tab.agent') },
|
|
40
84
|
]}
|
|
41
|
-
|
|
85
|
+
onChange={(e) => setTab(e as Tabs)}
|
|
42
86
|
/>
|
|
43
|
-
|
|
87
|
+
<div className={styles.logo}>
|
|
88
|
+
<Logo extra={'Chat'} type={'text'} />
|
|
89
|
+
</div>
|
|
90
|
+
<Flexbox align={'center'} className={styles.tag} gap={4} horizontal>
|
|
91
|
+
<Icon icon={PackageCheck} />
|
|
92
|
+
<div>{`${pkg.version}`}</div>
|
|
93
|
+
</Flexbox>
|
|
94
|
+
</Flexbox>
|
|
44
95
|
{tab === Tabs.common && <Common />}
|
|
45
96
|
{tab === Tabs.agent && <Agent />}
|
|
46
97
|
</Center>
|
|
File without changes
|
|
File without changes
|