@lobehub/chat 0.159.8 → 0.159.10
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 +50 -0
- package/package.json +2 -2
- package/src/app/(main)/chat/(workspace)/@topic/features/TopicListContent/index.tsx +1 -1
- package/src/app/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Main.tsx +3 -2
- package/src/app/(main)/chat/(workspace)/_layout/useInitAgentConfig.ts +0 -20
- package/src/app/(main)/chat/@session/features/SessionHydration.tsx +10 -7
- package/src/app/(main)/market/@detail/features/Header.tsx +9 -5
- package/src/app/(main)/settings/_layout/Desktop/Header.tsx +27 -67
- package/src/app/@modal/_layout/SettingModalLayout.tsx +14 -8
- package/src/components/404/index.tsx +1 -1
- package/src/components/Error/index.tsx +1 -1
- package/src/hooks/useActiveSettingsKey.ts +4 -0
- package/src/store/session/slices/session/action.test.ts +0 -3
- package/src/store/session/slices/session/initialState.ts +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.159.10](https://github.com/lobehub/lobe-chat/compare/v0.159.9...v0.159.10)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2024-05-15**</sup>
|
|
8
|
+
|
|
9
|
+
#### 💄 Styles
|
|
10
|
+
|
|
11
|
+
- **misc**: Fix setting modal on responsive and some other style problem.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Styles
|
|
19
|
+
|
|
20
|
+
- **misc**: Fix setting modal on responsive and some other style problem, closes [#2512](https://github.com/lobehub/lobe-chat/issues/2512) ([f6b4ca4](https://github.com/lobehub/lobe-chat/commit/f6b4ca4))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
### [Version 0.159.9](https://github.com/lobehub/lobe-chat/compare/v0.159.8...v0.159.9)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2024-05-14**</sup>
|
|
33
|
+
|
|
34
|
+
#### 🐛 Bug Fixes
|
|
35
|
+
|
|
36
|
+
- **misc**: Fix agent config on page init.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### What's fixed
|
|
44
|
+
|
|
45
|
+
- **misc**: Fix agent config on page init, closes [#2506](https://github.com/lobehub/lobe-chat/issues/2506) ([90e742d](https://github.com/lobehub/lobe-chat/commit/90e742d))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
### [Version 0.159.8](https://github.com/lobehub/lobe-chat/compare/v0.159.7...v0.159.8)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2024-05-14**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.159.
|
|
3
|
+
"version": "0.159.10",
|
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"@lobehub/chat-plugins-gateway": "latest",
|
|
97
97
|
"@lobehub/icons": "latest",
|
|
98
98
|
"@lobehub/tts": "latest",
|
|
99
|
-
"@lobehub/ui": "^1.138.
|
|
99
|
+
"@lobehub/ui": "^1.138.24",
|
|
100
100
|
"@microsoft/fetch-event-source": "^2.0.1",
|
|
101
101
|
"@next/third-parties": "^14.2.3",
|
|
102
102
|
"@sentry/nextjs": "^7.114.0",
|
|
@@ -8,6 +8,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
8
8
|
import { Flexbox } from 'react-layout-kit';
|
|
9
9
|
|
|
10
10
|
import { useInitAgentConfig } from '@/app/(main)/chat/(workspace)/_layout/useInitAgentConfig';
|
|
11
|
+
import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
|
11
12
|
import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
|
|
12
13
|
import { useGlobalStore } from '@/store/global';
|
|
13
14
|
import { useSessionStore } from '@/store/session';
|
|
@@ -45,7 +46,7 @@ const Main = memo(() => {
|
|
|
45
46
|
/>
|
|
46
47
|
</Flexbox>
|
|
47
48
|
) : (
|
|
48
|
-
<Flexbox align={'
|
|
49
|
+
<Flexbox align={'center'} gap={4} horizontal>
|
|
49
50
|
{
|
|
50
51
|
<ActionIcon
|
|
51
52
|
aria-label={t('agentsAndConversations')}
|
|
@@ -57,7 +58,7 @@ const Main = memo(() => {
|
|
|
57
58
|
showSessionPanel: !currentShowSessionPanel,
|
|
58
59
|
});
|
|
59
60
|
}}
|
|
60
|
-
size=
|
|
61
|
+
size={DESKTOP_HEADER_ICON_SIZE}
|
|
61
62
|
title={t('agentsAndConversations')}
|
|
62
63
|
/>
|
|
63
64
|
}
|
|
@@ -1,30 +1,10 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
|
|
3
1
|
import { useAgentStore } from '@/store/agent';
|
|
4
|
-
import { useChatStore } from '@/store/chat';
|
|
5
2
|
import { useSessionStore } from '@/store/session';
|
|
6
3
|
|
|
7
4
|
export const useInitAgentConfig = () => {
|
|
8
5
|
const [useFetchAgentConfig] = useAgentStore((s) => [s.useFetchAgentConfig]);
|
|
9
6
|
|
|
10
|
-
const [switchTopic] = useChatStore((s) => [s.switchTopic]);
|
|
11
7
|
const [sessionId] = useSessionStore((s) => [s.activeId]);
|
|
12
8
|
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
// // when activeId changed, switch topic to undefined
|
|
15
|
-
const unsubscribe = useSessionStore.subscribe(
|
|
16
|
-
(s) => s.activeId,
|
|
17
|
-
(activeId) => {
|
|
18
|
-
switchTopic();
|
|
19
|
-
|
|
20
|
-
useAgentStore.setState({ activeId }, false, 'updateActiveId');
|
|
21
|
-
},
|
|
22
|
-
);
|
|
23
|
-
|
|
24
|
-
return () => {
|
|
25
|
-
unsubscribe();
|
|
26
|
-
};
|
|
27
|
-
}, []);
|
|
28
|
-
|
|
29
9
|
return useFetchAgentConfig(sessionId);
|
|
30
10
|
};
|
|
@@ -1,32 +1,35 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { useResponsive } from 'antd-style';
|
|
4
3
|
import { useQueryState } from 'nuqs';
|
|
5
4
|
import { parseAsString } from 'nuqs/server';
|
|
6
5
|
import { memo, useEffect } from 'react';
|
|
7
6
|
import { createStoreUpdater } from 'zustand-utils';
|
|
8
7
|
|
|
8
|
+
import { useAgentStore } from '@/store/agent';
|
|
9
|
+
import { useChatStore } from '@/store/chat';
|
|
9
10
|
import { useSessionStore } from '@/store/session';
|
|
10
11
|
|
|
11
12
|
// sync outside state to useSessionStore
|
|
12
13
|
const SessionHydration = memo(() => {
|
|
13
14
|
const useStoreUpdater = createStoreUpdater(useSessionStore);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const { mobile } = useResponsive();
|
|
17
|
-
useStoreUpdater('isMobile', mobile);
|
|
15
|
+
const useAgentStoreUpdater = createStoreUpdater(useAgentStore);
|
|
16
|
+
const [switchTopic] = useChatStore((s) => [s.switchTopic]);
|
|
18
17
|
|
|
19
18
|
// two-way bindings the url and session store
|
|
20
19
|
const [session, setSession] = useQueryState(
|
|
21
20
|
'session',
|
|
22
|
-
parseAsString.withDefault('inbox').withOptions({ history: 'replace', throttleMs:
|
|
21
|
+
parseAsString.withDefault('inbox').withOptions({ history: 'replace', throttleMs: 50 }),
|
|
23
22
|
);
|
|
24
23
|
useStoreUpdater('activeId', session);
|
|
24
|
+
useAgentStoreUpdater('activeId', session);
|
|
25
25
|
|
|
26
26
|
useEffect(() => {
|
|
27
27
|
const unsubscribe = useSessionStore.subscribe(
|
|
28
28
|
(s) => s.activeId,
|
|
29
|
-
(state) =>
|
|
29
|
+
(state) => {
|
|
30
|
+
switchTopic();
|
|
31
|
+
setSession(state);
|
|
32
|
+
},
|
|
30
33
|
);
|
|
31
34
|
|
|
32
35
|
return () => {
|
|
@@ -3,7 +3,7 @@ import { App, Button, Typography } from 'antd';
|
|
|
3
3
|
import isEqual from 'fast-deep-equal';
|
|
4
4
|
import { startCase } from 'lodash-es';
|
|
5
5
|
import { useRouter } from 'next/navigation';
|
|
6
|
-
import { memo } from 'react';
|
|
6
|
+
import { memo, useState } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import { Center, Flexbox } from 'react-layout-kit';
|
|
9
9
|
|
|
@@ -23,7 +23,7 @@ const Header = memo(() => {
|
|
|
23
23
|
const { styles } = useStyles();
|
|
24
24
|
const createSession = useSessionStore((s) => s.createSession);
|
|
25
25
|
const agentItem = useMarketStore(agentMarketSelectors.currentAgentItem, isEqual);
|
|
26
|
-
|
|
26
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
27
27
|
const { message } = App.useApp();
|
|
28
28
|
|
|
29
29
|
const { meta, createAt, author, homepage, config } = agentItem;
|
|
@@ -34,15 +34,19 @@ const Header = memo(() => {
|
|
|
34
34
|
const handleAddAgentAndConverse = async () => {
|
|
35
35
|
if (!agentItem) return;
|
|
36
36
|
|
|
37
|
+
setIsLoading(true);
|
|
37
38
|
const session = await createSession({ config, meta });
|
|
39
|
+
setIsLoading(false);
|
|
38
40
|
message.success(t('addAgentSuccess'));
|
|
39
41
|
router.push(SESSION_CHAT_URL(session, isMobile));
|
|
40
42
|
};
|
|
41
43
|
|
|
42
|
-
const handleAddAgent = () => {
|
|
44
|
+
const handleAddAgent = async () => {
|
|
43
45
|
if (!agentItem) return;
|
|
46
|
+
setIsLoading(true);
|
|
44
47
|
createSession({ config, meta }, false);
|
|
45
48
|
message.success(t('addAgentSuccess'));
|
|
49
|
+
setIsLoading(false);
|
|
46
50
|
};
|
|
47
51
|
|
|
48
52
|
return (
|
|
@@ -56,10 +60,10 @@ const Header = memo(() => {
|
|
|
56
60
|
))}
|
|
57
61
|
</Center>
|
|
58
62
|
<div className={styles.desc}>{description}</div>
|
|
59
|
-
<Button block onClick={handleAddAgentAndConverse} type={'primary'}>
|
|
63
|
+
<Button block loading={isLoading} onClick={handleAddAgentAndConverse} type={'primary'}>
|
|
60
64
|
{t('addAgentAndConverse')}
|
|
61
65
|
</Button>
|
|
62
|
-
<Button block onClick={handleAddAgent}>
|
|
66
|
+
<Button block loading={isLoading} onClick={handleAddAgent}>
|
|
63
67
|
{t('addAgent')}
|
|
64
68
|
</Button>
|
|
65
69
|
<Flexbox align={'center'} gap={12} horizontal>
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { ActionIcon, ChatHeader, ChatHeaderTitle } from '@lobehub/ui';
|
|
4
|
-
import {
|
|
4
|
+
import { type DrawerProps, Popover } from 'antd';
|
|
5
5
|
import { createStyles } from 'antd-style';
|
|
6
6
|
import { Menu } from 'lucide-react';
|
|
7
|
-
import { PropsWithChildren, memo
|
|
8
|
-
import { useTranslation } from 'react-i18next';
|
|
9
|
-
import { Flexbox } from 'react-layout-kit';
|
|
10
|
-
|
|
11
|
-
import BrandWatermark from '@/components/BrandWatermark';
|
|
12
|
-
import { useActiveSettingsKey } from '@/hooks/useActiveSettingsKey';
|
|
13
|
-
import { SettingsTabs } from '@/store/global/initialState';
|
|
7
|
+
import { PropsWithChildren, memo } from 'react';
|
|
14
8
|
|
|
15
9
|
const useStyles = createStyles(({ token, css }) => ({
|
|
16
10
|
container: css`
|
|
17
11
|
position: relative;
|
|
12
|
+
flex: none;
|
|
18
13
|
height: 54px;
|
|
19
14
|
background: ${token.colorBgContainer};
|
|
20
15
|
`,
|
|
@@ -25,68 +20,33 @@ const useStyles = createStyles(({ token, css }) => ({
|
|
|
25
20
|
`,
|
|
26
21
|
}));
|
|
27
22
|
|
|
28
|
-
const Header = memo<PropsWithChildren & Pick<DrawerProps, 'getContainer'>>(
|
|
29
|
-
|
|
30
|
-
const [open, setOpen] = useState(false);
|
|
31
|
-
const { styles, theme } = useStyles();
|
|
32
|
-
const { t } = useTranslation('setting');
|
|
33
|
-
|
|
34
|
-
const activeKey = useActiveSettingsKey();
|
|
23
|
+
const Header = memo<PropsWithChildren & Pick<DrawerProps, 'getContainer'>>(({ children }) => {
|
|
24
|
+
const { styles, theme } = useStyles();
|
|
35
25
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
<Tag color={'gold'}>{t('tab.experiment')}</Tag>
|
|
54
|
-
)}
|
|
55
|
-
</Flexbox>
|
|
56
|
-
}
|
|
26
|
+
return (
|
|
27
|
+
<ChatHeader
|
|
28
|
+
className={styles.container}
|
|
29
|
+
left={
|
|
30
|
+
<ChatHeaderTitle
|
|
31
|
+
title={
|
|
32
|
+
<Popover
|
|
33
|
+
arrow={false}
|
|
34
|
+
content={children}
|
|
35
|
+
overlayInnerStyle={{ minWidth: 240, padding: '2px 4px' }}
|
|
36
|
+
placement={'bottomLeft'}
|
|
37
|
+
trigger={['click']}
|
|
38
|
+
>
|
|
39
|
+
<ActionIcon
|
|
40
|
+
color={theme.colorText}
|
|
41
|
+
icon={Menu}
|
|
42
|
+
size={{ blockSize: 32, fontSize: 18 }}
|
|
57
43
|
/>
|
|
58
|
-
</
|
|
44
|
+
</Popover>
|
|
59
45
|
}
|
|
60
46
|
/>
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
gap: 20,
|
|
66
|
-
justifyContent: 'space-between',
|
|
67
|
-
padding: 16,
|
|
68
|
-
}}
|
|
69
|
-
getContainer={getContainer}
|
|
70
|
-
headerStyle={{ display: 'none' }}
|
|
71
|
-
maskStyle={{ background: 'transparent' }}
|
|
72
|
-
onClick={() => setOpen(false)}
|
|
73
|
-
onClose={() => setOpen(false)}
|
|
74
|
-
open={open}
|
|
75
|
-
placement={'left'}
|
|
76
|
-
rootStyle={{ position: 'absolute' }}
|
|
77
|
-
style={{
|
|
78
|
-
background: theme.colorBgContainer,
|
|
79
|
-
borderRight: `1px solid ${theme.colorSplit}`,
|
|
80
|
-
}}
|
|
81
|
-
width={260}
|
|
82
|
-
zIndex={10}
|
|
83
|
-
>
|
|
84
|
-
{children}
|
|
85
|
-
<BrandWatermark paddingInline={12} />
|
|
86
|
-
</Drawer>
|
|
87
|
-
</>
|
|
88
|
-
);
|
|
89
|
-
},
|
|
90
|
-
);
|
|
47
|
+
}
|
|
48
|
+
/>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
91
51
|
|
|
92
52
|
export default Header;
|
|
@@ -18,11 +18,11 @@ const SettingModalLayout = memo<SettingLayoutProps>(({ children, category, desc,
|
|
|
18
18
|
const ref = useRef<any>(null);
|
|
19
19
|
const theme = useTheme();
|
|
20
20
|
const { isDarkMode } = useThemeMode();
|
|
21
|
-
const {
|
|
21
|
+
const { mobile = false } = useResponsive();
|
|
22
22
|
|
|
23
23
|
return (
|
|
24
|
-
|
|
25
|
-
{
|
|
24
|
+
<Flexbox horizontal={!mobile} width={'100%'}>
|
|
25
|
+
{!mobile ? (
|
|
26
26
|
<SideBar
|
|
27
27
|
desc={desc}
|
|
28
28
|
style={{
|
|
@@ -38,19 +38,25 @@ const SettingModalLayout = memo<SettingLayoutProps>(({ children, category, desc,
|
|
|
38
38
|
)}
|
|
39
39
|
<Flexbox
|
|
40
40
|
align={'center'}
|
|
41
|
-
gap={64}
|
|
41
|
+
gap={mobile ? 0 : 64}
|
|
42
|
+
ref={ref}
|
|
42
43
|
style={{
|
|
43
|
-
background:
|
|
44
|
+
background: mobile
|
|
45
|
+
? theme.colorBgContainer
|
|
46
|
+
: isDarkMode
|
|
47
|
+
? theme.colorFillQuaternary
|
|
48
|
+
: theme.colorBgElevated,
|
|
49
|
+
minHeight: '100%',
|
|
44
50
|
overflowX: 'hidden',
|
|
45
51
|
overflowY: 'auto',
|
|
46
|
-
paddingBlock: 40,
|
|
47
|
-
paddingInline: 56,
|
|
52
|
+
paddingBlock: mobile ? 0 : 40,
|
|
53
|
+
paddingInline: mobile ? 0 : 56,
|
|
48
54
|
}}
|
|
49
55
|
width={'100%'}
|
|
50
56
|
>
|
|
51
57
|
{children}
|
|
52
58
|
</Flexbox>
|
|
53
|
-
|
|
59
|
+
</Flexbox>
|
|
54
60
|
);
|
|
55
61
|
});
|
|
56
62
|
|
|
@@ -12,7 +12,7 @@ import { MAX_WIDTH } from '@/const/layoutTokens';
|
|
|
12
12
|
const NotFound = memo(() => {
|
|
13
13
|
const { t } = useTranslation('error');
|
|
14
14
|
return (
|
|
15
|
-
<Flexbox align={'center'} justify={'center'} style={{
|
|
15
|
+
<Flexbox align={'center'} justify={'center'} style={{ minHeight: '100%', width: '100%' }}>
|
|
16
16
|
<h1
|
|
17
17
|
style={{
|
|
18
18
|
filter: 'blur(8px)',
|
|
@@ -24,7 +24,7 @@ const ErrorCapture = memo<ErrorCaptureProps>(({ reset, error }) => {
|
|
|
24
24
|
}, [error]);
|
|
25
25
|
|
|
26
26
|
return (
|
|
27
|
-
<Flexbox align={'center'} justify={'center'} style={{
|
|
27
|
+
<Flexbox align={'center'} justify={'center'} style={{ minHeight: '100%', width: '100%' }}>
|
|
28
28
|
<h1
|
|
29
29
|
style={{
|
|
30
30
|
filter: 'blur(8px)',
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { usePathname } from 'next/navigation';
|
|
2
2
|
|
|
3
|
+
import { useQuery } from '@/hooks/useQuery';
|
|
3
4
|
import { SettingsTabs } from '@/store/global/initialState';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -7,10 +8,13 @@ import { SettingsTabs } from '@/store/global/initialState';
|
|
|
7
8
|
*/
|
|
8
9
|
export const useActiveSettingsKey = () => {
|
|
9
10
|
const pathname = usePathname();
|
|
11
|
+
const { tab } = useQuery();
|
|
10
12
|
|
|
11
13
|
const tabs = pathname.split('/').at(-1);
|
|
12
14
|
|
|
13
15
|
if (tabs === 'settings') return SettingsTabs.Common;
|
|
14
16
|
|
|
17
|
+
if (tabs === 'modal') return tab as SettingsTabs;
|
|
18
|
+
|
|
15
19
|
return tabs as SettingsTabs;
|
|
16
20
|
};
|
|
@@ -101,9 +101,6 @@ describe('SessionAction', () => {
|
|
|
101
101
|
expect(call[1]).toMatchObject({ config: { displayMode: 'docs' } });
|
|
102
102
|
|
|
103
103
|
expect(createdSessionId).toBe(newSessionId);
|
|
104
|
-
expect(mockRouterPush).not.toHaveBeenCalledWith(
|
|
105
|
-
SESSION_CHAT_URL(newSessionId, result.current.isMobile),
|
|
106
|
-
);
|
|
107
104
|
});
|
|
108
105
|
});
|
|
109
106
|
|
|
@@ -8,7 +8,6 @@ export interface SessionState {
|
|
|
8
8
|
activeId: string;
|
|
9
9
|
customSessionGroups: CustomSessionGroup[];
|
|
10
10
|
defaultSessions: LobeAgentSession[];
|
|
11
|
-
isMobile?: boolean;
|
|
12
11
|
isSearching: boolean;
|
|
13
12
|
isSessionsFirstFetchFinished: boolean;
|
|
14
13
|
pinnedSessions: LobeAgentSession[];
|
|
@@ -25,7 +24,6 @@ export const initialSessionState: SessionState = {
|
|
|
25
24
|
activeId: 'inbox',
|
|
26
25
|
customSessionGroups: [],
|
|
27
26
|
defaultSessions: [],
|
|
28
|
-
isMobile: false,
|
|
29
27
|
isSearching: false,
|
|
30
28
|
isSessionsFirstFetchFinished: false,
|
|
31
29
|
pinnedSessions: [],
|