@lobehub/chat 0.40.6 → 0.41.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/.eslintrc.js +1 -0
- package/CHANGELOG.md +58 -0
- package/package.json +2 -1
- package/src/components/Empty/index.tsx +46 -20
- package/src/pages/chat/[id]/Sidebar/Inner.tsx +16 -1
- package/src/pages/chat/[id]/Sidebar/Topic/index.tsx +16 -1
- package/src/store/session/hooks/useSessionHydrated.ts +5 -2
- package/src/store/settings/initialState.ts +7 -0
- package/src/store/settings/{action.ts → slices/agent.ts} +5 -66
- package/src/store/settings/slices/common.ts +96 -0
- package/src/store/settings/store.ts +5 -3
package/.eslintrc.js
CHANGED
|
@@ -7,5 +7,6 @@ config.rules['unicorn/prefer-type-error'] = 0;
|
|
|
7
7
|
config.rules['unicorn/prefer-logical-operator-over-ternary'] = 0;
|
|
8
8
|
config.rules['unicorn/no-null'] = 0;
|
|
9
9
|
config.rules['unicorn/no-typeof-undefined'] = 0;
|
|
10
|
+
config.rules['unicorn/explicit-length-check'] = 0;
|
|
10
11
|
|
|
11
12
|
module.exports = config;
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 0.41.0](https://github.com/lobehub/lobe-chat/compare/v0.40.7...v0.41.0)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-08-10**</sup>
|
|
8
|
+
|
|
9
|
+
#### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **misc**: 支持持久化隐藏 Topic 功能.
|
|
12
|
+
|
|
13
|
+
#### 💄 Styles
|
|
14
|
+
|
|
15
|
+
- **misc**: 优化第一次水合逻辑.
|
|
16
|
+
|
|
17
|
+
<br/>
|
|
18
|
+
|
|
19
|
+
<details>
|
|
20
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
21
|
+
|
|
22
|
+
#### What's improved
|
|
23
|
+
|
|
24
|
+
- **misc**: 支持持久化隐藏 Topic 功能 ([9ea2778](https://github.com/lobehub/lobe-chat/commit/9ea2778))
|
|
25
|
+
|
|
26
|
+
#### Styles
|
|
27
|
+
|
|
28
|
+
- **misc**: 优化第一次水合逻辑 ([fefae61](https://github.com/lobehub/lobe-chat/commit/fefae61))
|
|
29
|
+
|
|
30
|
+
</details>
|
|
31
|
+
|
|
32
|
+
<div align="right">
|
|
33
|
+
|
|
34
|
+
[](#readme-top)
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
### [Version 0.40.7](https://github.com/lobehub/lobe-chat/compare/v0.40.6...v0.40.7)
|
|
39
|
+
|
|
40
|
+
<sup>Released on **2023-08-10**</sup>
|
|
41
|
+
|
|
42
|
+
#### 💄 Styles
|
|
43
|
+
|
|
44
|
+
- **misc**: 优化 Topic 的水合加载效果.
|
|
45
|
+
|
|
46
|
+
<br/>
|
|
47
|
+
|
|
48
|
+
<details>
|
|
49
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
50
|
+
|
|
51
|
+
#### Styles
|
|
52
|
+
|
|
53
|
+
- **misc**: 优化 Topic 的水合加载效果 ([0cd0088](https://github.com/lobehub/lobe-chat/commit/0cd0088))
|
|
54
|
+
|
|
55
|
+
</details>
|
|
56
|
+
|
|
57
|
+
<div align="right">
|
|
58
|
+
|
|
59
|
+
[](#readme-top)
|
|
60
|
+
|
|
61
|
+
</div>
|
|
62
|
+
|
|
5
63
|
### [Version 0.40.6](https://github.com/lobehub/lobe-chat/compare/v0.40.5...v0.40.6)
|
|
6
64
|
|
|
7
65
|
<sup>Released on **2023-08-10**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.41.0",
|
|
4
4
|
"description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatbot",
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
"serpapi": "^2",
|
|
94
94
|
"swr": "^2",
|
|
95
95
|
"ts-md5": "^1",
|
|
96
|
+
"use-merge-value": "^1",
|
|
96
97
|
"uuid": "^9",
|
|
97
98
|
"zustand": "^4.4",
|
|
98
99
|
"zustand-utils": "^1"
|
|
@@ -1,34 +1,60 @@
|
|
|
1
1
|
import { ActionIcon, DivProps } from '@lobehub/ui';
|
|
2
2
|
import { X } from 'lucide-react';
|
|
3
|
-
import
|
|
3
|
+
import Image from 'next/image';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import useMergeState from 'use-merge-value';
|
|
4
6
|
|
|
5
7
|
import { useStyles } from './style';
|
|
6
8
|
|
|
7
9
|
interface EmptyProps extends DivProps {
|
|
10
|
+
alt: string;
|
|
8
11
|
cover: string;
|
|
12
|
+
defaultVisible?: boolean;
|
|
9
13
|
desc: string;
|
|
14
|
+
height?: number;
|
|
15
|
+
onVisibleChange?: (visible: boolean) => void;
|
|
10
16
|
title: string;
|
|
17
|
+
visible?: boolean;
|
|
18
|
+
width?: number;
|
|
11
19
|
}
|
|
12
20
|
|
|
13
|
-
const Empty = memo<EmptyProps>(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
const Empty = memo<EmptyProps>(
|
|
22
|
+
({
|
|
23
|
+
cover,
|
|
24
|
+
visible,
|
|
25
|
+
defaultVisible,
|
|
26
|
+
onVisibleChange,
|
|
27
|
+
alt,
|
|
28
|
+
title,
|
|
29
|
+
desc,
|
|
30
|
+
width,
|
|
31
|
+
height,
|
|
32
|
+
...props
|
|
33
|
+
}) => {
|
|
34
|
+
const [value, setValue] = useMergeState(true, {
|
|
35
|
+
defaultValue: defaultVisible,
|
|
36
|
+
onChange: onVisibleChange,
|
|
37
|
+
value: visible,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const { styles } = useStyles();
|
|
41
|
+
if (!value) return null;
|
|
42
|
+
return (
|
|
43
|
+
<div className={styles.container} {...props}>
|
|
44
|
+
<ActionIcon
|
|
45
|
+
className={styles.close}
|
|
46
|
+
icon={X}
|
|
47
|
+
onClick={() => setValue(false)}
|
|
48
|
+
size={{ blockSize: 24, fontSize: 16 }}
|
|
49
|
+
/>
|
|
50
|
+
{cover && <Image alt={alt} height={height} src={cover} width={width} />}
|
|
51
|
+
<div className={styles.content}>
|
|
52
|
+
{title && <h3>{title}</h3>}
|
|
53
|
+
{desc && <p className={styles.desc}>{desc}</p>}
|
|
54
|
+
</div>
|
|
29
55
|
</div>
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
56
|
+
);
|
|
57
|
+
},
|
|
58
|
+
);
|
|
33
59
|
|
|
34
60
|
export default Empty;
|
|
@@ -86,7 +86,22 @@ const Inner = memo(() => {
|
|
|
86
86
|
</Flexbox>
|
|
87
87
|
<Flexbox className={styles.topic} gap={16} padding={16}>
|
|
88
88
|
<SearchBar placeholder={t('topic.searchPlaceholder')} spotlight type={'ghost'} />
|
|
89
|
-
|
|
89
|
+
{!hydrated ? (
|
|
90
|
+
<Flexbox gap={8} style={{ marginTop: 12 }}>
|
|
91
|
+
{Array.from({ length: 8 }).map((_, i) => (
|
|
92
|
+
<Skeleton
|
|
93
|
+
active
|
|
94
|
+
avatar={false}
|
|
95
|
+
key={i}
|
|
96
|
+
paragraph={{ rows: 1, width: '100%' }}
|
|
97
|
+
round
|
|
98
|
+
title={false}
|
|
99
|
+
/>
|
|
100
|
+
))}
|
|
101
|
+
</Flexbox>
|
|
102
|
+
) : (
|
|
103
|
+
<Topic />
|
|
104
|
+
)}
|
|
90
105
|
</Flexbox>
|
|
91
106
|
</DraggablePanelBody>
|
|
92
107
|
);
|
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
import { useThemeMode } from 'antd-style';
|
|
2
|
+
import isEqual from 'fast-deep-equal';
|
|
2
3
|
import { useTranslation } from 'react-i18next';
|
|
3
4
|
import { Flexbox } from 'react-layout-kit';
|
|
4
5
|
import { shallow } from 'zustand/shallow';
|
|
5
6
|
|
|
6
7
|
import Empty from '@/components/Empty';
|
|
7
8
|
import { topicSelectors, useSessionStore } from '@/store/session';
|
|
9
|
+
import { useSettings } from '@/store/settings';
|
|
8
10
|
|
|
9
11
|
import TopicItem from './TopicItem';
|
|
10
12
|
|
|
11
13
|
export const Topic = () => {
|
|
12
|
-
const topics = useSessionStore(topicSelectors.currentTopics);
|
|
14
|
+
const topics = useSessionStore(topicSelectors.currentTopics, isEqual);
|
|
13
15
|
const { isDarkMode } = useThemeMode();
|
|
14
16
|
const [activeTopicId] = useSessionStore((s) => [s.activeTopicId], shallow);
|
|
15
17
|
const { t } = useTranslation('empty');
|
|
18
|
+
|
|
19
|
+
const [visible, updateGuideState] = useSettings(
|
|
20
|
+
(s) => [s.guide?.topic, s.updateGuideState],
|
|
21
|
+
shallow,
|
|
22
|
+
);
|
|
23
|
+
|
|
16
24
|
return (
|
|
17
25
|
<Flexbox gap={2}>
|
|
18
26
|
{topics?.length === 0 && (
|
|
19
27
|
<Empty
|
|
28
|
+
alt={t('topic.desc')}
|
|
20
29
|
cover={`/images/empty_topic_${isDarkMode ? 'dark' : 'light'}.webp`}
|
|
21
30
|
desc={t('topic.desc')}
|
|
31
|
+
height={120}
|
|
32
|
+
onVisibleChange={(visible) => {
|
|
33
|
+
updateGuideState({ topic: visible });
|
|
34
|
+
}}
|
|
22
35
|
style={{ marginBottom: 6 }}
|
|
23
36
|
title={t('topic.title')}
|
|
37
|
+
visible={visible}
|
|
38
|
+
width={200}
|
|
24
39
|
/>
|
|
25
40
|
)}
|
|
26
41
|
|
|
@@ -3,12 +3,15 @@ import { useEffect, useState } from 'react';
|
|
|
3
3
|
import { useSessionStore } from '@/store/session';
|
|
4
4
|
|
|
5
5
|
export const useSessionHydrated = () => {
|
|
6
|
-
|
|
6
|
+
// 根据 sessions 是否有值来判断是否已经初始化
|
|
7
|
+
const hasInited = !!Object.values(useSessionStore.getState().sessions).length;
|
|
8
|
+
|
|
9
|
+
const [isInit, setInit] = useState(hasInited);
|
|
7
10
|
|
|
8
11
|
useEffect(() => {
|
|
9
12
|
const hasRehydrated = useSessionStore.persist.hasHydrated();
|
|
10
13
|
|
|
11
|
-
if (hasRehydrated) {
|
|
14
|
+
if (hasRehydrated && !isInit) {
|
|
12
15
|
setInit(true);
|
|
13
16
|
}
|
|
14
17
|
}, []);
|
|
@@ -3,7 +3,13 @@ import type { GlobalSettings } from '@/types/settings';
|
|
|
3
3
|
|
|
4
4
|
export type SidebarTabKey = 'chat' | 'market' | 'settings';
|
|
5
5
|
|
|
6
|
+
export interface Guide {
|
|
7
|
+
// Topic 引导
|
|
8
|
+
topic?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
6
11
|
export interface AppSettingsState {
|
|
12
|
+
guide?: Guide;
|
|
7
13
|
inputHeight: number;
|
|
8
14
|
sessionExpandable?: boolean;
|
|
9
15
|
sessionsWidth: number;
|
|
@@ -13,6 +19,7 @@ export interface AppSettingsState {
|
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
export const initialState: AppSettingsState = {
|
|
22
|
+
guide: {},
|
|
16
23
|
inputHeight: 200,
|
|
17
24
|
sessionExpandable: true,
|
|
18
25
|
sessionsWidth: 320,
|
|
@@ -1,77 +1,37 @@
|
|
|
1
|
-
import { ThemeMode } from 'antd-style';
|
|
2
1
|
import { produce } from 'immer';
|
|
3
2
|
import { merge } from 'lodash-es';
|
|
4
3
|
import type { StateCreator } from 'zustand/vanilla';
|
|
5
4
|
|
|
6
|
-
import { DEFAULT_AGENT
|
|
5
|
+
import { DEFAULT_AGENT } from '@/const/settings';
|
|
7
6
|
import { MetaData } from '@/types/meta';
|
|
8
7
|
import type { LobeAgentSession } from '@/types/session';
|
|
9
8
|
import { LobeAgentConfig } from '@/types/session';
|
|
10
9
|
import type { GlobalSettings } from '@/types/settings';
|
|
11
10
|
import { setNamespace } from '@/utils/storeDebug';
|
|
12
11
|
|
|
13
|
-
import type {
|
|
14
|
-
import { AppSettingsState } from './initialState';
|
|
15
|
-
import type { SettingsStore } from './store';
|
|
12
|
+
import type { SettingsStore } from '../store';
|
|
16
13
|
|
|
17
14
|
const t = setNamespace('settings');
|
|
18
15
|
|
|
19
16
|
/**
|
|
20
17
|
* 设置操作
|
|
21
18
|
*/
|
|
22
|
-
export interface
|
|
23
|
-
importAppSettings: (settings: GlobalSettings) => void;
|
|
19
|
+
export interface AgentAction {
|
|
24
20
|
resetAgentConfig: () => void;
|
|
25
21
|
resetAgentMeta: () => void;
|
|
26
|
-
resetBaseSettings: () => void;
|
|
27
22
|
resetDefaultAgent: () => void;
|
|
28
|
-
/**
|
|
29
|
-
* 重置设置
|
|
30
|
-
*/
|
|
31
|
-
resetSettings: () => void;
|
|
32
23
|
setAgentConfig: (config: Partial<LobeAgentSession['config']>) => void;
|
|
33
24
|
setAgentMeta: (meta: Partial<LobeAgentSession['meta']>) => void;
|
|
34
|
-
/**
|
|
35
|
-
* 设置全局设置
|
|
36
|
-
* @param settings - 全局设置
|
|
37
|
-
*/
|
|
38
|
-
setAppSettings: (settings: AppSettingsState) => void;
|
|
39
|
-
/**
|
|
40
|
-
* 设置部分配置设置
|
|
41
|
-
* @param settings - 部分配置设置
|
|
42
|
-
*/
|
|
43
|
-
setSettings: (settings: Partial<GlobalSettings>) => void;
|
|
44
|
-
/**
|
|
45
|
-
* 设置主题模式
|
|
46
|
-
* @param themeMode - 主题模式
|
|
47
|
-
*/
|
|
48
|
-
setThemeMode: (themeMode: ThemeMode) => void;
|
|
49
|
-
/**
|
|
50
|
-
* 切换侧边栏选项
|
|
51
|
-
* @param key - 选中的侧边栏选项
|
|
52
|
-
*/
|
|
53
|
-
switchSideBar: (key: SidebarTabKey) => void;
|
|
54
25
|
toggleAgentPanel: (visible?: boolean) => void;
|
|
55
26
|
toggleAgentPlugin: (pluginId: string) => void;
|
|
56
27
|
}
|
|
57
28
|
|
|
58
|
-
export const
|
|
29
|
+
export const createAgentSlice: StateCreator<
|
|
59
30
|
SettingsStore,
|
|
60
31
|
[['zustand/devtools', never]],
|
|
61
32
|
[],
|
|
62
|
-
|
|
33
|
+
AgentAction
|
|
63
34
|
> = (set, get) => ({
|
|
64
|
-
importAppSettings: (importAppSettings) => {
|
|
65
|
-
const { setSettings } = get();
|
|
66
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
67
|
-
const { OPENAI_API_KEY: _, password: __, ...settings } = importAppSettings;
|
|
68
|
-
|
|
69
|
-
setSettings({
|
|
70
|
-
...settings,
|
|
71
|
-
// 如果用户存在用户头像,那么不做导入
|
|
72
|
-
avatar: !get().settings.avatar ? settings.avatar : get().settings.avatar,
|
|
73
|
-
});
|
|
74
|
-
},
|
|
75
35
|
resetAgentConfig: () => {
|
|
76
36
|
const settings = produce(get().settings, (draft: GlobalSettings) => {
|
|
77
37
|
draft.defaultAgent.config = DEFAULT_AGENT.config;
|
|
@@ -84,20 +44,12 @@ export const createSettings: StateCreator<
|
|
|
84
44
|
});
|
|
85
45
|
set({ settings }, false, t('resetAgentMeta'));
|
|
86
46
|
},
|
|
87
|
-
resetBaseSettings: () => {
|
|
88
|
-
const settings = get().settings;
|
|
89
|
-
|
|
90
|
-
set({ settings: { ...settings, ...DEFAULT_BASE_SETTINGS } }, false, t('resetBaseSettings'));
|
|
91
|
-
},
|
|
92
47
|
resetDefaultAgent: () => {
|
|
93
48
|
const settings = produce(get().settings, (draft: GlobalSettings) => {
|
|
94
49
|
draft.defaultAgent = DEFAULT_AGENT;
|
|
95
50
|
});
|
|
96
51
|
set({ settings }, false, t('resetDefaultAgent'));
|
|
97
52
|
},
|
|
98
|
-
resetSettings: () => {
|
|
99
|
-
set({ settings: DEFAULT_SETTINGS }, false, t('resetSettings'));
|
|
100
|
-
},
|
|
101
53
|
setAgentConfig: (config) => {
|
|
102
54
|
const settings = produce(get().settings, (draft: GlobalSettings) => {
|
|
103
55
|
const oldConfig = draft.defaultAgent.config as LobeAgentConfig;
|
|
@@ -114,19 +66,6 @@ export const createSettings: StateCreator<
|
|
|
114
66
|
|
|
115
67
|
set({ settings }, false, t('setAgentMeta', meta));
|
|
116
68
|
},
|
|
117
|
-
setAppSettings: (settings) => {
|
|
118
|
-
set({ ...settings }, false, t('setAppSettings', settings));
|
|
119
|
-
},
|
|
120
|
-
setSettings: (settings) => {
|
|
121
|
-
const oldSetting = get().settings;
|
|
122
|
-
set({ settings: merge(oldSetting, settings) }, false, t('setSettings', settings));
|
|
123
|
-
},
|
|
124
|
-
setThemeMode: (themeMode) => {
|
|
125
|
-
get().setSettings({ themeMode });
|
|
126
|
-
},
|
|
127
|
-
switchSideBar: (key) => {
|
|
128
|
-
set({ sidebarKey: key }, false, t('switchSideBar', key));
|
|
129
|
-
},
|
|
130
69
|
toggleAgentPanel: (newValue) => {
|
|
131
70
|
const showAgentConfig = typeof newValue === 'boolean' ? newValue : !get().showAgentConfig;
|
|
132
71
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ThemeMode } from 'antd-style';
|
|
2
|
+
import { produce } from 'immer';
|
|
3
|
+
import { merge } from 'lodash-es';
|
|
4
|
+
import type { StateCreator } from 'zustand/vanilla';
|
|
5
|
+
|
|
6
|
+
import { DEFAULT_AGENT, DEFAULT_BASE_SETTINGS, DEFAULT_SETTINGS } from '@/const/settings';
|
|
7
|
+
import type { GlobalSettings } from '@/types/settings';
|
|
8
|
+
import { setNamespace } from '@/utils/storeDebug';
|
|
9
|
+
|
|
10
|
+
import type { Guide, SidebarTabKey } from '../initialState';
|
|
11
|
+
import { AppSettingsState } from '../initialState';
|
|
12
|
+
import type { SettingsStore } from '../store';
|
|
13
|
+
|
|
14
|
+
const t = setNamespace('settings');
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 设置操作
|
|
18
|
+
*/
|
|
19
|
+
export interface CommonAction {
|
|
20
|
+
importAppSettings: (settings: GlobalSettings) => void;
|
|
21
|
+
resetBaseSettings: () => void;
|
|
22
|
+
/**
|
|
23
|
+
* 重置设置
|
|
24
|
+
*/
|
|
25
|
+
resetSettings: () => void;
|
|
26
|
+
/**
|
|
27
|
+
* 设置全局设置
|
|
28
|
+
* @param settings - 全局设置
|
|
29
|
+
*/
|
|
30
|
+
setAppSettings: (settings: AppSettingsState) => void;
|
|
31
|
+
/**
|
|
32
|
+
* 设置部分配置设置
|
|
33
|
+
* @param settings - 部分配置设置
|
|
34
|
+
*/
|
|
35
|
+
setSettings: (settings: Partial<GlobalSettings>) => void;
|
|
36
|
+
/**
|
|
37
|
+
* 设置主题模式
|
|
38
|
+
* @param themeMode - 主题模式
|
|
39
|
+
*/
|
|
40
|
+
setThemeMode: (themeMode: ThemeMode) => void;
|
|
41
|
+
/**
|
|
42
|
+
* 切换侧边栏选项
|
|
43
|
+
* @param key - 选中的侧边栏选项
|
|
44
|
+
*/
|
|
45
|
+
switchSideBar: (key: SidebarTabKey) => void;
|
|
46
|
+
updateGuideState: (guide: Partial<Guide>) => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const createCommonSlice: StateCreator<
|
|
50
|
+
SettingsStore,
|
|
51
|
+
[['zustand/devtools', never]],
|
|
52
|
+
[],
|
|
53
|
+
CommonAction
|
|
54
|
+
> = (set, get) => ({
|
|
55
|
+
importAppSettings: (importAppSettings) => {
|
|
56
|
+
const { setSettings } = get();
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
58
|
+
const { OPENAI_API_KEY: _, password: __, ...settings } = importAppSettings;
|
|
59
|
+
|
|
60
|
+
setSettings({
|
|
61
|
+
...settings,
|
|
62
|
+
// 如果用户存在用户头像,那么不做导入
|
|
63
|
+
avatar: !get().settings.avatar ? settings.avatar : get().settings.avatar,
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
resetBaseSettings: () => {
|
|
67
|
+
const settings = get().settings;
|
|
68
|
+
|
|
69
|
+
set({ settings: { ...settings, ...DEFAULT_BASE_SETTINGS } }, false, t('resetBaseSettings'));
|
|
70
|
+
},
|
|
71
|
+
resetDefaultAgent: () => {
|
|
72
|
+
const settings = produce(get().settings, (draft: GlobalSettings) => {
|
|
73
|
+
draft.defaultAgent = DEFAULT_AGENT;
|
|
74
|
+
});
|
|
75
|
+
set({ settings }, false, t('resetDefaultAgent'));
|
|
76
|
+
},
|
|
77
|
+
resetSettings: () => {
|
|
78
|
+
set({ settings: DEFAULT_SETTINGS }, false, t('resetSettings'));
|
|
79
|
+
},
|
|
80
|
+
setAppSettings: (settings) => {
|
|
81
|
+
set({ ...settings }, false, t('setAppSettings', settings));
|
|
82
|
+
},
|
|
83
|
+
setSettings: (settings) => {
|
|
84
|
+
const oldSetting = get().settings;
|
|
85
|
+
set({ settings: merge(oldSetting, settings) }, false, t('setSettings', settings));
|
|
86
|
+
},
|
|
87
|
+
setThemeMode: (themeMode) => {
|
|
88
|
+
get().setSettings({ themeMode });
|
|
89
|
+
},
|
|
90
|
+
switchSideBar: (key) => {
|
|
91
|
+
set({ sidebarKey: key }, false, t('switchSideBar', key));
|
|
92
|
+
},
|
|
93
|
+
updateGuideState: (guide) => {
|
|
94
|
+
set({ guide: { ...get().guide, ...guide } });
|
|
95
|
+
},
|
|
96
|
+
});
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { StateCreator } from 'zustand/vanilla';
|
|
2
2
|
|
|
3
|
-
import { type SettingsAction, createSettings } from './action';
|
|
4
3
|
import { type AppSettingsState, initialState } from './initialState';
|
|
4
|
+
import { type AgentAction, createAgentSlice } from './slices/agent';
|
|
5
|
+
import { type CommonAction, createCommonSlice } from './slices/common';
|
|
5
6
|
|
|
6
|
-
export type SettingsStore =
|
|
7
|
+
export type SettingsStore = CommonAction & AppSettingsState & AgentAction;
|
|
7
8
|
|
|
8
9
|
export const createStore: StateCreator<SettingsStore, [['zustand/devtools', never]]> = (
|
|
9
10
|
...parameters
|
|
10
11
|
) => ({
|
|
11
12
|
...initialState,
|
|
12
|
-
...
|
|
13
|
+
...createCommonSlice(...parameters),
|
|
14
|
+
...createAgentSlice(...parameters),
|
|
13
15
|
});
|