@lobehub/chat 0.41.0 → 0.41.2
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 +51 -0
- package/package.json +1 -1
- package/src/features/AvatarWithUpload/index.tsx +1 -2
- package/src/features/FolderPanel/index.tsx +4 -5
- package/src/features/SideBar/index.tsx +1 -2
- package/src/layout/index.tsx +6 -6
- package/src/pages/chat/SessionList/Header.tsx +2 -6
- package/src/pages/chat/SessionList/List/SessionItem.tsx +2 -2
- package/src/pages/chat/SessionList/List/index.tsx +1 -5
- package/src/pages/chat/[id]/Conversation/ChatList/Error/ApiKeyForm.tsx +1 -5
- package/src/pages/chat/[id]/Conversation/ChatList/Error/InvalidAccess.tsx +2 -6
- package/src/pages/chat/[id]/Conversation/ChatList/Error/OpenAiBizError.tsx +1 -5
- package/src/pages/chat/[id]/Conversation/ChatList/MessageExtra.tsx +1 -2
- package/src/pages/chat/[id]/Conversation/ChatList/index.tsx +9 -19
- package/src/pages/chat/[id]/Conversation/Input/Action.tsx +1 -2
- package/src/pages/chat/[id]/Conversation/Input/ActionRight.tsx +1 -2
- package/src/pages/chat/[id]/Conversation/Input/Token.tsx +6 -10
- package/src/pages/chat/[id]/Conversation/Input/index.tsx +6 -6
- package/src/pages/chat/[id]/Header/index.tsx +13 -17
- package/src/pages/chat/[id]/Sidebar/Inner.tsx +4 -5
- package/src/pages/chat/[id]/Sidebar/Topic/TopicContent.tsx +5 -5
- package/src/pages/chat/[id]/Sidebar/Topic/TopicItem.tsx +1 -2
- package/src/pages/chat/[id]/Sidebar/Topic/index.tsx +2 -6
- package/src/pages/chat/[id]/Sidebar/index.tsx +4 -5
- package/src/pages/chat/[id]/index.page.tsx +4 -5
- package/src/pages/chat/[id]/setting/index.page.tsx +7 -11
- package/src/pages/chat/layout.tsx +1 -2
- package/src/pages/settings/Settings/Agent.tsx +5 -5
- package/src/pages/settings/Settings/Common.tsx +5 -9
- package/src/pages/settings/ThemeSwatches/ThemeSwatchesNeutral.tsx +1 -5
- package/src/pages/settings/ThemeSwatches/ThemeSwatchesPrimary.tsx +1 -5
- package/src/store/session/store.ts +8 -2
- package/src/store/settings/hooks/useHydrated.ts +20 -0
- package/src/store/settings/index.ts +1 -25
- package/src/store/settings/store.ts +29 -1
package/.eslintrc.js
CHANGED
|
@@ -8,5 +8,6 @@ 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
10
|
config.rules['unicorn/explicit-length-check'] = 0;
|
|
11
|
+
config.rules['unicorn/prefer-code-point'] = 0;
|
|
11
12
|
|
|
12
13
|
module.exports = config;
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.41.2](https://github.com/lobehub/lobe-chat/compare/v0.41.1...v0.41.2)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-08-10**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: 将 sessionStore 默认 equalFn 改为 shallow, 将 settingStore 默认 equalFn 改为 shallow.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Code refactoring
|
|
19
|
+
|
|
20
|
+
- **misc**: 将 sessionStore 默认 equalFn 改为 shallow ([5c1b8d7](https://github.com/lobehub/lobe-chat/commit/5c1b8d7))
|
|
21
|
+
- **misc**: 将 settingStore 默认 equalFn 改为 shallow ([1e72308](https://github.com/lobehub/lobe-chat/commit/1e72308))
|
|
22
|
+
|
|
23
|
+
</details>
|
|
24
|
+
|
|
25
|
+
<div align="right">
|
|
26
|
+
|
|
27
|
+
[](#readme-top)
|
|
28
|
+
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
### [Version 0.41.1](https://github.com/lobehub/lobe-chat/compare/v0.41.0...v0.41.1)
|
|
32
|
+
|
|
33
|
+
<sup>Released on **2023-08-10**</sup>
|
|
34
|
+
|
|
35
|
+
#### ♻ Code Refactoring
|
|
36
|
+
|
|
37
|
+
- **misc**: 重构 settings store 代码写法.
|
|
38
|
+
|
|
39
|
+
<br/>
|
|
40
|
+
|
|
41
|
+
<details>
|
|
42
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
43
|
+
|
|
44
|
+
#### Code refactoring
|
|
45
|
+
|
|
46
|
+
- **misc**: 重构 settings store 代码写法 ([4b6f917](https://github.com/lobehub/lobe-chat/commit/4b6f917))
|
|
47
|
+
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
<div align="right">
|
|
51
|
+
|
|
52
|
+
[](#readme-top)
|
|
53
|
+
|
|
54
|
+
</div>
|
|
55
|
+
|
|
5
56
|
## [Version 0.41.0](https://github.com/lobehub/lobe-chat/compare/v0.40.7...v0.41.0)
|
|
6
57
|
|
|
7
58
|
<sup>Released on **2023-08-10**</sup>
|
package/package.json
CHANGED
|
@@ -2,7 +2,6 @@ import { Avatar, Logo } from '@lobehub/ui';
|
|
|
2
2
|
import { Upload } from 'antd';
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
4
|
import { memo } from 'react';
|
|
5
|
-
import { shallow } from 'zustand/shallow';
|
|
6
5
|
|
|
7
6
|
import { useSettings } from '@/store/settings';
|
|
8
7
|
import { createUploadImageHandler } from '@/utils/uploadFIle';
|
|
@@ -28,7 +27,7 @@ interface AvatarWithUploadProps {
|
|
|
28
27
|
}
|
|
29
28
|
|
|
30
29
|
const AvatarWithUpload = memo<AvatarWithUploadProps>(({ size = 40 }) => {
|
|
31
|
-
const [avatar, setSettings] = useSettings((st) => [st.settings.avatar, st.setSettings]
|
|
30
|
+
const [avatar, setSettings] = useSettings((st) => [st.settings.avatar, st.setSettings]);
|
|
32
31
|
const { styles } = useStyle();
|
|
33
32
|
|
|
34
33
|
const handleUploadAvatar = createUploadImageHandler((avatar) => {
|
|
@@ -2,7 +2,6 @@ import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
|
|
|
2
2
|
import { createStyles } from 'antd-style';
|
|
3
3
|
import isEqual from 'fast-deep-equal';
|
|
4
4
|
import { PropsWithChildren, memo, useState } from 'react';
|
|
5
|
-
import { shallow } from 'zustand/shallow';
|
|
6
5
|
|
|
7
6
|
import { FOLDER_WIDTH } from '@/const/layoutTokens';
|
|
8
7
|
import { useSettings } from '@/store/settings';
|
|
@@ -17,10 +16,10 @@ export const useStyles = createStyles(({ css, token }) => ({
|
|
|
17
16
|
|
|
18
17
|
const FolderPanel = memo<PropsWithChildren>(({ children }) => {
|
|
19
18
|
const { styles } = useStyles();
|
|
20
|
-
const [sessionsWidth, sessionExpandable] = useSettings(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
);
|
|
19
|
+
const [sessionsWidth, sessionExpandable] = useSettings((s) => [
|
|
20
|
+
s.sessionsWidth,
|
|
21
|
+
s.sessionExpandable,
|
|
22
|
+
]);
|
|
24
23
|
const [tmpWidth, setWidth] = useState(sessionsWidth);
|
|
25
24
|
if (tmpWidth !== sessionsWidth) setWidth(sessionsWidth);
|
|
26
25
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SideNav } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
|
-
import { shallow } from 'zustand/shallow';
|
|
4
3
|
|
|
5
4
|
import AvatarWithUpload from '@/features/AvatarWithUpload';
|
|
6
5
|
import { useSettings } from '@/store/settings';
|
|
@@ -9,7 +8,7 @@ import BottomActions from './BottomActions';
|
|
|
9
8
|
import TopActions from './TopActions';
|
|
10
9
|
|
|
11
10
|
export default memo(() => {
|
|
12
|
-
const [tab, setTab] = useSettings((s) => [s.sidebarKey, s.switchSideBar]
|
|
11
|
+
const [tab, setTab] = useSettings((s) => [s.sidebarKey, s.switchSideBar]);
|
|
13
12
|
|
|
14
13
|
return (
|
|
15
14
|
<SideNav
|
package/src/layout/index.tsx
CHANGED
|
@@ -4,7 +4,6 @@ import { useThemeMode } from 'antd-style';
|
|
|
4
4
|
import 'antd/dist/reset.css';
|
|
5
5
|
import Zh_CN from 'antd/locale/zh_CN';
|
|
6
6
|
import { PropsWithChildren, useCallback, useEffect } from 'react';
|
|
7
|
-
import { shallow } from 'zustand/shallow';
|
|
8
7
|
|
|
9
8
|
import { useSessionStore } from '@/store/session';
|
|
10
9
|
import { useSettings } from '@/store/settings';
|
|
@@ -29,11 +28,12 @@ const Layout = ({ children }: PropsWithChildren) => {
|
|
|
29
28
|
};
|
|
30
29
|
|
|
31
30
|
export default ({ children }: PropsWithChildren) => {
|
|
32
|
-
const themeMode = useSettings((s) => s.settings.themeMode
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
);
|
|
31
|
+
const themeMode = useSettings((s) => s.settings.themeMode);
|
|
32
|
+
const [primaryColor, neutralColor] = useSettings((s) => [
|
|
33
|
+
s.settings.primaryColor,
|
|
34
|
+
s.settings.neutralColor,
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
37
|
const { browserPrefers } = useThemeMode();
|
|
38
38
|
const isDarkMode = themeMode === 'auto' ? browserPrefers === 'dark' : themeMode === 'dark';
|
|
39
39
|
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { ActionIcon, Logo, SearchBar } from '@lobehub/ui';
|
|
2
2
|
import { createStyles } from 'antd-style';
|
|
3
3
|
import { MessageSquarePlus } from 'lucide-react';
|
|
4
|
-
import { useTranslation } from 'react-i18next';
|
|
5
4
|
import Link from 'next/link';
|
|
6
5
|
import { memo } from 'react';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
|
8
|
-
import { shallow } from 'zustand/shallow';
|
|
9
8
|
|
|
10
9
|
import { useSessionStore } from '@/store/session';
|
|
11
10
|
|
|
@@ -22,10 +21,7 @@ export const useStyles = createStyles(({ css, token }) => ({
|
|
|
22
21
|
const Header = memo(() => {
|
|
23
22
|
const { styles } = useStyles();
|
|
24
23
|
const { t } = useTranslation('common');
|
|
25
|
-
const [keywords, createSession] = useSessionStore(
|
|
26
|
-
(s) => [s.searchKeywords, s.createSession],
|
|
27
|
-
shallow,
|
|
28
|
-
);
|
|
24
|
+
const [keywords, createSession] = useSessionStore((s) => [s.searchKeywords, s.createSession]);
|
|
29
25
|
|
|
30
26
|
return (
|
|
31
27
|
<Flexbox className={styles.top} gap={16} padding={16}>
|
|
@@ -29,7 +29,7 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading })
|
|
|
29
29
|
const { t } = useTranslation('common');
|
|
30
30
|
|
|
31
31
|
const { styles } = useStyles();
|
|
32
|
-
const [defaultModel] = useSettings((s) => [s.settings.defaultAgent.config?.model]
|
|
32
|
+
const [defaultModel] = useSettings((s) => [s.settings.defaultAgent.config?.model]);
|
|
33
33
|
|
|
34
34
|
const [
|
|
35
35
|
pin,
|
|
@@ -60,7 +60,7 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading })
|
|
|
60
60
|
s.removeSession,
|
|
61
61
|
s.pinSession,
|
|
62
62
|
];
|
|
63
|
-
}
|
|
63
|
+
});
|
|
64
64
|
|
|
65
65
|
const { modal } = App.useApp();
|
|
66
66
|
const items: MenuProps['items'] = useMemo(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import isEqual from 'fast-deep-equal';
|
|
2
2
|
import Link from 'next/link';
|
|
3
3
|
import { memo } from 'react';
|
|
4
|
-
import { shallow } from 'zustand/shallow';
|
|
5
4
|
|
|
6
5
|
import { sessionSelectors, useSessionHydrated, useSessionStore } from '@/store/session';
|
|
7
6
|
|
|
@@ -10,10 +9,7 @@ import SkeletonItem from './SkeletonItem';
|
|
|
10
9
|
|
|
11
10
|
const SessionList = memo(() => {
|
|
12
11
|
const list = useSessionStore((s) => sessionSelectors.sessionList(s), isEqual);
|
|
13
|
-
const [activeId, loading] = useSessionStore(
|
|
14
|
-
(s) => [s.activeId, s.autocompleteLoading.title],
|
|
15
|
-
shallow,
|
|
16
|
-
);
|
|
12
|
+
const [activeId, loading] = useSessionStore((s) => [s.activeId, s.autocompleteLoading.title]);
|
|
17
13
|
|
|
18
14
|
const isInit = useSessionHydrated();
|
|
19
15
|
|
|
@@ -3,7 +3,6 @@ import { Button, Input } from 'antd';
|
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { Center, Flexbox } from 'react-layout-kit';
|
|
6
|
-
import { shallow } from 'zustand/shallow';
|
|
7
6
|
|
|
8
7
|
import { useSettings } from '@/store/settings';
|
|
9
8
|
|
|
@@ -12,10 +11,7 @@ import { useStyles } from './style';
|
|
|
12
11
|
const APIKeyForm = memo<{ onConfirm?: () => void }>(({ onConfirm }) => {
|
|
13
12
|
const { t } = useTranslation('error');
|
|
14
13
|
const { styles, theme } = useStyles();
|
|
15
|
-
const [apiKey, setSettings] = useSettings(
|
|
16
|
-
(s) => [s.settings.OPENAI_API_KEY, s.setSettings],
|
|
17
|
-
shallow,
|
|
18
|
-
);
|
|
14
|
+
const [apiKey, setSettings] = useSettings((s) => [s.settings.OPENAI_API_KEY, s.setSettings]);
|
|
19
15
|
|
|
20
16
|
return (
|
|
21
17
|
<Center gap={16} style={{ maxWidth: 300 }}>
|
|
@@ -4,7 +4,6 @@ import { KeySquare, SquareAsterisk } from 'lucide-react';
|
|
|
4
4
|
import { memo, useState } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { Flexbox } from 'react-layout-kit';
|
|
7
|
-
import { shallow } from 'zustand/shallow';
|
|
8
7
|
|
|
9
8
|
import { useSessionStore } from '@/store/session';
|
|
10
9
|
import { useSettings } from '@/store/settings';
|
|
@@ -16,11 +15,8 @@ import { ErrorActionContainer, FormAction } from './style';
|
|
|
16
15
|
const InvalidAccess = memo<{ id: string }>(({ id }) => {
|
|
17
16
|
const { t } = useTranslation('error');
|
|
18
17
|
const [mode, setMode] = useState('password');
|
|
19
|
-
const [password, setSettings] = useSettings((s) => [s.settings.password, s.setSettings]
|
|
20
|
-
const [resend, deleteMessage] = useSessionStore(
|
|
21
|
-
(s) => [s.resendMessage, s.deleteMessage],
|
|
22
|
-
shallow,
|
|
23
|
-
);
|
|
18
|
+
const [password, setSettings] = useSettings((s) => [s.settings.password, s.setSettings]);
|
|
19
|
+
const [resend, deleteMessage] = useSessionStore((s) => [s.resendMessage, s.deleteMessage]);
|
|
24
20
|
|
|
25
21
|
return (
|
|
26
22
|
<ErrorActionContainer>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Highlighter } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
|
-
import { shallow } from 'zustand/shallow';
|
|
5
4
|
|
|
6
5
|
import { useSessionStore } from '@/store/session';
|
|
7
6
|
|
|
@@ -22,10 +21,7 @@ interface OpenAIErrorResponse {
|
|
|
22
21
|
const OpenAiBizError = memo<{ content: OpenAIErrorResponse; id: string }>(({ content, id }) => {
|
|
23
22
|
const { styles } = useStyles();
|
|
24
23
|
|
|
25
|
-
const [resend, deleteMessage] = useSessionStore(
|
|
26
|
-
(s) => [s.resendMessage, s.deleteMessage],
|
|
27
|
-
shallow,
|
|
28
|
-
);
|
|
24
|
+
const [resend, deleteMessage] = useSessionStore((s) => [s.resendMessage, s.deleteMessage]);
|
|
29
25
|
|
|
30
26
|
const errorCode = content.error?.code;
|
|
31
27
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createStyles } from 'antd-style';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
|
-
import { shallow } from 'zustand/shallow';
|
|
5
4
|
|
|
6
5
|
import Tag from '@/components/Tag';
|
|
7
6
|
import { agentSelectors, useSessionStore } from '@/store/session';
|
|
@@ -28,7 +27,7 @@ const MessageExtra = ({
|
|
|
28
27
|
const { styles } = useStyles();
|
|
29
28
|
|
|
30
29
|
// const { t } = useTranslation();
|
|
31
|
-
const [model] = useSessionStore((s) => [agentSelectors.currentAgentModel(s)]
|
|
30
|
+
const [model] = useSessionStore((s) => [agentSelectors.currentAgentModel(s)]);
|
|
32
31
|
|
|
33
32
|
// const plugin = PluginsMap[name || ''];
|
|
34
33
|
|
|
@@ -3,14 +3,8 @@ import isEqual from 'fast-deep-equal';
|
|
|
3
3
|
import { memo, useCallback } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
|
-
import { shallow } from 'zustand/shallow';
|
|
7
6
|
|
|
8
|
-
import {
|
|
9
|
-
agentSelectors,
|
|
10
|
-
chatSelectors,
|
|
11
|
-
useSessionHydrated,
|
|
12
|
-
useSessionStore,
|
|
13
|
-
} from '@/store/session';
|
|
7
|
+
import { agentSelectors, chatSelectors, useSessionStore } from '@/store/session';
|
|
14
8
|
import { ChatMessage } from '@/types/chatMessage';
|
|
15
9
|
import { ErrorType } from '@/types/fetch';
|
|
16
10
|
import { isFunctionMessage } from '@/utils/message';
|
|
@@ -34,20 +28,16 @@ const renderErrorMessage: RenderErrorMessage = (error, message) => {
|
|
|
34
28
|
|
|
35
29
|
const List = () => {
|
|
36
30
|
const { t } = useTranslation('common');
|
|
37
|
-
|
|
31
|
+
|
|
38
32
|
const data = useSessionStore(chatSelectors.currentChats, isEqual);
|
|
39
|
-
console.log(hydrated, data);
|
|
40
33
|
const [displayMode, chatLoadingId, deleteMessage, resendMessage, dispatchMessage] =
|
|
41
|
-
useSessionStore(
|
|
42
|
-
(s)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
],
|
|
49
|
-
shallow,
|
|
50
|
-
);
|
|
34
|
+
useSessionStore((s) => [
|
|
35
|
+
agentSelectors.currentAgentConfig(s).displayMode,
|
|
36
|
+
s.chatLoadingId,
|
|
37
|
+
s.deleteMessage,
|
|
38
|
+
s.resendMessage,
|
|
39
|
+
s.dispatchMessage,
|
|
40
|
+
]);
|
|
51
41
|
|
|
52
42
|
const renderMessage: RenderMessage = useCallback(
|
|
53
43
|
(content, message: ChatMessage) => {
|
|
@@ -4,7 +4,6 @@ import { BrainCog, Thermometer, Timer, TimerOff } from 'lucide-react';
|
|
|
4
4
|
import { memo } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { Flexbox } from 'react-layout-kit';
|
|
7
|
-
import { shallow } from 'zustand/shallow';
|
|
8
7
|
|
|
9
8
|
import SliderWithInput from '@/components/SliderWithInput';
|
|
10
9
|
import { agentSelectors, useSessionStore } from '@/store/session';
|
|
@@ -22,7 +21,7 @@ const InputActions = memo(() => {
|
|
|
22
21
|
!config.enableHistoryCount,
|
|
23
22
|
s.updateAgentConfig,
|
|
24
23
|
];
|
|
25
|
-
}
|
|
24
|
+
});
|
|
26
25
|
|
|
27
26
|
return (
|
|
28
27
|
<>
|
|
@@ -3,13 +3,12 @@ import { Popconfirm } from 'antd';
|
|
|
3
3
|
import { Eraser } from 'lucide-react';
|
|
4
4
|
import { memo } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
-
import { shallow } from 'zustand/shallow';
|
|
7
6
|
|
|
8
7
|
import { useSessionStore } from '@/store/session';
|
|
9
8
|
|
|
10
9
|
const ActionsRight = memo(() => {
|
|
11
10
|
const { t } = useTranslation('setting');
|
|
12
|
-
const [clearMessage] = useSessionStore((s) => [s.clearMessage, s.updateAgentConfig]
|
|
11
|
+
const [clearMessage] = useSessionStore((s) => [s.clearMessage, s.updateAgentConfig]);
|
|
13
12
|
|
|
14
13
|
return (
|
|
15
14
|
<Popconfirm
|
|
@@ -2,7 +2,6 @@ import { TokenTag, Tooltip } from '@lobehub/ui';
|
|
|
2
2
|
import { encode } from 'gpt-tokenizer';
|
|
3
3
|
import { memo, useMemo } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
-
import { shallow } from 'zustand/shallow';
|
|
6
5
|
|
|
7
6
|
import { ModelTokens } from '@/const/modelTokens';
|
|
8
7
|
import { agentSelectors, chatSelectors, useSessionStore } from '@/store/session';
|
|
@@ -12,15 +11,12 @@ const Token = memo<{ input: string }>(({ input }) => {
|
|
|
12
11
|
|
|
13
12
|
const inputTokenCount = useMemo(() => encode(input).length, [input]);
|
|
14
13
|
|
|
15
|
-
const [totalToken, systemRoleToken, chatsToken, model] = useSessionStore(
|
|
16
|
-
(s)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
],
|
|
22
|
-
shallow,
|
|
23
|
-
);
|
|
14
|
+
const [totalToken, systemRoleToken, chatsToken, model] = useSessionStore((s) => [
|
|
15
|
+
chatSelectors.totalTokenCount(s),
|
|
16
|
+
chatSelectors.systemRoleTokenCount(s),
|
|
17
|
+
chatSelectors.chatsTokenCount(s),
|
|
18
|
+
agentSelectors.currentAgentModel(s),
|
|
19
|
+
]);
|
|
24
20
|
|
|
25
21
|
return (
|
|
26
22
|
<Tooltip placement={'bottom'} title={t('tokenDetail', { chatsToken, systemRoleToken })}>
|
|
@@ -3,7 +3,6 @@ import { Button } from 'antd';
|
|
|
3
3
|
import { LucideGalleryVerticalEnd } from 'lucide-react';
|
|
4
4
|
import { memo, useState } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
-
import { shallow } from 'zustand/shallow';
|
|
7
6
|
|
|
8
7
|
import { CHAT_TEXTAREA_HEIGHT, HEADER_HEIGHT } from '@/const/layoutTokens';
|
|
9
8
|
import { useSessionStore } from '@/store/session';
|
|
@@ -18,11 +17,12 @@ const ChatInput = () => {
|
|
|
18
17
|
const [expand, setExpand] = useState<boolean>(false);
|
|
19
18
|
const [text, setText] = useState('');
|
|
20
19
|
|
|
21
|
-
const [inputHeight] = useSettings((s) => [s.inputHeight]
|
|
22
|
-
const [sendMessage, hasTopic, saveToTopic] = useSessionStore(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
const [inputHeight] = useSettings((s) => [s.inputHeight]);
|
|
21
|
+
const [sendMessage, hasTopic, saveToTopic] = useSessionStore((s) => [
|
|
22
|
+
s.createOrSendMsg,
|
|
23
|
+
!!s.activeTopicId,
|
|
24
|
+
s.saveToTopic,
|
|
25
|
+
]);
|
|
26
26
|
|
|
27
27
|
const footer = hasTopic ? null : (
|
|
28
28
|
<Tooltip title={t('topic.saveCurrentMessages')}>
|
|
@@ -6,7 +6,6 @@ import Router from 'next/router';
|
|
|
6
6
|
import { memo } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import { Flexbox } from 'react-layout-kit';
|
|
9
|
-
import { shallow } from 'zustand/shallow';
|
|
10
9
|
|
|
11
10
|
import HeaderTitle from '@/components/HeaderTitle';
|
|
12
11
|
import Tag from '@/components/Tag';
|
|
@@ -19,23 +18,20 @@ const Header = memo(() => {
|
|
|
19
18
|
const init = useSessionHydrated();
|
|
20
19
|
const { t } = useTranslation('common');
|
|
21
20
|
|
|
22
|
-
const [title, description, avatar, backgroundColor, id, model, plugins] = useSessionStore(
|
|
23
|
-
(s)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
],
|
|
32
|
-
shallow,
|
|
33
|
-
);
|
|
21
|
+
const [title, description, avatar, backgroundColor, id, model, plugins] = useSessionStore((s) => [
|
|
22
|
+
agentSelectors.currentAgentTitle(s),
|
|
23
|
+
agentSelectors.currentAgentDescription(s),
|
|
24
|
+
agentSelectors.currentAgentAvatar(s),
|
|
25
|
+
agentSelectors.currentAgentBackgroundColor(s),
|
|
26
|
+
s.activeId,
|
|
27
|
+
agentSelectors.currentAgentModel(s),
|
|
28
|
+
agentSelectors.currentAgentPlugins(s),
|
|
29
|
+
]);
|
|
34
30
|
|
|
35
|
-
const [showAgentSettings, toggleConfig] = useSettings(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
);
|
|
31
|
+
const [showAgentSettings, toggleConfig] = useSettings((s) => [
|
|
32
|
+
s.showAgentConfig,
|
|
33
|
+
s.toggleAgentPanel,
|
|
34
|
+
]);
|
|
39
35
|
|
|
40
36
|
return (
|
|
41
37
|
<ChatHeader
|
|
@@ -5,7 +5,6 @@ import { Maximize2Icon } from 'lucide-react';
|
|
|
5
5
|
import { memo, useState } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
|
8
|
-
import { shallow } from 'zustand/shallow';
|
|
9
8
|
|
|
10
9
|
import { agentSelectors, useSessionHydrated, useSessionStore } from '@/store/session';
|
|
11
10
|
|
|
@@ -41,10 +40,10 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
|
41
40
|
const Inner = memo(() => {
|
|
42
41
|
const [openModal, setOpenModal] = useState(false);
|
|
43
42
|
const { styles } = useStyles();
|
|
44
|
-
const [systemRole, updateAgentConfig] = useSessionStore(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
);
|
|
43
|
+
const [systemRole, updateAgentConfig] = useSessionStore((s) => [
|
|
44
|
+
agentSelectors.currentAgentSystemRole(s),
|
|
45
|
+
s.updateAgentConfig,
|
|
46
|
+
]);
|
|
48
47
|
|
|
49
48
|
const hydrated = useSessionHydrated();
|
|
50
49
|
const { t } = useTranslation('common');
|
|
@@ -5,7 +5,6 @@ import { MoreVertical, PencilLine, Star, Trash } from 'lucide-react';
|
|
|
5
5
|
import { memo, useMemo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
|
8
|
-
import { shallow } from 'zustand/shallow';
|
|
9
8
|
|
|
10
9
|
import { useSessionStore } from '@/store/session';
|
|
11
10
|
|
|
@@ -33,10 +32,11 @@ interface TopicContentProps {
|
|
|
33
32
|
const TopicContent = memo<TopicContentProps>(({ id, title, fav }) => {
|
|
34
33
|
const { t } = useTranslation('common');
|
|
35
34
|
|
|
36
|
-
const [editing, dispatchTopic, removeTopic] = useSessionStore(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
const [editing, dispatchTopic, removeTopic] = useSessionStore((s) => [
|
|
36
|
+
s.renameTopicId === id,
|
|
37
|
+
s.dispatchTopic,
|
|
38
|
+
s.removeTopic,
|
|
39
|
+
]);
|
|
40
40
|
const { styles, theme } = useStyles();
|
|
41
41
|
|
|
42
42
|
const toggleEditing = (visible?: boolean) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createStyles } from 'antd-style';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
|
-
import { shallow } from 'zustand/shallow';
|
|
5
4
|
|
|
6
5
|
import { useSessionStore } from '@/store/session';
|
|
7
6
|
|
|
@@ -50,7 +49,7 @@ export interface ConfigCellProps {
|
|
|
50
49
|
const TopicItem = memo<ConfigCellProps>(({ title, active, id, fav }) => {
|
|
51
50
|
const { styles, cx } = useStyles();
|
|
52
51
|
|
|
53
|
-
const [toggleTopic] = useSessionStore((s) => [s.toggleTopic]
|
|
52
|
+
const [toggleTopic] = useSessionStore((s) => [s.toggleTopic]);
|
|
54
53
|
|
|
55
54
|
return (
|
|
56
55
|
<Flexbox
|
|
@@ -2,7 +2,6 @@ import { useThemeMode } from 'antd-style';
|
|
|
2
2
|
import isEqual from 'fast-deep-equal';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
|
5
|
-
import { shallow } from 'zustand/shallow';
|
|
6
5
|
|
|
7
6
|
import Empty from '@/components/Empty';
|
|
8
7
|
import { topicSelectors, useSessionStore } from '@/store/session';
|
|
@@ -13,13 +12,10 @@ import TopicItem from './TopicItem';
|
|
|
13
12
|
export const Topic = () => {
|
|
14
13
|
const topics = useSessionStore(topicSelectors.currentTopics, isEqual);
|
|
15
14
|
const { isDarkMode } = useThemeMode();
|
|
16
|
-
const [activeTopicId] = useSessionStore((s) => [s.activeTopicId]
|
|
15
|
+
const [activeTopicId] = useSessionStore((s) => [s.activeTopicId]);
|
|
17
16
|
const { t } = useTranslation('empty');
|
|
18
17
|
|
|
19
|
-
const [visible, updateGuideState] = useSettings(
|
|
20
|
-
(s) => [s.guide?.topic, s.updateGuideState],
|
|
21
|
-
shallow,
|
|
22
|
-
);
|
|
18
|
+
const [visible, updateGuideState] = useSettings((s) => [s.guide?.topic, s.updateGuideState]);
|
|
23
19
|
|
|
24
20
|
return (
|
|
25
21
|
<Flexbox gap={2}>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
|
|
2
2
|
import { createStyles } from 'antd-style';
|
|
3
3
|
import { rgba } from 'polished';
|
|
4
|
-
import { shallow } from 'zustand/shallow';
|
|
5
4
|
|
|
6
5
|
import HeaderSpacing from '@/components/HeaderSpacing';
|
|
7
6
|
import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
|
|
@@ -23,10 +22,10 @@ const useStyles = createStyles(({ cx, css, token, stylish }) => ({
|
|
|
23
22
|
|
|
24
23
|
const Config = () => {
|
|
25
24
|
const { styles } = useStyles();
|
|
26
|
-
const [showAgentSettings, toggleConfig] = useSettings(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
);
|
|
25
|
+
const [showAgentSettings, toggleConfig] = useSettings((s) => [
|
|
26
|
+
s.showAgentConfig,
|
|
27
|
+
s.toggleAgentPanel,
|
|
28
|
+
]);
|
|
30
29
|
|
|
31
30
|
return (
|
|
32
31
|
<DraggablePanel
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import isEqual from 'fast-deep-equal';
|
|
2
1
|
import Head from 'next/head';
|
|
3
2
|
import { memo } from 'react';
|
|
4
3
|
import { Flexbox } from 'react-layout-kit';
|
|
@@ -12,10 +11,10 @@ import Header from './Header';
|
|
|
12
11
|
import Config from './Sidebar';
|
|
13
12
|
|
|
14
13
|
const Chat = memo(() => {
|
|
15
|
-
const [avatar, title] = useSessionStore(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
);
|
|
14
|
+
const [avatar, title] = useSessionStore((s) => [
|
|
15
|
+
agentSelectors.currentAgentAvatar(s),
|
|
16
|
+
agentSelectors.currentAgentTitle(s),
|
|
17
|
+
]);
|
|
19
18
|
|
|
20
19
|
const pageTitle = genSiteHeadTitle([avatar, title].filter(Boolean).join(' '));
|
|
21
20
|
|
|
@@ -3,7 +3,6 @@ import Head from 'next/head';
|
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
|
-
import { shallow } from 'zustand/shallow';
|
|
7
6
|
|
|
8
7
|
import HeaderSpacing from '@/components/HeaderSpacing';
|
|
9
8
|
import { HEADER_HEIGHT } from '@/const/layoutTokens';
|
|
@@ -18,16 +17,13 @@ const EditPage = memo(() => {
|
|
|
18
17
|
const { t } = useTranslation('setting');
|
|
19
18
|
const config = useSessionStore(agentSelectors.currentAgentConfig, isEqual);
|
|
20
19
|
const meta = useSessionStore(agentSelectors.currentAgentMeta, isEqual);
|
|
21
|
-
const autocomplete = useSessionStore(agentSelectors.currentAutocomplete
|
|
22
|
-
const [updateAgentConfig, toggleAgentPlugin, updateAgentMeta, title] = useSessionStore(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
],
|
|
29
|
-
shallow,
|
|
30
|
-
);
|
|
20
|
+
const autocomplete = useSessionStore(agentSelectors.currentAutocomplete);
|
|
21
|
+
const [updateAgentConfig, toggleAgentPlugin, updateAgentMeta, title] = useSessionStore((s) => [
|
|
22
|
+
s.updateAgentConfig,
|
|
23
|
+
s.toggleAgentPlugin,
|
|
24
|
+
s.updateAgentMeta,
|
|
25
|
+
agentSelectors.currentAgentTitle(s),
|
|
26
|
+
]);
|
|
31
27
|
|
|
32
28
|
const pageTitle = genSiteHeadTitle(t('header.sessionWithName', { name: title }));
|
|
33
29
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useRouter } from 'next/router';
|
|
2
2
|
import { PropsWithChildren, memo, useEffect } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
|
-
import { shallow } from 'zustand/shallow';
|
|
5
4
|
|
|
6
5
|
import SideBar from '@/features/SideBar';
|
|
7
6
|
import { createI18nNext } from '@/locales/create';
|
|
@@ -19,7 +18,7 @@ const ChatLayout = memo<PropsWithChildren>(({ children }) => {
|
|
|
19
18
|
|
|
20
19
|
const [activeSession, toggleTopic] = useSessionStore((s) => {
|
|
21
20
|
return [s.activeSession, s.toggleTopic];
|
|
22
|
-
}
|
|
21
|
+
});
|
|
23
22
|
|
|
24
23
|
const router = useRouter();
|
|
25
24
|
const { id } = router.query;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import isEqual from 'fast-deep-equal';
|
|
2
2
|
import { memo } from 'react';
|
|
3
|
-
import { shallow } from 'zustand/shallow';
|
|
4
3
|
|
|
5
4
|
import { AgentConfig, AgentMeta, AgentPlugin, AgentPrompt } from '@/features/AgentSetting';
|
|
6
5
|
import { settingsSelectors, useSettings } from '@/store/settings';
|
|
@@ -8,10 +7,11 @@ import { settingsSelectors, useSettings } from '@/store/settings';
|
|
|
8
7
|
const Agent = memo(() => {
|
|
9
8
|
const config = useSettings(settingsSelectors.currentAgentConfig, isEqual);
|
|
10
9
|
const meta = useSettings(settingsSelectors.currentAgentMeta, isEqual);
|
|
11
|
-
const [setAgentConfig, setAgentMeta, toggleAgentPlugin] = useSettings(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
const [setAgentConfig, setAgentMeta, toggleAgentPlugin] = useSettings((s) => [
|
|
11
|
+
s.setAgentConfig,
|
|
12
|
+
s.setAgentMeta,
|
|
13
|
+
s.toggleAgentPlugin,
|
|
14
|
+
]);
|
|
15
15
|
return (
|
|
16
16
|
<>
|
|
17
17
|
<AgentPrompt config={config} updateConfig={setAgentConfig} />
|
|
@@ -6,7 +6,6 @@ import { AppWindow, Palette, Webhook } from 'lucide-react';
|
|
|
6
6
|
import { memo, useCallback, useMemo } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import SliderWithInput from 'src/components/SliderWithInput';
|
|
9
|
-
import { shallow } from 'zustand/shallow';
|
|
10
9
|
|
|
11
10
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
12
11
|
import { DEFAULT_SETTINGS } from '@/const/settings';
|
|
@@ -29,14 +28,11 @@ const Common = memo(() => {
|
|
|
29
28
|
const [form] = AntForm.useForm();
|
|
30
29
|
const clearSessions = useSessionStore((s) => s.clearSessions);
|
|
31
30
|
const settings = useSettings(settingsSelectors.currentSettings, isEqual);
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}),
|
|
38
|
-
shallow,
|
|
39
|
-
);
|
|
31
|
+
const [setThemeMode, setSettings, resetSettings] = useSettings((s) => [
|
|
32
|
+
s.setThemeMode,
|
|
33
|
+
s.setSettings,
|
|
34
|
+
s.resetSettings,
|
|
35
|
+
]);
|
|
40
36
|
|
|
41
37
|
const { message, modal } = App.useApp();
|
|
42
38
|
const handleReset = useCallback(() => {
|
|
@@ -6,15 +6,11 @@ import {
|
|
|
6
6
|
neutralColorsSwatches,
|
|
7
7
|
} from '@lobehub/ui';
|
|
8
8
|
import { memo } from 'react';
|
|
9
|
-
import { shallow } from 'zustand/shallow';
|
|
10
9
|
|
|
11
10
|
import { useSettings } from '@/store/settings';
|
|
12
11
|
|
|
13
12
|
const ThemeSwatchesNeutral = memo(() => {
|
|
14
|
-
const
|
|
15
|
-
(s) => ({ neutralColor: s.settings.neutralColor, setSettings: s.setSettings }),
|
|
16
|
-
shallow,
|
|
17
|
-
);
|
|
13
|
+
const [neutralColor, setSettings] = useSettings((s) => [s.settings.neutralColor, s.setSettings]);
|
|
18
14
|
|
|
19
15
|
const handleSelect = (v: any) => {
|
|
20
16
|
const name = findCustomThemeName('neutral', v) as NeutralColors;
|
|
@@ -6,15 +6,11 @@ import {
|
|
|
6
6
|
primaryColorsSwatches,
|
|
7
7
|
} from '@lobehub/ui';
|
|
8
8
|
import { memo } from 'react';
|
|
9
|
-
import { shallow } from 'zustand/shallow';
|
|
10
9
|
|
|
11
10
|
import { useSettings } from '@/store/settings';
|
|
12
11
|
|
|
13
12
|
const ThemeSwatchesPrimary = memo(() => {
|
|
14
|
-
const
|
|
15
|
-
(s) => ({ primaryColor: s.settings.primaryColor, setSettings: s.setSettings }),
|
|
16
|
-
shallow,
|
|
17
|
-
);
|
|
13
|
+
const [primaryColor, setSettings] = useSettings((s) => [s.settings.primaryColor, s.setSettings]);
|
|
18
14
|
|
|
19
15
|
const handleSelect = (v: any) => {
|
|
20
16
|
const name = findCustomThemeName('primary', v) as PrimaryColors;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import equal from 'fast-deep-equal';
|
|
2
1
|
import { PersistOptions, devtools, persist } from 'zustand/middleware';
|
|
2
|
+
import { shallow } from 'zustand/shallow';
|
|
3
3
|
import { createWithEqualityFn } from 'zustand/traditional';
|
|
4
4
|
import { StateCreator } from 'zustand/vanilla';
|
|
5
5
|
|
|
@@ -10,6 +10,8 @@ import { AgentAction, createAgentSlice } from './slices/agentConfig';
|
|
|
10
10
|
import { ChatAction, createChatSlice } from './slices/chat';
|
|
11
11
|
import { SessionAction, createSessionSlice } from './slices/session';
|
|
12
12
|
|
|
13
|
+
// =============== 聚合 createStoreFn ============ //
|
|
14
|
+
|
|
13
15
|
export type SessionStore = SessionAction & AgentAction & ChatAction & SessionStoreState;
|
|
14
16
|
|
|
15
17
|
const createStore: StateCreator<SessionStore, [['zustand/devtools', never]]> = (...parameters) => ({
|
|
@@ -19,6 +21,8 @@ const createStore: StateCreator<SessionStore, [['zustand/devtools', never]]> = (
|
|
|
19
21
|
...createChatSlice(...parameters),
|
|
20
22
|
});
|
|
21
23
|
|
|
24
|
+
// =============== persist 本地缓存中间件配置 ============ //
|
|
25
|
+
|
|
22
26
|
type SessionPersist = Pick<SessionStore, 'sessions'>;
|
|
23
27
|
|
|
24
28
|
const LOBE_CHAT = 'LOBE_CHAT';
|
|
@@ -36,6 +40,8 @@ const persistOptions: PersistOptions<SessionStore, SessionPersist> = {
|
|
|
36
40
|
// version: Migration.targetVersion,
|
|
37
41
|
};
|
|
38
42
|
|
|
43
|
+
// =============== 实装 useStore ============ //
|
|
44
|
+
|
|
39
45
|
export const useSessionStore = createWithEqualityFn<SessionStore>()(
|
|
40
46
|
persist(
|
|
41
47
|
devtools(createStore, {
|
|
@@ -43,5 +49,5 @@ export const useSessionStore = createWithEqualityFn<SessionStore>()(
|
|
|
43
49
|
}),
|
|
44
50
|
persistOptions,
|
|
45
51
|
),
|
|
46
|
-
|
|
52
|
+
shallow,
|
|
47
53
|
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useSettings } from '../store';
|
|
4
|
+
|
|
5
|
+
export const useSettingsHydrated = () => {
|
|
6
|
+
// 根据 sessions 是否有值来判断是否已经初始化
|
|
7
|
+
const hasInited = !!Object.values(useSettings.getState().settings).length;
|
|
8
|
+
|
|
9
|
+
const [isInit, setInit] = useState(hasInited);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
const hasRehydrated = useSettings.persist.hasHydrated();
|
|
13
|
+
|
|
14
|
+
if (hasRehydrated && !isInit) {
|
|
15
|
+
setInit(true);
|
|
16
|
+
}
|
|
17
|
+
}, []);
|
|
18
|
+
|
|
19
|
+
return isInit;
|
|
20
|
+
};
|
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
import equal from 'fast-deep-equal';
|
|
2
|
-
import { type PersistOptions, devtools, persist } from 'zustand/middleware';
|
|
3
|
-
import { createWithEqualityFn } from 'zustand/traditional';
|
|
4
|
-
|
|
5
|
-
import { isDev } from '@/utils/env';
|
|
6
|
-
|
|
7
|
-
import { type SettingsStore, createStore } from './store';
|
|
8
|
-
|
|
9
|
-
export const LOBE_SETTINGS = 'LOBE_SETTINGS';
|
|
10
|
-
|
|
11
|
-
const persistOptions: PersistOptions<SettingsStore> = {
|
|
12
|
-
name: LOBE_SETTINGS,
|
|
13
|
-
skipHydration: true,
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const useSettings = createWithEqualityFn<SettingsStore>()(
|
|
17
|
-
persist(
|
|
18
|
-
devtools(createStore, {
|
|
19
|
-
name: LOBE_SETTINGS + (isDev ? '_DEV' : ''),
|
|
20
|
-
}),
|
|
21
|
-
persistOptions,
|
|
22
|
-
),
|
|
23
|
-
equal,
|
|
24
|
-
);
|
|
25
|
-
|
|
26
1
|
export * from './selectors';
|
|
27
2
|
export type { SettingsStore } from './store';
|
|
3
|
+
export { useSettings } from './store';
|
|
@@ -1,15 +1,43 @@
|
|
|
1
|
+
import { PersistOptions, devtools, persist } from 'zustand/middleware';
|
|
2
|
+
import { shallow } from 'zustand/shallow';
|
|
3
|
+
import { createWithEqualityFn } from 'zustand/traditional';
|
|
1
4
|
import { StateCreator } from 'zustand/vanilla';
|
|
2
5
|
|
|
6
|
+
import { isDev } from '@/utils/env';
|
|
7
|
+
|
|
3
8
|
import { type AppSettingsState, initialState } from './initialState';
|
|
4
9
|
import { type AgentAction, createAgentSlice } from './slices/agent';
|
|
5
10
|
import { type CommonAction, createCommonSlice } from './slices/common';
|
|
6
11
|
|
|
12
|
+
// =============== 聚合 createStoreFn ============ //
|
|
13
|
+
|
|
7
14
|
export type SettingsStore = CommonAction & AppSettingsState & AgentAction;
|
|
8
15
|
|
|
9
|
-
|
|
16
|
+
const createStore: StateCreator<SettingsStore, [['zustand/devtools', never]]> = (
|
|
10
17
|
...parameters
|
|
11
18
|
) => ({
|
|
12
19
|
...initialState,
|
|
13
20
|
...createCommonSlice(...parameters),
|
|
14
21
|
...createAgentSlice(...parameters),
|
|
15
22
|
});
|
|
23
|
+
|
|
24
|
+
// =============== persist 本地缓存中间件配置 ============ //
|
|
25
|
+
|
|
26
|
+
const LOBE_SETTINGS = 'LOBE_SETTINGS';
|
|
27
|
+
|
|
28
|
+
const persistOptions: PersistOptions<SettingsStore> = {
|
|
29
|
+
name: LOBE_SETTINGS,
|
|
30
|
+
skipHydration: true,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// =============== 实装 useStore ============ //
|
|
34
|
+
|
|
35
|
+
export const useSettings = createWithEqualityFn<SettingsStore>()(
|
|
36
|
+
persist(
|
|
37
|
+
devtools(createStore, {
|
|
38
|
+
name: LOBE_SETTINGS + (isDev ? '_DEV' : ''),
|
|
39
|
+
}),
|
|
40
|
+
persistOptions,
|
|
41
|
+
),
|
|
42
|
+
shallow,
|
|
43
|
+
);
|