@lobehub/chat 0.82.7 → 0.82.9

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 (106) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/next.config.mjs +6 -1
  3. package/package.json +5 -1
  4. package/src/app/chat/{features/Header → (desktop)/features/ChatHeader}/Desktop.tsx +2 -2
  5. package/src/app/chat/{features/Header → (desktop)/features/ChatHeader}/index.tsx +1 -1
  6. package/src/app/chat/(desktop)/features/ChatInput/index.tsx +22 -0
  7. package/src/app/chat/{features/SessionList/Header → (desktop)/features/SessionHeader}/Desktop.tsx +1 -1
  8. package/src/app/chat/{features/SessionList/Header → (desktop)/features/SessionHeader}/index.tsx +1 -1
  9. package/src/app/chat/{features → (desktop)/features}/SessionList/Desktop.tsx +1 -1
  10. package/src/app/chat/(desktop)/features/SessionList/index.tsx +20 -0
  11. package/src/app/chat/{features/Sidebar → (desktop)/features/SideBar}/Desktop.tsx +4 -4
  12. package/src/app/chat/(desktop)/features/SideBar/index.tsx +20 -0
  13. package/src/app/chat/(desktop)/index.tsx +24 -0
  14. package/src/app/chat/{layout.desktop.tsx → (desktop)/layout/Desktop.tsx} +4 -4
  15. package/src/app/chat/(desktop)/layout/index.tsx +25 -0
  16. package/src/app/chat/(mobile)/features/ChatHeader.tsx +1 -0
  17. package/src/app/chat/(mobile)/features/ChatInput.tsx +14 -0
  18. package/src/app/chat/(mobile)/features/SessionList.tsx +12 -0
  19. package/src/app/chat/(mobile)/features/Topics.tsx +12 -0
  20. package/src/app/chat/(mobile)/index.tsx +20 -0
  21. package/src/app/chat/(mobile)/layout.tsx +15 -0
  22. package/src/app/chat/(mobile)/mobile/page.tsx +21 -0
  23. package/src/app/chat/{features/Header → components/ChatHeader}/Mobile.tsx +2 -1
  24. package/src/app/chat/{features/Header → components/ChatHeader}/ShareButton/Preview.tsx +3 -3
  25. package/src/app/chat/{features/Conversation/Input → components/ChatInput}/ActionBar/Token.tsx +10 -7
  26. package/src/app/chat/{features/Conversation/Input → components/ChatInput}/index.tsx +30 -24
  27. package/src/app/chat/components/Inspector/index.tsx +17 -0
  28. package/src/app/chat/{features → components}/SessionList/Mobile.tsx +1 -1
  29. package/src/app/chat/{features → components}/SessionList/index.tsx +3 -10
  30. package/src/app/chat/features/Conversation/index.tsx +8 -4
  31. package/src/app/chat/features/PageTitle.tsx +19 -0
  32. package/src/app/chat/layout.tsx +14 -0
  33. package/src/app/chat/page.tsx +9 -4
  34. package/src/app/chat/settings/(desktop)/Header/index.tsx +13 -0
  35. package/src/app/chat/settings/{layout.desktop.tsx → (desktop)/layout.desktop.tsx} +5 -4
  36. package/src/app/chat/settings/(mobile)/Header.tsx +12 -0
  37. package/src/app/chat/settings/{layout.mobile.tsx → (mobile)/layout.mobile.tsx} +3 -1
  38. package/src/app/chat/settings/{features → components}/Header/index.tsx +4 -13
  39. package/src/app/chat/settings/layout.tsx +14 -0
  40. package/src/app/chat/settings/page.tsx +36 -5
  41. package/src/app/home/Redirect.tsx +29 -0
  42. package/src/app/home/index.tsx +18 -29
  43. package/src/app/market/features/SideBar/AgentInfo/TokenTag.tsx +4 -3
  44. package/src/app/metadata.ts +4 -1
  45. package/src/app/page.tsx +7 -3
  46. package/src/app/welcome/{layout.desktop.tsx → DesktopLayout/Desktop.tsx} +5 -4
  47. package/src/app/welcome/DesktopLayout/index.tsx +15 -0
  48. package/src/app/welcome/{layout.mobile.tsx → MobileLayout.tsx} +6 -3
  49. package/src/app/welcome/features/Banner/index.tsx +2 -0
  50. package/src/app/welcome/features/Footer/index.tsx +2 -0
  51. package/src/app/welcome/layout.tsx +22 -0
  52. package/src/app/welcome/page.tsx +10 -5
  53. package/src/components/PageTitle.tsx +11 -0
  54. package/src/features/AgentSetting/AgentPrompt/index.tsx +3 -6
  55. package/src/hooks/useTokenCount.ts +20 -0
  56. package/src/layout/AppMobileLayout.tsx +15 -24
  57. package/src/prompts/chat.ts +4 -2
  58. package/src/store/session/hooks/useEffectAfterHydrated.ts +11 -6
  59. package/src/store/session/slices/chat/actions/message.ts +1 -1
  60. package/src/store/session/slices/chat/actions/topic.ts +3 -3
  61. package/src/store/session/slices/chat/helpers.ts +3 -4
  62. package/src/store/session/slices/chat/selectors/chat.ts +5 -0
  63. package/src/store/session/slices/chat/selectors/index.ts +9 -5
  64. package/src/store/session/slices/session/action.ts +1 -1
  65. package/src/utils/responsive.ts +19 -0
  66. package/src/utils/tokenizer.ts +5 -0
  67. package/src/app/chat/features/Sidebar/index.tsx +0 -29
  68. package/src/app/chat/index.tsx +0 -54
  69. package/src/app/chat/layout.mobile.tsx +0 -20
  70. package/src/app/chat/mobile/index.tsx +0 -38
  71. package/src/app/chat/mobile/page.tsx +0 -7
  72. package/src/app/chat/settings/index.tsx +0 -51
  73. package/src/app/home/Loading.tsx +0 -23
  74. package/src/app/welcome/index.tsx +0 -39
  75. package/src/store/session/slices/chat/selectors/token.ts +0 -28
  76. /package/src/app/chat/{features/Conversation/Input → (desktop)/features/ChatInput}/Desktop.tsx +0 -0
  77. /package/src/app/chat/{features/SessionList/Header/Mobile.tsx → (mobile)/features/SessionHeader.tsx} +0 -0
  78. /package/src/app/chat/{features/Header → components/ChatHeader}/PluginTag/PluginStatus.tsx +0 -0
  79. /package/src/app/chat/{features/Header → components/ChatHeader}/PluginTag/index.tsx +0 -0
  80. /package/src/app/chat/{features/Header → components/ChatHeader}/ShareButton/Inner.tsx +0 -0
  81. /package/src/app/chat/{features/Header → components/ChatHeader}/ShareButton/index.tsx +0 -0
  82. /package/src/app/chat/{features/Header → components/ChatHeader}/ShareButton/style.ts +0 -0
  83. /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/ActionBar/ActionLeft.tsx +0 -0
  84. /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/ActionBar/ActionRight.tsx +0 -0
  85. /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/Footer/SaveTopic.tsx +0 -0
  86. /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/Footer/index.tsx +0 -0
  87. /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/Mobile.tsx +0 -0
  88. /package/src/app/chat/{features/Sidebar → components/Inspector}/Mobile.tsx +0 -0
  89. /package/src/app/chat/{features/Sidebar → components/Inspector}/SystemRole/Header.tsx +0 -0
  90. /package/src/app/chat/{features/Sidebar → components/Inspector}/SystemRole/index.tsx +0 -0
  91. /package/src/app/chat/{features/Sidebar → components/Inspector}/SystemRole/style.ts +0 -0
  92. /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/DefaultContent.tsx +0 -0
  93. /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/SkeletonList.tsx +0 -0
  94. /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/TopicContent.tsx +0 -0
  95. /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/TopicItem.tsx +0 -0
  96. /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/index.tsx +0 -0
  97. /package/src/app/chat/{features/Sidebar → components/Inspector}/TopicSearchBar/index.tsx +0 -0
  98. /package/src/app/chat/{features → components}/SessionList/CollapseGroup/index.tsx +0 -0
  99. /package/src/app/chat/{features → components}/SessionList/Inbox/index.tsx +0 -0
  100. /package/src/app/chat/{features → components}/SessionList/List/AddButton.tsx +0 -0
  101. /package/src/app/chat/{features → components}/SessionList/List/Item/Actions.tsx +0 -0
  102. /package/src/app/chat/{features → components}/SessionList/List/Item/index.tsx +0 -0
  103. /package/src/app/chat/{features → components}/SessionList/List/SkeletonList.tsx +0 -0
  104. /package/src/app/chat/{features → components}/SessionList/List/index.tsx +0 -0
  105. /package/src/app/chat/settings/{features → (desktop)}/Header/Desktop.tsx +0 -0
  106. /package/src/app/chat/settings/{features → components}/Header/Mobile.tsx +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,48 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.82.9](https://github.com/lobehub/lobe-chat/compare/v0.82.8...v0.82.9)
6
+
7
+ <sup>Released on **2023-10-05**</sup>
8
+
9
+ <br/>
10
+
11
+ <details>
12
+ <summary><kbd>Improvements and Fixes</kbd></summary>
13
+
14
+ </details>
15
+
16
+ <div align="right">
17
+
18
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
19
+
20
+ </div>
21
+
22
+ ### [Version 0.82.8](https://github.com/lobehub/lobe-chat/compare/v0.82.7...v0.82.8)
23
+
24
+ <sup>Released on **2023-09-30**</sup>
25
+
26
+ #### ♻ Code Refactoring
27
+
28
+ - **misc**: Refactor / route to reduce page js size.
29
+
30
+ <br/>
31
+
32
+ <details>
33
+ <summary><kbd>Improvements and Fixes</kbd></summary>
34
+
35
+ #### Code refactoring
36
+
37
+ - **misc**: Refactor / route to reduce page js size ([79f0347](https://github.com/lobehub/lobe-chat/commit/79f0347))
38
+
39
+ </details>
40
+
41
+ <div align="right">
42
+
43
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
44
+
45
+ </div>
46
+
5
47
  ### [Version 0.82.7](https://github.com/lobehub/lobe-chat/compare/v0.82.6...v0.82.7)
6
48
 
7
49
  <sup>Released on **2023-09-30**</sup>
package/next.config.mjs CHANGED
@@ -1,7 +1,12 @@
1
+ import analyzer from '@next/bundle-analyzer';
1
2
  import nextPWA from 'next-pwa';
2
3
 
3
4
  const isProd = process.env.NODE_ENV === 'production';
4
5
 
6
+ const withBundleAnalyzer = analyzer({
7
+ enabled: process.env.ANALYZE === 'true',
8
+ });
9
+
5
10
  const withPWA = nextPWA({
6
11
  dest: 'public',
7
12
  register: true,
@@ -29,4 +34,4 @@ const nextConfig = {
29
34
  },
30
35
  };
31
36
 
32
- export default isProd ? withPWA(nextConfig) : nextConfig;
37
+ export default isProd ? withBundleAnalyzer(withPWA(nextConfig)) : nextConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.82.7",
3
+ "version": "0.82.9",
4
4
  "description": "An open-source, extensible (Function Calling), high-performance chatbot framework. It supports one-click free deployment of your private ChatGPT/LLM web application",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -24,6 +24,7 @@
24
24
  "sideEffects": false,
25
25
  "scripts": {
26
26
  "build": "next build",
27
+ "build:analyze": "ANALYZE=true next build",
27
28
  "dev": "next dev -p 3010",
28
29
  "i18n": "npm run i18n:workflow && lobe-i18n",
29
30
  "i18n:workflow": "ts-node --project ./tsconfig.json scripts/i18nWorkflow/index.ts",
@@ -106,6 +107,7 @@
106
107
  "swr": "^2",
107
108
  "systemjs": "^6",
108
109
  "ts-md5": "^1",
110
+ "ua-parser-js": "^1",
109
111
  "url-join": "^5",
110
112
  "use-merge-value": "^1",
111
113
  "utility-types": "^3",
@@ -117,6 +119,7 @@
117
119
  "@commitlint/cli": "^17",
118
120
  "@lobehub/i18n-cli": "latest",
119
121
  "@lobehub/lint": "latest",
122
+ "@next/bundle-analyzer": "^13",
120
123
  "@next/eslint-plugin-next": "^13",
121
124
  "@testing-library/jest-dom": "^6",
122
125
  "@testing-library/react": "^14",
@@ -127,6 +130,7 @@
127
130
  "@types/react": "^18",
128
131
  "@types/react-dom": "^18",
129
132
  "@types/systemjs": "^6",
133
+ "@types/ua-parser-js": "^0.7",
130
134
  "@types/uuid": "^9",
131
135
  "@umijs/lint": "^4",
132
136
  "@vitest/coverage-v8": "latest",
@@ -12,8 +12,8 @@ import { useSessionChatInit, useSessionStore } from '@/store/session';
12
12
  import { agentSelectors, sessionSelectors } from '@/store/session/selectors';
13
13
  import { pathString } from '@/utils/url';
14
14
 
15
- import PluginTag from './PluginTag';
16
- import ShareButton from './ShareButton';
15
+ import PluginTag from '../../../components/ChatHeader/PluginTag';
16
+ import ShareButton from '../../../components/ChatHeader/ShareButton';
17
17
 
18
18
  const Header = memo(() => {
19
19
  const init = useSessionChatInit();
@@ -1,8 +1,8 @@
1
1
  import { useResponsive } from 'antd-style';
2
2
  import { memo } from 'react';
3
3
 
4
+ import Mobile from '../../../components/ChatHeader/Mobile';
4
5
  import Desktop from './Desktop';
5
- import Mobile from './Mobile';
6
6
 
7
7
  const Header = memo(() => {
8
8
  const { mobile } = useResponsive();
@@ -0,0 +1,22 @@
1
+ import { useResponsive } from 'antd-style';
2
+ import { memo, useState } from 'react';
3
+
4
+ import { ChatInputContent } from '../../../components/ChatInput';
5
+ import Mobile from '../../../components/ChatInput/Mobile';
6
+ import Desktop from './Desktop';
7
+
8
+ const ChatInput = () => {
9
+ const [expand, setExpand] = useState<boolean>(false);
10
+
11
+ const { mobile } = useResponsive();
12
+
13
+ const Render = mobile ? Mobile : Desktop;
14
+
15
+ return (
16
+ <Render expand={expand}>
17
+ <ChatInputContent expand={expand} onExpandChange={setExpand} />
18
+ </Render>
19
+ );
20
+ };
21
+
22
+ export default memo(ChatInput);
@@ -7,7 +7,7 @@ import { Flexbox } from 'react-layout-kit';
7
7
 
8
8
  import { useSessionStore } from '@/store/session';
9
9
 
10
- import SessionSearchBar from '../../SessionSearchBar';
10
+ import SessionSearchBar from '../../../features/SessionSearchBar';
11
11
 
12
12
  export const useStyles = createStyles(({ css, token }) => ({
13
13
  logo: css`
@@ -1,8 +1,8 @@
1
1
  import { useResponsive } from 'antd-style';
2
2
  import { memo } from 'react';
3
3
 
4
+ import Mobile from '../../../(mobile)/features/SessionHeader';
4
5
  import Desktop from './Desktop';
5
- import Mobile from './Mobile';
6
6
 
7
7
  const Header = memo(() => {
8
8
  const { mobile } = useResponsive();
@@ -4,7 +4,7 @@ import { ReactNode, memo } from 'react';
4
4
 
5
5
  import FolderPanel from '@/features/FolderPanel';
6
6
 
7
- import Header from './Header';
7
+ import Header from '../SessionHeader';
8
8
 
9
9
  const useStyles = createStyles(({ stylish }) => stylish.noScrollbar);
10
10
 
@@ -0,0 +1,20 @@
1
+ import { useResponsive } from 'antd-style';
2
+ import { memo } from 'react';
3
+
4
+ import { SessionListContent } from '../../../components/SessionList';
5
+ import Mobile from '../../../components/SessionList/Mobile';
6
+ import Desktop from './Desktop';
7
+
8
+ const ResponsiveSessionList = memo(() => {
9
+ const { mobile } = useResponsive();
10
+
11
+ const Wrapper = mobile ? Mobile : Desktop;
12
+
13
+ return (
14
+ <Wrapper>
15
+ <SessionListContent />
16
+ </Wrapper>
17
+ );
18
+ });
19
+
20
+ export default ResponsiveSessionList;
@@ -6,9 +6,9 @@ import SafeSpacing from '@/components/SafeSpacing';
6
6
  import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
7
7
  import { useGlobalStore } from '@/store/global';
8
8
  import { useSessionStore } from '@/store/session';
9
- import { sessionSelectors } from '@/store/session/slices/session/selectors';
9
+ import { sessionSelectors } from '@/store/session/selectors';
10
10
 
11
- import SystemRole from './SystemRole';
11
+ import SystemRole from '../../../components/Inspector/SystemRole';
12
12
 
13
13
  const useStyles = createStyles(({ css, token }) => ({
14
14
  content: css`
@@ -23,7 +23,7 @@ const useStyles = createStyles(({ css, token }) => ({
23
23
  `,
24
24
  }));
25
25
 
26
- const SideBar = memo<{ children: ReactNode }>(({ children }) => {
26
+ const Desktop = memo<{ children: ReactNode }>(({ children }) => {
27
27
  const { styles } = useStyles();
28
28
  const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
29
29
  s.preference.showChatSideBar,
@@ -55,4 +55,4 @@ const SideBar = memo<{ children: ReactNode }>(({ children }) => {
55
55
  );
56
56
  });
57
57
 
58
- export default SideBar;
58
+ export default Desktop;
@@ -0,0 +1,20 @@
1
+ import { useResponsive } from 'antd-style';
2
+ import { memo } from 'react';
3
+
4
+ import { InspectorContent } from '../../../components/Inspector';
5
+ import Mobile from '../../../components/Inspector/Mobile';
6
+ import Desktop from './Desktop';
7
+
8
+ const SideBar = memo(() => {
9
+ const { mobile } = useResponsive();
10
+
11
+ const Render = mobile ? Mobile : Desktop;
12
+
13
+ return (
14
+ <Render>
15
+ <InspectorContent />
16
+ </Render>
17
+ );
18
+ });
19
+
20
+ export default SideBar;
@@ -0,0 +1,24 @@
1
+ 'use client';
2
+
3
+ import { memo } from 'react';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import Conversation from '../features/Conversation';
7
+ import PageTitle from '../features/PageTitle';
8
+ import ChatHeader from './features/ChatHeader';
9
+ import ChatInput from './features/ChatInput';
10
+ import SideBar from './features/SideBar';
11
+
12
+ const DesktopPage = memo(() => {
13
+ return (
14
+ <>
15
+ <PageTitle />
16
+ <ChatHeader />
17
+ <Flexbox flex={1} height={'calc(100vh - 64px)'} horizontal>
18
+ <Conversation chatInput={<ChatInput />} />
19
+ <SideBar />
20
+ </Flexbox>
21
+ </>
22
+ );
23
+ });
24
+ export default DesktopPage;
@@ -5,14 +5,14 @@ import AppLayout from '@/layout/AppLayout';
5
5
  import { useSwitchSideBarOnInit } from '@/store/global';
6
6
  import { SidebarTabKey } from '@/store/global/initialState';
7
7
 
8
- import { Sessions } from './features/SessionList';
8
+ import ResponsiveSessionList from '../features/SessionList';
9
9
 
10
- const ChatLayout = memo<PropsWithChildren>(({ children }) => {
10
+ const Desktop = memo<PropsWithChildren>(({ children }) => {
11
11
  useSwitchSideBarOnInit(SidebarTabKey.Chat);
12
12
 
13
13
  return (
14
14
  <AppLayout>
15
- <Sessions />
15
+ <ResponsiveSessionList />
16
16
  <Flexbox
17
17
  flex={1}
18
18
  height={'100vh'}
@@ -25,4 +25,4 @@ const ChatLayout = memo<PropsWithChildren>(({ children }) => {
25
25
  );
26
26
  });
27
27
 
28
- export default ChatLayout;
28
+ export default Desktop;
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+
3
+ import { useResponsive } from 'antd-style';
4
+ import { PropsWithChildren, memo } from 'react';
5
+
6
+ import { useEffectAfterSessionHydrated } from '@/store/session/hooks';
7
+
8
+ import MobileLayout from '../../(mobile)/layout';
9
+ import DesktopLayout from './Desktop';
10
+
11
+ const Chat = memo<PropsWithChildren>(({ children }) => {
12
+ const { mobile } = useResponsive();
13
+
14
+ const RenderLayout = mobile ? MobileLayout : DesktopLayout;
15
+
16
+ useEffectAfterSessionHydrated(
17
+ (store) => {
18
+ store.setState({ isMobile: mobile });
19
+ },
20
+ [mobile],
21
+ );
22
+
23
+ return <RenderLayout>{children}</RenderLayout>;
24
+ });
25
+ export default Chat;
@@ -0,0 +1 @@
1
+ export { default } from '../../components/ChatHeader/Mobile';
@@ -0,0 +1,14 @@
1
+ import { memo } from 'react';
2
+
3
+ import { ChatInputContent } from '../../components/ChatInput';
4
+ import Mobile from '../../components/ChatInput/Mobile';
5
+
6
+ const ChatInput = () => {
7
+ return (
8
+ <Mobile>
9
+ <ChatInputContent mobile />
10
+ </Mobile>
11
+ );
12
+ };
13
+
14
+ export default memo(ChatInput);
@@ -0,0 +1,12 @@
1
+ import { memo } from 'react';
2
+
3
+ import { SessionListContent } from '../../components/SessionList';
4
+ import Wrapper from '../../components/SessionList/Mobile';
5
+
6
+ const SessionList = memo(() => (
7
+ <Wrapper>
8
+ <SessionListContent />
9
+ </Wrapper>
10
+ ));
11
+
12
+ export default SessionList;
@@ -0,0 +1,12 @@
1
+ import { memo } from 'react';
2
+
3
+ import { InspectorContent } from '../../components/Inspector';
4
+ import Mobile from '../../components/Inspector/Mobile';
5
+
6
+ const Topics = memo(() => (
7
+ <Mobile>
8
+ <InspectorContent />
9
+ </Mobile>
10
+ ));
11
+
12
+ export default Topics;
@@ -0,0 +1,20 @@
1
+ 'use client';
2
+
3
+ import { memo } from 'react';
4
+
5
+ import AppMobileLayout from '@/layout/AppMobileLayout';
6
+
7
+ import PageTitle from '../features/PageTitle';
8
+ import SessionHeader from './features/SessionHeader';
9
+ import SessionList from './features/SessionList';
10
+
11
+ const ChatMobilePage = memo(() => {
12
+ return (
13
+ <AppMobileLayout navBar={<SessionHeader />} showTabBar>
14
+ <PageTitle />
15
+ <SessionList />
16
+ </AppMobileLayout>
17
+ );
18
+ });
19
+
20
+ export default ChatMobilePage;
@@ -0,0 +1,15 @@
1
+ 'use client';
2
+
3
+ import { PropsWithChildren, memo } from 'react';
4
+
5
+ import { useEffectAfterSessionHydrated } from '@/store/session';
6
+
7
+ const ChatMobileLayout = memo<PropsWithChildren>(({ children }) => {
8
+ useEffectAfterSessionHydrated((store) => {
9
+ store.setState({ isMobile: true });
10
+ }, []);
11
+
12
+ return children;
13
+ });
14
+
15
+ export default ChatMobileLayout;
@@ -0,0 +1,21 @@
1
+ 'use client';
2
+
3
+ import { memo } from 'react';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import AppMobileLayout from '@/layout/AppMobileLayout';
7
+
8
+ import Conversation from '../../features/Conversation';
9
+ import Header from '../features/ChatHeader';
10
+ import ChatInput from '../features/ChatInput';
11
+ import Topics from '../features/Topics';
12
+
13
+ const Chat = memo(() => (
14
+ <AppMobileLayout navBar={<Header />}>
15
+ <Flexbox height={'calc(100vh - 44px)'} horizontal>
16
+ <Conversation chatInput={<ChatInput />} mobile />
17
+ <Topics />
18
+ </Flexbox>
19
+ </AppMobileLayout>
20
+ ));
21
+ export default Chat;
@@ -4,13 +4,14 @@ import { useRouter } from 'next/navigation';
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
- import ShareButton from '@/app/chat/features/Header/ShareButton';
8
7
  import { MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
9
8
  import { useGlobalStore } from '@/store/global';
10
9
  import { useSessionStore } from '@/store/session';
11
10
  import { agentSelectors, sessionSelectors } from '@/store/session/selectors';
12
11
  import { pathString } from '@/utils/url';
13
12
 
13
+ import ShareButton from './ShareButton';
14
+
14
15
  const MobileHeader = memo(() => {
15
16
  const { t } = useTranslation('common');
16
17
  const router = useRouter();
@@ -6,14 +6,14 @@ import { toJpeg, toPng, toSvg } from 'html-to-image';
6
6
  import { memo, useCallback, useState } from 'react';
7
7
  import { useTranslation } from 'react-i18next';
8
8
  import { Flexbox } from 'react-layout-kit';
9
+ import ChatList from 'src/app/chat/features/Conversation/ChatList';
9
10
 
10
- import pkg from '@/../package.json';
11
- import ChatList from '@/app/chat/features/Conversation/ChatList';
12
- import PluginTag from '@/app/chat/features/Header/PluginTag';
11
+ import PluginTag from '@/app/chat/components/ChatHeader/PluginTag';
13
12
  import { useSessionStore } from '@/store/session';
14
13
  import { agentSelectors } from '@/store/session/slices/agentConfig';
15
14
  import { sessionSelectors } from '@/store/session/slices/session/selectors';
16
15
 
16
+ import pkg from '../../../../../../package.json';
17
17
  import { useStyles } from './style';
18
18
 
19
19
  export enum ImageType {
@@ -1,24 +1,27 @@
1
1
  import { TokenTag, Tooltip } from '@lobehub/ui';
2
- import { encode } from 'gpt-tokenizer';
3
- import { memo, useMemo } from 'react';
2
+ import { memo } from 'react';
4
3
  import { useTranslation } from 'react-i18next';
5
4
 
6
5
  import { ModelTokens } from '@/const/modelTokens';
6
+ import { useTokenCount } from '@/hooks/useTokenCount';
7
7
  import { useSessionStore } from '@/store/session';
8
8
  import { agentSelectors, chatSelectors } from '@/store/session/selectors';
9
9
 
10
10
  const Token = memo<{ input: string }>(({ input }) => {
11
11
  const { t } = useTranslation('common');
12
12
 
13
- const inputTokenCount = useMemo(() => encode(input).length, [input]);
13
+ const inputTokenCount = useTokenCount(input);
14
14
 
15
- const [totalToken, systemRoleToken, chatsToken, model] = useSessionStore((s) => [
16
- chatSelectors.totalTokenCount(s),
17
- chatSelectors.systemRoleTokenCount(s),
18
- chatSelectors.chatsTokenCount(s),
15
+ const [messageString, systemRole, model] = useSessionStore((s) => [
16
+ chatSelectors.chatsMessageString(s),
17
+ agentSelectors.currentAgentSystemRole(s),
19
18
  agentSelectors.currentAgentModel(s),
20
19
  ]);
21
20
 
21
+ const systemRoleToken = useTokenCount(systemRole);
22
+ const chatsToken = useTokenCount(messageString);
23
+
24
+ const totalToken = systemRoleToken + chatsToken;
22
25
  return (
23
26
  <Tooltip placement={'bottom'} title={t('tokenDetail', { chatsToken, systemRoleToken })}>
24
27
  <TokenTag
@@ -1,6 +1,7 @@
1
1
  import { ChatInputArea } from '@lobehub/ui';
2
2
  import { useResponsive } from 'antd-style';
3
- import { memo, useState } from 'react';
3
+ import dynamic from 'next/dynamic';
4
+ import { Suspense, memo, useState } from 'react';
4
5
  import { useTranslation } from 'react-i18next';
5
6
 
6
7
  import { CHAT_TEXTAREA_HEIGHT } from '@/const/layoutTokens';
@@ -8,32 +9,39 @@ import { useSessionStore } from '@/store/session';
8
9
 
9
10
  import ActionLeft from './ActionBar/ActionLeft';
10
11
  import ActionsRight from './ActionBar/ActionRight';
11
- import Token from './ActionBar/Token';
12
- import Desktop from './Desktop';
13
12
  import Footer from './Footer';
14
- import Mobile from './Mobile';
15
13
 
16
- const ChatInput = () => {
17
- const { t } = useTranslation('common');
18
- const [expand, setExpand] = useState<boolean>(false);
19
- const [message, setMessage] = useState('');
20
- const { mobile } = useResponsive();
14
+ const Token = dynamic(() => import('./ActionBar/Token'), { ssr: false });
21
15
 
22
- const [isLoading, sendMessage, stopGenerateMessage] = useSessionStore((s) => [
23
- !!s.chatLoadingId,
24
- s.sendMessage,
25
- s.stopGenerateMessage,
26
- ]);
16
+ interface ChatContentProps {
17
+ expand?: boolean;
18
+ mobile?: boolean;
19
+ onExpandChange?: (expand: boolean) => void;
20
+ }
27
21
 
28
- const Render = mobile ? Mobile : Desktop;
22
+ export const ChatInputContent = memo<ChatContentProps>(
23
+ ({ expand, onExpandChange, mobile: defaultMobile }) => {
24
+ const { t } = useTranslation('common');
29
25
 
30
- return (
31
- <Render expand={expand}>
26
+ const [message, setMessage] = useState('');
27
+ const { mobile: runtimeMobile } = useResponsive();
28
+
29
+ const mobile = runtimeMobile || defaultMobile;
30
+
31
+ const [isLoading, sendMessage, stopGenerateMessage] = useSessionStore((s) => [
32
+ !!s.chatLoadingId,
33
+ s.sendMessage,
34
+ s.stopGenerateMessage,
35
+ ]);
36
+
37
+ return (
32
38
  <ChatInputArea
33
39
  actions={
34
40
  <>
35
41
  <ActionLeft />
36
- <Token input={message} />
42
+ <Suspense>
43
+ <Token input={message} />
44
+ </Suspense>
37
45
  </>
38
46
  }
39
47
  actionsRight={<ActionsRight />}
@@ -41,7 +49,7 @@ const ChatInput = () => {
41
49
  footer={<Footer />}
42
50
  loading={isLoading}
43
51
  minHeight={mobile ? 0 : CHAT_TEXTAREA_HEIGHT}
44
- onExpandChange={setExpand}
52
+ onExpandChange={onExpandChange}
45
53
  onInputChange={setMessage}
46
54
  onSend={sendMessage}
47
55
  onStop={stopGenerateMessage}
@@ -52,8 +60,6 @@ const ChatInput = () => {
52
60
  }}
53
61
  value={message}
54
62
  />
55
- </Render>
56
- );
57
- };
58
-
59
- export default memo(ChatInput);
63
+ );
64
+ },
65
+ );
@@ -0,0 +1,17 @@
1
+ import { Flexbox } from 'react-layout-kit';
2
+
3
+ import { Topic } from './Topic';
4
+ import TopicSearchBar from './TopicSearchBar';
5
+
6
+ export const InspectorContent = () => {
7
+ return (
8
+ <Flexbox height={'100%'} style={{ overflow: 'hidden' }}>
9
+ <Flexbox padding={16}>
10
+ <TopicSearchBar />
11
+ </Flexbox>
12
+ <Flexbox gap={16} paddingInline={16} style={{ overflowY: 'auto', position: 'relative' }}>
13
+ <Topic />
14
+ </Flexbox>
15
+ </Flexbox>
16
+ );
17
+ };
@@ -1,6 +1,6 @@
1
1
  import { ReactNode, memo } from 'react';
2
2
 
3
- import SessionSearchBar from '../SessionSearchBar';
3
+ import SessionSearchBar from '../../features/SessionSearchBar';
4
4
 
5
5
  const Sessions = memo<{ children: ReactNode }>(({ children }) => {
6
6
  return (
@@ -1,20 +1,13 @@
1
1
  import { CollapseProps } from 'antd';
2
- import { useResponsive } from 'antd-style';
3
2
  import { memo, useMemo } from 'react';
4
3
  import { useTranslation } from 'react-i18next';
5
4
 
6
5
  import CollapseGroup from './CollapseGroup';
7
- import Desktop from './Desktop';
8
6
  import Inbox from './Inbox';
9
7
  import SessionList from './List';
10
- import Mobile from './Mobile';
11
8
 
12
- export const Sessions = memo(() => {
13
- const { mobile } = useResponsive();
9
+ export const SessionListContent = memo(() => {
14
10
  const { t } = useTranslation('common');
15
-
16
- const Render = mobile ? Mobile : Desktop;
17
-
18
11
  const items: CollapseProps['items'] = useMemo(
19
12
  () => [
20
13
  {
@@ -27,9 +20,9 @@ export const Sessions = memo(() => {
27
20
  );
28
21
 
29
22
  return (
30
- <Render>
23
+ <>
31
24
  <Inbox />
32
25
  <CollapseGroup defaultActiveKey={['sessionList']} items={items} />
33
- </Render>
26
+ </>
34
27
  );
35
28
  });