@lobehub/chat 0.155.3 → 0.155.5

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.
Files changed (136) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +2 -2
  3. package/README.zh-CN.md +8 -8
  4. package/package.json +1 -1
  5. package/src/app/(main)/(mobile)/me/features/Header.tsx +2 -9
  6. package/src/app/(main)/(mobile)/me/loading.tsx +1 -12
  7. package/src/app/(main)/(mobile)/me/page.tsx +2 -5
  8. package/src/app/(main)/@nav/_layout/Mobile.tsx +1 -1
  9. package/src/app/(main)/_layout/Mobile.tsx +5 -1
  10. package/src/app/(main)/chat/(workspace)/@conversation/default.tsx +23 -0
  11. package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/index.tsx +6 -2
  12. package/src/app/(main)/chat/{(mobile)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Mobile}/index.tsx +9 -4
  13. package/src/app/(main)/chat/(workspace)/@topic/default.tsx +19 -0
  14. package/src/app/(main)/chat/{(desktop)/features/SideBar/SystemRole/index.tsx → (workspace)/@topic/features/SystemRole/SystemRoleContent.tsx} +2 -0
  15. package/src/app/(main)/chat/(workspace)/@topic/features/SystemRole/index.tsx +18 -0
  16. package/src/app/(main)/chat/{features → (workspace)/@topic/features}/TopicListContent/Header.tsx +2 -0
  17. package/src/app/(main)/chat/{features → (workspace)/@topic/features}/TopicListContent/Topic/index.tsx +26 -28
  18. package/src/app/(main)/chat/{features → (workspace)/@topic/features}/TopicListContent/TopicSearchBar/index.tsx +4 -2
  19. package/src/app/(main)/chat/{features → (workspace)/@topic/features}/TopicListContent/index.tsx +3 -4
  20. package/src/app/(main)/chat/{(desktop)/features → (workspace)/_layout/Desktop}/ChatHeader/HeaderAction.tsx +2 -0
  21. package/src/app/(main)/chat/{(desktop)/features → (workspace)/_layout/Desktop}/ChatHeader/Main.tsx +3 -1
  22. package/src/app/(main)/chat/{(desktop)/features → (workspace)/_layout/Desktop}/ChatHeader/Tags.tsx +1 -1
  23. package/src/app/(main)/chat/{(desktop)/features → (workspace)/_layout/Desktop}/ChatHeader/index.tsx +1 -2
  24. package/src/app/(main)/chat/{(desktop)/features → (workspace)/_layout/Desktop}/HotKeys.tsx +2 -0
  25. package/src/app/(main)/chat/{(desktop)/features/SideBar/index.tsx → (workspace)/_layout/Desktop/TopicPanel.tsx} +23 -20
  26. package/src/app/(main)/chat/(workspace)/_layout/Desktop/index.tsx +35 -0
  27. package/src/app/(main)/chat/(workspace)/_layout/Mobile/ChatHeader/index.tsx +35 -0
  28. package/src/app/(main)/chat/(workspace)/_layout/Mobile/TopicModal.tsx +26 -0
  29. package/src/app/(main)/chat/(workspace)/_layout/Mobile/index.tsx +21 -0
  30. package/src/app/(main)/chat/(workspace)/_layout/type.ts +7 -0
  31. package/src/app/(main)/chat/{features → (workspace)/features}/PluginTag/index.tsx +2 -0
  32. package/src/app/(main)/chat/{features → (workspace)/features}/SettingButton.tsx +3 -1
  33. package/src/app/(main)/chat/{features → (workspace)/features}/ShareButton/index.tsx +5 -6
  34. package/src/app/(main)/chat/{features/TelemetryNotification/index.tsx → (workspace)/features/TelemetryNotification.tsx} +2 -0
  35. package/src/app/(main)/chat/(workspace)/features/useWorkspaceModal.tsx +27 -0
  36. package/src/app/(main)/chat/(workspace)/layout.ts +11 -0
  37. package/src/app/(main)/chat/(workspace)/page.tsx +19 -0
  38. package/src/app/(main)/chat/@session/_layout/Desktop/PanelBody.tsx +22 -0
  39. package/src/app/(main)/chat/{_layout → @session/_layout}/Desktop/SessionHeader.tsx +2 -0
  40. package/src/app/(main)/chat/@session/_layout/Desktop/index.tsx +15 -0
  41. package/src/app/(main)/chat/{(mobile)/features → @session/_layout/Mobile}/SessionHeader.tsx +7 -20
  42. package/src/app/(main)/chat/@session/_layout/Mobile/index.tsx +19 -0
  43. package/src/app/(main)/chat/@session/default.tsx +23 -0
  44. package/src/app/(main)/chat/{components/SessionHydration/index.tsx → @session/features/SessionHydration.tsx} +1 -0
  45. package/src/app/(main)/chat/{features → @session/features}/SessionListContent/DefaultMode.tsx +3 -3
  46. package/src/app/(main)/chat/{features → @session/features}/SessionListContent/Inbox/index.tsx +2 -2
  47. package/src/app/(main)/chat/{features → @session/features}/SessionListContent/List/index.tsx +3 -4
  48. package/src/app/(main)/chat/{features → @session/features}/SessionListContent/ListItem/index.tsx +12 -10
  49. package/src/app/(main)/chat/{features → @session/features}/SessionListContent/SearchMode.tsx +4 -2
  50. package/src/app/(main)/chat/{features → @session/features}/SessionListContent/index.tsx +2 -0
  51. package/src/app/(main)/chat/{features/SessionSearchBar/index.tsx → @session/features/SessionSearchBar.tsx} +3 -5
  52. package/src/app/(main)/chat/_layout/Desktop/SessionPanel.tsx +79 -0
  53. package/src/app/(main)/chat/_layout/Desktop/index.tsx +11 -7
  54. package/src/app/(main)/chat/_layout/Mobile.tsx +52 -0
  55. package/src/app/(main)/chat/_layout/type.ts +1 -0
  56. package/src/app/(main)/chat/error.tsx +5 -0
  57. package/src/app/(main)/chat/features/Migration/index.tsx +3 -8
  58. package/src/app/(main)/chat/not-found.tsx +3 -0
  59. package/src/app/(main)/chat/settings/_layout/Mobile/Header.tsx +3 -4
  60. package/src/app/(main)/chat/settings/features/HeaderContent.tsx +2 -2
  61. package/src/app/(main)/chat/settings/features/SubmitAgentButton/index.tsx +2 -2
  62. package/src/app/(main)/market/@detail/features/Header.tsx +2 -2
  63. package/src/components/Cell/Divider.tsx +2 -2
  64. package/src/components/Cell/index.tsx +2 -2
  65. package/src/components/StoreHydration/ChatHydration/index.tsx +2 -2
  66. package/src/const/session.ts +2 -0
  67. package/src/const/url.ts +5 -1
  68. package/src/features/AgentSetting/AgentChat/index.tsx +3 -5
  69. package/src/features/AgentSetting/AgentMeta/index.tsx +51 -54
  70. package/src/features/AgentSetting/AgentModal/index.tsx +2 -2
  71. package/src/features/AgentSetting/AgentTTS/index.tsx +18 -16
  72. package/src/features/AgentSetting/useSyncAgemtSettings.ts +14 -0
  73. package/src/features/ChatInput/ActionBar/Tools/index.tsx +3 -2
  74. package/src/features/Conversation/components/InboxWelcome/AgentsSuggest.tsx +1 -1
  75. package/src/features/Conversation/components/InboxWelcome/index.tsx +2 -2
  76. package/src/features/Conversation/components/SkeletonList.tsx +21 -8
  77. package/src/features/Conversation/components/VirtualizedList/index.tsx +19 -17
  78. package/src/features/Conversation/index.tsx +12 -31
  79. package/src/features/PluginStore/InstalledPluginList.tsx +28 -21
  80. package/src/features/PluginStore/OnlineList.tsx +4 -10
  81. package/src/features/PluginStore/PluginItem/Action.tsx +3 -2
  82. package/src/features/PluginStore/PluginItem/index.tsx +2 -0
  83. package/src/features/PluginStore/index.tsx +4 -2
  84. package/src/features/User/UserAvatar.tsx +2 -1
  85. package/src/features/User/UserPanel/useMenu.tsx +1 -1
  86. package/src/layout/GlobalProvider/AppTheme.tsx +7 -17
  87. package/src/store/global/action.ts +2 -0
  88. package/src/store/global/initialState.ts +2 -0
  89. package/src/styles/global.ts +12 -9
  90. package/src/styles/mobileHeader.ts +1 -1
  91. package/src/app/(main)/(mobile)/me/features/AvatarBanner.tsx +0 -27
  92. package/src/app/(main)/(mobile)/me/features/style.ts +0 -29
  93. package/src/app/(main)/chat/(desktop)/features/Conversation.tsx +0 -19
  94. package/src/app/(main)/chat/(desktop)/index.tsx +0 -22
  95. package/src/app/(main)/chat/(mobile)/features/SessionList.tsx +0 -17
  96. package/src/app/(main)/chat/(mobile)/features/TopicList.tsx +0 -29
  97. package/src/app/(main)/chat/(mobile)/index.tsx +0 -26
  98. package/src/app/(main)/chat/(mobile)/mobile/ChatHeader/index.tsx +0 -56
  99. package/src/app/(main)/chat/(mobile)/mobile/page.tsx +0 -26
  100. package/src/app/(main)/chat/_layout/Desktop/SessionList.tsx +0 -39
  101. package/src/app/(main)/chat/_layout/Mobile/index.tsx +0 -9
  102. package/src/app/(main)/chat/page.tsx +0 -25
  103. package/src/features/FolderPanel/index.tsx +0 -60
  104. package/src/utils/screen.ts +0 -14
  105. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/Footer/DragUpload.tsx +0 -0
  106. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/Footer/LocalFiles.tsx +0 -0
  107. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/Footer/SendMore.tsx +0 -0
  108. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/Footer/index.tsx +0 -0
  109. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/Header/index.tsx +0 -0
  110. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/TextArea.test.tsx +0 -0
  111. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/TextArea.tsx +0 -0
  112. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/__tests__/useAutoFocus.test.ts +0 -0
  113. /package/src/app/(main)/chat/{(desktop)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Desktop}/useAutoFocus.ts +0 -0
  114. /package/src/app/(main)/chat/{(mobile)/features/ChatInput → (workspace)/@conversation/features/ChatInput/Mobile}/Files.tsx +0 -0
  115. /package/src/app/(main)/chat/{(desktop)/features/SideBar → (workspace)/@topic/features}/SystemRole/style.ts +0 -0
  116. /package/src/app/(main)/chat/{features → (workspace)/@topic/features}/TopicListContent/Topic/DefaultContent.tsx +0 -0
  117. /package/src/app/(main)/chat/{features → (workspace)/@topic/features}/TopicListContent/Topic/SkeletonList.tsx +0 -0
  118. /package/src/app/(main)/chat/{features → (workspace)/@topic/features}/TopicListContent/Topic/TopicContent.tsx +0 -0
  119. /package/src/app/(main)/chat/{features → (workspace)/@topic/features}/TopicListContent/Topic/TopicItem.tsx +0 -0
  120. /package/src/app/(main)/chat/{(mobile)/mobile → (workspace)/_layout/Mobile}/ChatHeader/ChatHeaderTitle.tsx +0 -0
  121. /package/src/app/(main)/chat/{features → (workspace)/features}/PluginTag/PluginStatus.tsx +0 -0
  122. /package/src/app/(main)/chat/{features → (workspace)/features}/ShareButton/Preview.tsx +0 -0
  123. /package/src/app/(main)/chat/{features → (workspace)/features}/ShareButton/ShareModal.tsx +0 -0
  124. /package/src/app/(main)/chat/{features → (workspace)/features}/ShareButton/style.ts +0 -0
  125. /package/src/app/(main)/chat/{features → (workspace)/features}/ShareButton/type.ts +0 -0
  126. /package/src/app/(main)/chat/{features → (workspace)/features}/ShareButton/useScreenshot.ts +0 -0
  127. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/CollapseGroup/Actions.tsx +0 -0
  128. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/CollapseGroup/index.tsx +0 -0
  129. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/List/AddButton.tsx +0 -0
  130. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/List/Item/Actions.tsx +0 -0
  131. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/List/Item/index.tsx +0 -0
  132. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/Modals/ConfigGroupModal/GroupItem.tsx +0 -0
  133. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/Modals/ConfigGroupModal/index.tsx +0 -0
  134. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/Modals/CreateGroupModal.tsx +0 -0
  135. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/Modals/RenameGroupModal.tsx +0 -0
  136. /package/src/app/(main)/chat/{features → @session/features}/SessionListContent/SkeletonList.tsx +0 -0
@@ -1,20 +1,24 @@
1
1
  import { Flexbox } from 'react-layout-kit';
2
2
 
3
+ import Migration from '../../features/Migration';
3
4
  import { LayoutProps } from '../type';
4
- import ResponsiveSessionList from './SessionList';
5
+ import SessionPanel from './SessionPanel';
5
6
 
6
- const Layout = ({ children }: LayoutProps) => {
7
+ const Layout = ({ children, session }: LayoutProps) => {
7
8
  return (
8
9
  <>
9
- <ResponsiveSessionList />
10
10
  <Flexbox
11
- flex={1}
12
11
  height={'100%'}
13
- id={'lobe-conversion-container'}
14
- style={{ position: 'relative' }}
12
+ horizontal
13
+ style={{ maxWidth: 'calc(100vw - 64px)', overflow: 'hidden', position: 'relative' }}
14
+ width={'100%'}
15
15
  >
16
- {children}
16
+ <SessionPanel>{session}</SessionPanel>
17
+ <Flexbox flex={1} style={{ overflow: 'hidden', position: 'relative' }}>
18
+ {children}
19
+ </Flexbox>
17
20
  </Flexbox>
21
+ <Migration />
18
22
  </>
19
23
  );
20
24
  };
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+
3
+ import { createStyles } from 'antd-style';
4
+ import { memo } from 'react';
5
+ import { Flexbox } from 'react-layout-kit';
6
+
7
+ import Migration from '@/app/(main)/chat/features/Migration';
8
+ import { useQuery } from '@/hooks/useQuery';
9
+
10
+ import { LayoutProps } from './type';
11
+
12
+ const useStyles = createStyles(({ css, token }) => ({
13
+ active: css`
14
+ display: unset;
15
+ `,
16
+ main: css`
17
+ position: relative;
18
+ overflow: hidden;
19
+ display: none;
20
+ background: ${token.colorBgLayout};
21
+ `,
22
+ }));
23
+
24
+ const Layout = memo<LayoutProps>(({ children, session }) => {
25
+ const { showMobileWorkspace } = useQuery();
26
+ const { cx, styles } = useStyles();
27
+
28
+ return (
29
+ <>
30
+ <Flexbox
31
+ className={cx(styles.main, !showMobileWorkspace && styles.active)}
32
+ height="100%"
33
+ width="100%"
34
+ >
35
+ {session}
36
+ </Flexbox>
37
+ <Flexbox
38
+ className={cx(styles.main, showMobileWorkspace && styles.active)}
39
+ height="100%"
40
+ id={'lobe-workspace-mobile'}
41
+ width="100%"
42
+ >
43
+ {children}
44
+ </Flexbox>
45
+ <Migration />
46
+ </>
47
+ );
48
+ });
49
+
50
+ Layout.displayName = 'MobileChatLayout';
51
+
52
+ export default Layout;
@@ -2,4 +2,5 @@ import { ReactNode } from 'react';
2
2
 
3
3
  export interface LayoutProps {
4
4
  children: ReactNode;
5
+ session: ReactNode;
5
6
  }
@@ -0,0 +1,5 @@
1
+ 'use client';
2
+
3
+ import dynamic from 'next/dynamic';
4
+
5
+ export default dynamic(() => import('@/components/Error'));
@@ -3,13 +3,13 @@
3
3
  import { Spin } from 'antd';
4
4
  import { createStore, getMany } from 'idb-keyval';
5
5
  import dynamic from 'next/dynamic';
6
- import { PropsWithChildren, memo, useEffect, useState } from 'react';
6
+ import { memo, useEffect, useState } from 'react';
7
7
 
8
8
  import { MIGRATE_KEY, V1DB_NAME, V1DB_TABLE_NAME } from './const';
9
9
 
10
10
  const Modal = dynamic(() => import('./Modal'), { loading: () => <Spin fullscreen />, ssr: false });
11
11
 
12
- const Migration = memo<PropsWithChildren>(({ children }) => {
12
+ const Migration = memo(() => {
13
13
  const [dbState, setDbState] = useState(null);
14
14
  const [open, setOpen] = useState(false);
15
15
 
@@ -33,12 +33,7 @@ const Migration = memo<PropsWithChildren>(({ children }) => {
33
33
  checkMigration();
34
34
  }, []);
35
35
 
36
- return (
37
- <>
38
- {open && <Modal open={open} setOpen={setOpen} state={dbState} />}
39
- {children}
40
- </>
41
- );
36
+ return open && <Modal open={open} setOpen={setOpen} state={dbState} />;
42
37
  });
43
38
 
44
39
  export default Migration;
@@ -0,0 +1,3 @@
1
+ import dynamic from 'next/dynamic';
2
+
3
+ export default dynamic(() => import('@/components/404'));
@@ -1,23 +1,22 @@
1
1
  'use client';
2
2
 
3
3
  import { MobileNavBar, MobileNavBarTitle } from '@lobehub/ui';
4
- import { useRouter } from 'next/navigation';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
7
+ import { useQueryRoute } from '@/hooks/useQueryRoute';
8
8
  import { mobileHeaderSticky } from '@/styles/mobileHeader';
9
- import { pathString } from '@/utils/url';
10
9
 
11
10
  import HeaderContent from '../../features/HeaderContent';
12
11
 
13
12
  const Header = memo(() => {
14
13
  const { t } = useTranslation('setting');
15
- const router = useRouter();
14
+ const router = useQueryRoute();
16
15
 
17
16
  return (
18
17
  <MobileNavBar
19
18
  center={<MobileNavBarTitle title={t('header.session')} />}
20
- onBackClick={() => router.push(pathString('/chat/mobile', { search: location.search }))}
19
+ onBackClick={() => router.push('/chat')}
21
20
  right={<HeaderContent />}
22
21
  showBackButton
23
22
  style={mobileHeaderSticky}
@@ -1,12 +1,12 @@
1
1
  import { ActionIcon, Icon } from '@lobehub/ui';
2
2
  import { Button, Dropdown, MenuProps } from 'antd';
3
- import { useResponsive } from 'antd-style';
4
3
  import { HardDriveDownload } from 'lucide-react';
5
4
  import { memo, useMemo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
8
7
  import { HEADER_ICON_SIZE } from '@/const/layoutTokens';
9
8
  import { configService } from '@/services/config';
9
+ import { useServerConfigStore } from '@/store/serverConfig';
10
10
  import { useSessionStore } from '@/store/session';
11
11
 
12
12
  import SubmitAgentButton from './SubmitAgentButton';
@@ -15,7 +15,7 @@ export const HeaderContent = memo<{ mobile?: boolean; modal?: boolean }>(({ moda
15
15
  const { t } = useTranslation('setting');
16
16
  const id = useSessionStore((s) => s.activeId);
17
17
 
18
- const { mobile } = useResponsive();
18
+ const mobile = useServerConfigStore((s) => s.isMobile);
19
19
 
20
20
  const items = useMemo<MenuProps['items']>(
21
21
  () => [
@@ -1,17 +1,17 @@
1
1
  import { ActionIcon, Icon } from '@lobehub/ui';
2
2
  import { Button } from 'antd';
3
- import { useResponsive } from 'antd-style';
4
3
  import { Share2 } from 'lucide-react';
5
4
  import { memo, useState } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
8
7
  import { HEADER_ICON_SIZE } from '@/const/layoutTokens';
8
+ import { useServerConfigStore } from '@/store/serverConfig';
9
9
 
10
10
  import SubmitAgentModal from './SubmitAgentModal';
11
11
 
12
12
  const SubmitAgentButton = memo<{ modal?: boolean }>(({ modal }) => {
13
13
  const { t } = useTranslation('setting');
14
- const { mobile } = useResponsive();
14
+ const mobile = useServerConfigStore((s) => s.isMobile);
15
15
  const [isModalOpen, setIsModalOpen] = useState(false);
16
16
 
17
17
  return (
@@ -8,8 +8,8 @@ import { useTranslation } from 'react-i18next';
8
8
  import { Center, Flexbox } from 'react-layout-kit';
9
9
 
10
10
  import { SESSION_CHAT_URL } from '@/const/url';
11
- import { useIsMobile } from '@/hooks/useIsMobile';
12
11
  import { agentMarketSelectors, useMarketStore } from '@/store/market';
12
+ import { useServerConfigStore } from '@/store/serverConfig';
13
13
  import { useSessionStore } from '@/store/session';
14
14
 
15
15
  import { useStyles } from './style';
@@ -29,7 +29,7 @@ const Header = memo(() => {
29
29
  const { meta, createAt, author, homepage, config } = agentItem;
30
30
  const { title, description, tags } = meta;
31
31
 
32
- const isMobile = useIsMobile();
32
+ const isMobile = useServerConfigStore((s) => s.isMobile);
33
33
 
34
34
  const handleAddAgentAndConverse = async () => {
35
35
  if (!agentItem) return;
@@ -4,11 +4,11 @@ import { createStyles } from 'antd-style';
4
4
  import { memo } from 'react';
5
5
 
6
6
  const useStyles = createStyles(
7
- ({ css, token, isDarkMode }) => css`
7
+ ({ css, token }) => css`
8
8
  flex: none;
9
9
  width: 100%;
10
10
  height: 6px;
11
- background: ${isDarkMode ? token.colorBgContainer : token.colorBgLayout};
11
+ background: ${token.colorFillTertiary};
12
12
  `,
13
13
  );
14
14
 
@@ -5,7 +5,7 @@ import { ReactNode, memo } from 'react';
5
5
 
6
6
  const { Item } = List;
7
7
 
8
- const useStyles = createStyles(({ css, token, isDarkMode }) => ({
8
+ const useStyles = createStyles(({ css, token }) => ({
9
9
  container: css`
10
10
  position: relative;
11
11
 
@@ -13,7 +13,7 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
13
13
 
14
14
  padding: 16px !important;
15
15
 
16
- background: ${isDarkMode ? token.colorBgLayout : token.colorBgContainer};
16
+ background: ${token.colorBgLayout};
17
17
  border-radius: 0;
18
18
  `,
19
19
  }));
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { useQueryState } from 'nuqs';
4
- import { memo, useEffect } from 'react';
4
+ import { memo, useLayoutEffect } from 'react';
5
5
  import { createStoreUpdater } from 'zustand-utils';
6
6
 
7
7
  import { useChatStore } from '@/store/chat';
@@ -14,7 +14,7 @@ const ChatHydration = memo(() => {
14
14
  const [topic, setTopic] = useQueryState('topic', { history: 'replace', throttleMs: 500 });
15
15
  useStoreUpdater('activeTopicId', topic);
16
16
 
17
- useEffect(() => {
17
+ useLayoutEffect(() => {
18
18
  const unsubscribe = useChatStore.subscribe(
19
19
  (s) => s.activeTopicId,
20
20
  (state) => {
@@ -5,6 +5,8 @@ import { merge } from '@/utils/merge';
5
5
 
6
6
  export const INBOX_SESSION_ID = 'inbox';
7
7
 
8
+ export const WELCOME_GUIDE_CHAT_ID = 'welcome';
9
+
8
10
  export const DEFAULT_AGENT_LOBE_SESSION: LobeAgentSession = {
9
11
  config: DEFAULT_AGENT_CONFIG,
10
12
  createdAt: Date.now(),
package/src/const/url.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import qs from 'query-string';
1
2
  import urlJoin from 'url-join';
2
3
 
3
4
  import { withBasePath } from '@/utils/basePath';
@@ -40,7 +41,10 @@ export const AGENTS_INDEX_GITHUB = 'https://github.com/lobehub/lobe-chat-agents'
40
41
  export const AGENTS_INDEX_GITHUB_ISSUE = urlJoin(AGENTS_INDEX_GITHUB, 'issues/new');
41
42
 
42
43
  export const SESSION_CHAT_URL = (id: string = INBOX_SESSION_ID, mobile?: boolean) =>
43
- mobile ? `/chat/mobile?session=${id}` : `/chat?session=${id}`;
44
+ qs.stringifyUrl({
45
+ query: mobile ? { session: id, showMobileWorkspace: mobile } : { session: id },
46
+ url: '/chat',
47
+ });
44
48
 
45
49
  export const imageUrl = (filename: string) => withBasePath(`/images/${filename}`);
46
50
 
@@ -3,22 +3,20 @@
3
3
  import { Form, ItemGroup, SelectWithImg, SliderWithInput } from '@lobehub/ui';
4
4
  import { Input, Switch } from 'antd';
5
5
  import { useThemeMode } from 'antd-style';
6
- import { debounce } from 'lodash-es';
7
6
  import { LayoutList, MessagesSquare } from 'lucide-react';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
 
11
- import { useSyncSettings } from '@/app/(main)/settings/hooks/useSyncSettings';
12
10
  import { FORM_STYLE } from '@/const/layoutTokens';
13
11
  import { imageUrl } from '@/const/url';
14
12
 
15
13
  import { useStore } from '../store';
14
+ import { useAgentSyncSettings } from '../useSyncAgemtSettings';
16
15
 
17
16
  const AgentChat = memo(() => {
18
17
  const { t } = useTranslation('setting');
19
18
  const [form] = Form.useForm();
20
19
  const { isDarkMode } = useThemeMode();
21
-
22
20
  const [
23
21
  displayMode,
24
22
  enableAutoCreateTopic,
@@ -33,7 +31,7 @@ const AgentChat = memo(() => {
33
31
  s.setAgentConfig,
34
32
  ]);
35
33
 
36
- useSyncSettings(form);
34
+ useAgentSyncSettings(form);
37
35
 
38
36
  const chat: ItemGroup = {
39
37
  children: [
@@ -125,7 +123,7 @@ const AgentChat = memo(() => {
125
123
  form={form}
126
124
  items={[chat]}
127
125
  itemsType={'group'}
128
- onValuesChange={debounce(updateConfig, 100)}
126
+ onValuesChange={updateConfig}
129
127
  variant={'pure'}
130
128
  {...FORM_STYLE}
131
129
  />
@@ -6,7 +6,7 @@ import isEqual from 'fast-deep-equal';
6
6
  import { isString } from 'lodash-es';
7
7
  import { Wand2 } from 'lucide-react';
8
8
  import dynamic from 'next/dynamic';
9
- import { memo, useMemo } from 'react';
9
+ import { memo } from 'react';
10
10
  import { useTranslation } from 'react-i18next';
11
11
 
12
12
  import { FORM_STYLE } from '@/const/layoutTokens';
@@ -77,60 +77,57 @@ const AgentMeta = memo(() => {
77
77
  };
78
78
  });
79
79
 
80
- const metaData: ItemGroup = useMemo(
81
- () => ({
82
- children: [
83
- {
84
- children: (
85
- <EmojiPicker
86
- backgroundColor={meta.backgroundColor}
87
- locale={locale}
88
- onChange={(avatar) => updateMeta({ avatar })}
89
- value={meta.avatar}
90
- />
91
- ),
92
- label: t('settingAgent.avatar.title'),
93
- minWidth: undefined,
94
- },
95
- {
96
- children: (
97
- <BackgroundSwatches
98
- backgroundColor={meta.backgroundColor}
99
- onChange={(backgroundColor) => updateMeta({ backgroundColor })}
100
- />
101
- ),
102
- label: t('settingAgent.backgroundColor.title'),
103
- minWidth: undefined,
104
- },
105
- ...autocompleteItems,
106
- ],
107
- extra: (
108
- <Tooltip
109
- title={
110
- !hasSystemRole
111
- ? t('autoGenerateTooltipDisabled', { ns: 'common' })
112
- : t('autoGenerateTooltip', { ns: 'common' })
113
- }
114
- >
115
- <Button
116
- disabled={!hasSystemRole}
117
- icon={<Icon icon={Wand2} />}
118
- loading={Object.values(loading).some((i) => !!i)}
119
- onClick={(e: any) => {
120
- e.stopPropagation();
80
+ const metaData: ItemGroup = {
81
+ children: [
82
+ {
83
+ children: (
84
+ <EmojiPicker
85
+ backgroundColor={meta.backgroundColor}
86
+ locale={locale}
87
+ onChange={(avatar) => updateMeta({ avatar })}
88
+ value={meta.avatar}
89
+ />
90
+ ),
91
+ label: t('settingAgent.avatar.title'),
92
+ minWidth: undefined,
93
+ },
94
+ {
95
+ children: (
96
+ <BackgroundSwatches
97
+ backgroundColor={meta.backgroundColor}
98
+ onChange={(backgroundColor) => updateMeta({ backgroundColor })}
99
+ />
100
+ ),
101
+ label: t('settingAgent.backgroundColor.title'),
102
+ minWidth: undefined,
103
+ },
104
+ ...autocompleteItems,
105
+ ],
106
+ extra: (
107
+ <Tooltip
108
+ title={
109
+ !hasSystemRole
110
+ ? t('autoGenerateTooltipDisabled', { ns: 'common' })
111
+ : t('autoGenerateTooltip', { ns: 'common' })
112
+ }
113
+ >
114
+ <Button
115
+ disabled={!hasSystemRole}
116
+ icon={<Icon icon={Wand2} />}
117
+ loading={Object.values(loading).some((i) => !!i)}
118
+ onClick={(e: any) => {
119
+ e.stopPropagation();
121
120
 
122
- autocompleteAllMeta(true);
123
- }}
124
- size={'small'}
125
- >
126
- {t('autoGenerate', { ns: 'common' })}
127
- </Button>
128
- </Tooltip>
129
- ),
130
- title: t('settingAgent.title'),
131
- }),
132
- [autocompleteItems, meta],
133
- );
121
+ autocompleteAllMeta(true);
122
+ }}
123
+ size={'small'}
124
+ >
125
+ {t('autoGenerate', { ns: 'common' })}
126
+ </Button>
127
+ </Tooltip>
128
+ ),
129
+ title: t('settingAgent.title'),
130
+ };
134
131
 
135
132
  return <Form items={[metaData]} itemsType={'group'} variant={'pure'} {...FORM_STYLE} />;
136
133
  });
@@ -6,10 +6,10 @@ import { debounce } from 'lodash-es';
6
6
  import { memo } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
 
9
- import { useSyncSettings } from '@/app/(main)/settings/hooks/useSyncSettings';
10
9
  import { FORM_STYLE } from '@/const/layoutTokens';
11
10
 
12
11
  import { useStore } from '../store';
12
+ import { useAgentSyncSettings } from '../useSyncAgemtSettings';
13
13
  import ModelSelect from './ModelSelect';
14
14
 
15
15
  const AgentModal = memo(() => {
@@ -21,7 +21,7 @@ const AgentModal = memo(() => {
21
21
  s.setAgentConfig,
22
22
  ]);
23
23
 
24
- useSyncSettings(form);
24
+ useAgentSyncSettings(form);
25
25
 
26
26
  const model: ItemGroup = {
27
27
  children: [
@@ -2,11 +2,10 @@
2
2
 
3
3
  import { VoiceList } from '@lobehub/tts';
4
4
  import { Form, ItemGroup } from '@lobehub/ui';
5
- import { Form as AFrom, Select, Switch } from 'antd';
6
- import isEqual from 'fast-deep-equal';
5
+ import { Select, Switch } from 'antd';
7
6
  import { debounce } from 'lodash-es';
8
7
  import { Mic } from 'lucide-react';
9
- import { memo, useEffect } from 'react';
8
+ import { memo, useMemo } from 'react';
10
9
  import { useTranslation } from 'react-i18next';
11
10
 
12
11
  import { FORM_STYLE } from '@/const/layoutTokens';
@@ -14,6 +13,7 @@ import { useUserStore } from '@/store/user';
14
13
  import { settingsSelectors } from '@/store/user/selectors';
15
14
 
16
15
  import { useStore } from '../store';
16
+ import { useAgentSyncSettings } from '../useSyncAgemtSettings';
17
17
  import SelectWithTTSPreview from './SelectWithTTSPreview';
18
18
  import { ttsOptions } from './options';
19
19
 
@@ -22,21 +22,23 @@ const { openaiVoiceOptions, localeOptions } = VoiceList;
22
22
 
23
23
  const AgentTTS = memo(() => {
24
24
  const { t } = useTranslation('setting');
25
- const updateConfig = useStore((s) => s.setAgentConfig);
26
- const [form] = AFrom.useForm();
25
+ const [form] = Form.useForm();
27
26
  const voiceList = useUserStore((s) => {
28
27
  const locale = settingsSelectors.currentLanguage(s);
29
28
  return (all?: boolean) => new VoiceList(all ? undefined : locale);
30
29
  });
31
- const config = useStore((s) => s.config, isEqual);
30
+ const [showAllLocaleVoice, ttsService, updateConfig] = useStore((s) => [
31
+ s.config.tts.showAllLocaleVoice,
32
+ s.config.tts.ttsService,
33
+ s.setAgentConfig,
34
+ ]);
32
35
 
33
- useEffect(() => {
34
- form.setFieldsValue(config);
35
- }, [config]);
36
+ useAgentSyncSettings(form);
36
37
 
37
- const showAllLocaleVoice = config.tts.showAllLocaleVoice;
38
-
39
- const { edgeVoiceOptions, microsoftVoiceOptions } = voiceList(showAllLocaleVoice);
38
+ const { edgeVoiceOptions, microsoftVoiceOptions } = useMemo(
39
+ () => voiceList(showAllLocaleVoice),
40
+ [showAllLocaleVoice],
41
+ );
40
42
 
41
43
  const tts: ItemGroup = {
42
44
  children: [
@@ -49,7 +51,7 @@ const AgentTTS = memo(() => {
49
51
  {
50
52
  children: <Switch />,
51
53
  desc: t('settingTTS.showAllLocaleVoice.desc'),
52
- hidden: config.tts.ttsService === 'openai',
54
+ hidden: ttsService === 'openai',
53
55
  label: t('settingTTS.showAllLocaleVoice.title'),
54
56
  minWidth: undefined,
55
57
  name: [TTS_SETTING_KEY, 'showAllLocaleVoice'],
@@ -58,7 +60,7 @@ const AgentTTS = memo(() => {
58
60
  {
59
61
  children: <SelectWithTTSPreview options={openaiVoiceOptions} server={'openai'} />,
60
62
  desc: t('settingTTS.voice.desc'),
61
- hidden: config.tts.ttsService !== 'openai',
63
+ hidden: ttsService !== 'openai',
62
64
  label: t('settingTTS.voice.title'),
63
65
  name: [TTS_SETTING_KEY, 'voice', 'openai'],
64
66
  },
@@ -66,7 +68,7 @@ const AgentTTS = memo(() => {
66
68
  children: <SelectWithTTSPreview options={edgeVoiceOptions} server={'edge'} />,
67
69
  desc: t('settingTTS.voice.desc'),
68
70
  divider: false,
69
- hidden: config.tts.ttsService !== 'edge',
71
+ hidden: ttsService !== 'edge',
70
72
  label: t('settingTTS.voice.title'),
71
73
  name: [TTS_SETTING_KEY, 'voice', 'edge'],
72
74
  },
@@ -74,7 +76,7 @@ const AgentTTS = memo(() => {
74
76
  children: <SelectWithTTSPreview options={microsoftVoiceOptions} server={'microsoft'} />,
75
77
  desc: t('settingTTS.voice.desc'),
76
78
  divider: false,
77
- hidden: config.tts.ttsService !== 'microsoft',
79
+ hidden: ttsService !== 'microsoft',
78
80
  label: t('settingTTS.voice.title'),
79
81
  name: [TTS_SETTING_KEY, 'voice', 'microsoft'],
80
82
  },
@@ -0,0 +1,14 @@
1
+ import { FormInstance } from 'antd/es/form/hooks/useForm';
2
+ import isEqual from 'fast-deep-equal';
3
+ import { useLayoutEffect } from 'react';
4
+
5
+ import { useStore } from './store';
6
+
7
+ export const useAgentSyncSettings = (form: FormInstance) => {
8
+ const config = useStore((s) => s.config, isEqual);
9
+ useLayoutEffect(() => {
10
+ form.setFieldsValue(config);
11
+ }, [config]);
12
+
13
+ return config;
14
+ };
@@ -4,10 +4,11 @@ import { createStyles } from 'antd-style';
4
4
  import type { ItemType } from 'antd/es/menu/hooks/useItems';
5
5
  import isEqual from 'fast-deep-equal';
6
6
  import { ArrowRight, Blocks, Store, ToyBrick } from 'lucide-react';
7
- import { memo, useState } from 'react';
7
+ import { memo } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
  import { Flexbox } from 'react-layout-kit';
10
10
 
11
+ import { useWorkspaceModal } from '@/app/(main)/chat/(workspace)/features/useWorkspaceModal';
11
12
  import PluginStore from '@/features/PluginStore';
12
13
  import { useAgentStore } from '@/store/agent';
13
14
  import { agentSelectors } from '@/store/agent/selectors';
@@ -45,7 +46,7 @@ const Tools = memo(() => {
45
46
  .filter((i) => !builtinList.some((b) => b.identifier === i)).length,
46
47
  );
47
48
 
48
- const [open, setOpen] = useState(false);
49
+ const [open, setOpen] = useWorkspaceModal();
49
50
  const { styles } = useStyles();
50
51
 
51
52
  const model = useAgentStore(agentSelectors.currentAgentModel);
@@ -63,7 +63,7 @@ const AgentsSuggest = memo<{ mobile?: boolean }>(({ mobile }) => {
63
63
  const agentList = useMarketStore((s) => s.agentList, isEqual);
64
64
  const { styles } = useStyles();
65
65
 
66
- const agentLength = mobile ? 3 : 4;
66
+ const agentLength = mobile ? 2 : 4;
67
67
 
68
68
  const loadingCards = Array.from({ length: agentLength }).map((_, index) => (
69
69
  <Flexbox className={styles.card} key={index}>
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
7
7
  import { Center, Flexbox } from 'react-layout-kit';
8
8
 
9
9
  import { useGreeting } from '@/hooks/useGreeting';
10
- import { useIsMobile } from '@/hooks/useIsMobile';
10
+ import { useServerConfigStore } from '@/store/serverConfig';
11
11
 
12
12
  import AgentsSuggest from './AgentsSuggest';
13
13
  import QuestionSuggest from './QuestionSuggest';
@@ -42,7 +42,7 @@ const useStyles = createStyles(({ css, responsive }) => ({
42
42
  const InboxWelcome = memo(() => {
43
43
  const { t } = useTranslation('welcome');
44
44
  const { styles } = useStyles();
45
- const mobile = useIsMobile();
45
+ const mobile = useServerConfigStore((s) => s.isMobile);
46
46
  const greeting = useGreeting();
47
47
 
48
48
  return (