@lobehub/chat 0.84.0-beta.1 → 0.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/lighthouse-badger-advanced.yml +92 -0
- package/.github/workflows/release.yml +0 -3
- package/.github/workflows/sync.yml +9 -2
- package/.releaserc.js +1 -14
- package/CHANGELOG.md +41 -4
- package/README.md +21 -0
- package/README.zh-CN.md +21 -0
- package/docs/Home.md +1 -0
- package/docs/Lighthouse.md +65 -0
- package/docs/Lighthouse.zh-CN.md +65 -0
- package/docs/_Sidebar.md +1 -0
- package/locales/en_US/common.json +5 -0
- package/locales/ru_RU/common.json +5 -0
- package/locales/zh_CN/common.json +5 -0
- package/locales/zh_TW/common.json +5 -0
- package/next.config.mjs +0 -3
- package/package.json +4 -4
- package/src/app/chat/(desktop)/features/{ChatHeader/Desktop.tsx → ChatHeader.tsx} +2 -2
- package/src/app/chat/(desktop)/features/{ChatInput/Desktop.tsx → ChatInput.tsx} +5 -7
- package/src/app/chat/(desktop)/features/{SessionHeader/Desktop.tsx → SessionHeader.tsx} +1 -1
- package/src/app/chat/(desktop)/features/{SessionList/Desktop.tsx → SessionList.tsx} +5 -4
- package/src/app/chat/(desktop)/features/{SideBar/Desktop.tsx → SideBar.tsx} +5 -4
- package/src/app/chat/(desktop)/index.tsx +14 -8
- package/src/app/chat/(desktop)/{layout/Desktop.tsx → layout.desktop.tsx} +7 -8
- package/src/app/chat/(desktop)/layout.responsive.tsx +12 -0
- package/src/app/chat/(mobile)/features/ChatHeader.tsx +54 -1
- package/src/app/chat/(mobile)/features/ChatInput.tsx +28 -8
- package/src/app/chat/(mobile)/features/SessionList.tsx +13 -8
- package/src/app/chat/{components/Inspector/Mobile.tsx → (mobile)/features/TopicList.tsx} +6 -4
- package/src/app/chat/(mobile)/index.tsx +3 -5
- package/src/app/chat/(mobile)/layout.mobile.tsx +17 -0
- package/src/app/chat/(mobile)/mobile/index.tsx +19 -0
- package/src/app/chat/(mobile)/mobile/layout.mobile.tsx +11 -0
- package/src/app/chat/(mobile)/mobile/page.tsx +2 -20
- package/src/app/chat/{components → features}/ChatHeader/ShareButton/Preview.tsx +25 -9
- package/src/app/chat/{components → features}/ChatHeader/ShareButton/style.ts +7 -7
- package/src/app/chat/{components/ChatInput → features/ChatInputContent}/index.tsx +3 -1
- package/src/app/chat/{components/SessionList → features/SessionListContent}/Inbox/index.tsx +7 -5
- package/src/app/chat/{components/SessionList → features/SessionListContent}/index.tsx +3 -1
- package/src/app/chat/{components/Inspector → features/TopicListContent}/index.tsx +3 -1
- package/src/app/chat/page.tsx +3 -1
- package/src/app/chat/settings/(desktop)/index.tsx +14 -0
- package/src/app/chat/settings/(desktop)/layout.desktop.tsx +10 -15
- package/src/app/chat/settings/(desktop)/layout.responsive.tsx +12 -0
- package/src/app/chat/settings/(mobile)/index.tsx +14 -0
- package/src/app/chat/settings/(mobile)/layout.mobile.tsx +4 -8
- package/src/app/chat/settings/features/EditPage.tsx +38 -0
- package/src/app/chat/settings/page.tsx +9 -33
- package/src/app/market/(desktop)/{AgentDetail/Desktop.tsx → features/AgentDetail.tsx} +5 -3
- package/src/app/market/(desktop)/index.tsx +12 -0
- package/src/app/market/(desktop)/{layout/Desktop.tsx → layout.desktop.tsx} +5 -5
- package/src/app/market/(desktop)/layout.responsive.tsx +16 -0
- package/src/app/market/{components/AgentDetail/Mobile.tsx → (mobile)/features/AgentDetail.tsx} +6 -4
- package/src/app/market/(mobile)/index.tsx +12 -0
- package/src/app/market/(mobile)/layout.mobile.tsx +5 -5
- package/src/app/market/{components/AgentDetail → features/AgentDetailContent}/AgentInfo/Header.tsx +1 -0
- package/src/app/market/{components/AgentDetail → features/AgentDetailContent}/index.tsx +3 -1
- package/src/app/market/features/TagList/index.tsx +2 -1
- package/src/app/market/page.tsx +8 -5
- package/src/app/settings/{features/Header/Desktop.tsx → (desktop)/features/Header.tsx} +2 -2
- package/src/app/settings/(desktop)/index.tsx +17 -0
- package/src/app/settings/{layout.desktop/Desktop.tsx → (desktop)/layout.desktop.tsx} +10 -9
- package/src/app/settings/(desktop)/layout.responsive.tsx +14 -0
- package/src/app/settings/{mobile → (mobile)/features}/ExtraList.tsx +1 -1
- package/src/app/settings/(mobile)/features/Header/Home.tsx +8 -0
- package/src/app/settings/{features/Header/Mobile.tsx → (mobile)/features/Header/index.tsx} +1 -0
- package/src/app/settings/(mobile)/index.tsx +3 -0
- package/src/app/settings/(mobile)/layout.mobile.tsx +19 -0
- package/src/app/settings/{mobile → (mobile)/mobile}/index.tsx +9 -9
- package/src/app/settings/(mobile)/mobile/layout.mobile.tsx +14 -0
- package/src/app/settings/agent/Agent.tsx +30 -0
- package/src/app/settings/agent/index.tsx +23 -0
- package/src/app/settings/agent/layout.tsx +1 -0
- package/src/app/settings/agent/page.tsx +2 -31
- package/src/app/settings/common/index.tsx +23 -0
- package/src/app/settings/common/layout.tsx +1 -0
- package/src/app/settings/common/page.tsx +2 -14
- package/src/app/settings/features/SideBar/index.tsx +2 -0
- package/src/app/settings/features/UpgradeAlert.tsx +32 -0
- package/src/app/settings/layout.server.tsx +12 -0
- package/src/app/settings/llm/index.tsx +23 -0
- package/src/app/settings/llm/layout.tsx +1 -0
- package/src/app/settings/llm/page.tsx +2 -14
- package/src/app/settings/page.tsx +14 -1
- package/src/app/welcome/(desktop)/features/Showcase.tsx +23 -0
- package/src/app/welcome/(desktop)/index.tsx +19 -0
- package/src/app/welcome/{DesktopLayout/Desktop.tsx → (desktop)/layout.desktop.tsx} +4 -4
- package/src/app/welcome/(desktop)/layout.responsive.tsx +14 -0
- package/src/app/welcome/(mobile)/features/Header.tsx +6 -0
- package/src/app/welcome/(mobile)/features/Showcase.tsx +16 -0
- package/src/app/welcome/(mobile)/index.tsx +10 -0
- package/src/app/welcome/(mobile)/layout.mobile.tsx +20 -0
- package/src/app/welcome/features/Banner/Hero.tsx +2 -3
- package/src/app/welcome/features/Banner/index.tsx +34 -31
- package/src/app/welcome/features/Banner/style.ts +10 -1
- package/src/app/welcome/page.tsx +9 -7
- package/src/components/ResponsiveIndex.tsx +17 -0
- package/src/const/version.ts +6 -0
- package/src/features/MobileTabBar/index.tsx +1 -1
- package/src/features/SideBar/BottomActions.tsx +98 -79
- package/src/layout/{AppLayout.tsx → AppLayout.desktop.tsx} +2 -2
- package/src/layout/{AppMobileLayout.tsx → AppLayout.mobile.tsx} +2 -2
- package/src/layout/GlobalLayout/StoreHydration.tsx +15 -1
- package/src/layout/ResponsiveLayout.client.tsx +18 -0
- package/src/{components/ResponsiveLayout.tsx → layout/ResponsiveLayout.server.tsx} +4 -3
- package/src/locales/default/common.ts +5 -0
- package/src/services/latestVersion.ts +11 -1
- package/src/store/global/initialState.ts +11 -9
- package/src/store/global/slices/common.ts +12 -0
- package/src/store/session/slices/session/initialState.ts +2 -2
- package/.dockerignore +0 -10
- package/Dockerfile +0 -46
- package/src/app/chat/(desktop)/features/ChatHeader/index.tsx +0 -14
- package/src/app/chat/(desktop)/features/ChatInput/index.tsx +0 -22
- package/src/app/chat/(desktop)/features/SessionHeader/index.tsx +0 -14
- package/src/app/chat/(desktop)/features/SessionList/index.tsx +0 -20
- package/src/app/chat/(desktop)/features/SideBar/index.tsx +0 -20
- package/src/app/chat/(desktop)/layout/index.tsx +0 -25
- package/src/app/chat/(mobile)/features/Topics.tsx +0 -12
- package/src/app/chat/(mobile)/layout.tsx +0 -15
- package/src/app/chat/components/ChatHeader/Mobile.tsx +0 -54
- package/src/app/chat/components/ChatInput/Mobile.tsx +0 -35
- package/src/app/chat/components/SessionList/Mobile.tsx +0 -16
- package/src/app/chat/layout.tsx +0 -15
- package/src/app/chat/settings/layout.tsx +0 -14
- package/src/app/market/(desktop)/AgentDetail/index.tsx +0 -16
- package/src/app/market/(desktop)/Header/index.tsx +0 -13
- package/src/app/market/(desktop)/layout/index.tsx +0 -17
- package/src/app/market/(mobile)/AgentDetail.tsx +0 -12
- package/src/app/market/layout.tsx +0 -13
- package/src/app/settings/features/Header/index.tsx +0 -14
- package/src/app/settings/layout.desktop/index.tsx +0 -32
- package/src/app/settings/layout.mobile.tsx +0 -16
- package/src/app/settings/layout.tsx +0 -15
- package/src/app/settings/mobile/page.tsx +0 -7
- package/src/app/welcome/DesktopLayout/index.tsx +0 -15
- package/src/app/welcome/MobileLayout.tsx +0 -23
- package/src/app/welcome/layout.tsx +0 -22
- /package/src/app/chat/{components → features}/ChatHeader/PluginTag/PluginStatus.tsx +0 -0
- /package/src/app/chat/{components → features}/ChatHeader/PluginTag/index.tsx +0 -0
- /package/src/app/chat/{components → features}/ChatHeader/ShareButton/Inner.tsx +0 -0
- /package/src/app/chat/{components → features}/ChatHeader/ShareButton/index.tsx +0 -0
- /package/src/app/chat/{components/ChatInput → features/ChatInputContent}/ActionBar/ActionLeft.tsx +0 -0
- /package/src/app/chat/{components/ChatInput → features/ChatInputContent}/ActionBar/ActionRight.tsx +0 -0
- /package/src/app/chat/{components/ChatInput → features/ChatInputContent}/ActionBar/Token.tsx +0 -0
- /package/src/app/chat/{components/ChatInput → features/ChatInputContent}/Footer/SaveTopic.tsx +0 -0
- /package/src/app/chat/{components/ChatInput → features/ChatInputContent}/Footer/index.tsx +0 -0
- /package/src/app/chat/features/{PageTitle.tsx → PageTitle/index.tsx} +0 -0
- /package/src/app/chat/{components/SessionList → features/SessionListContent}/CollapseGroup/index.tsx +0 -0
- /package/src/app/chat/{components/SessionList → features/SessionListContent}/List/AddButton.tsx +0 -0
- /package/src/app/chat/{components/SessionList → features/SessionListContent}/List/Item/Actions.tsx +0 -0
- /package/src/app/chat/{components/SessionList → features/SessionListContent}/List/Item/index.tsx +0 -0
- /package/src/app/chat/{components/SessionList → features/SessionListContent}/List/SkeletonList.tsx +0 -0
- /package/src/app/chat/{components/SessionList → features/SessionListContent}/List/index.tsx +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/SystemRole/Header.tsx +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/SystemRole/index.tsx +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/SystemRole/style.ts +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/Topic/DefaultContent.tsx +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/Topic/SkeletonList.tsx +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/Topic/TopicContent.tsx +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/Topic/TopicItem.tsx +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/Topic/index.tsx +0 -0
- /package/src/app/chat/{components/Inspector → features/TopicListContent}/TopicSearchBar/index.tsx +0 -0
- /package/src/app/market/(desktop)/{Header/Desktop.tsx → features/Header.tsx} +0 -0
- /package/src/app/market/(mobile)/{Header.tsx → features/Header.tsx} +0 -0
- /package/src/app/market/{components/AgentDetail → features/AgentDetailContent}/AgentInfo/Comment.tsx +0 -0
- /package/src/app/market/{components/AgentDetail → features/AgentDetailContent}/AgentInfo/Loading.tsx +0 -0
- /package/src/app/market/{components/AgentDetail → features/AgentDetailContent}/AgentInfo/TokenTag.tsx +0 -0
- /package/src/app/market/{components/AgentDetail → features/AgentDetailContent}/AgentInfo/index.tsx +0 -0
- /package/src/app/market/{components/AgentDetail → features/AgentDetailContent}/AgentInfo/style.ts +0 -0
- /package/src/app/welcome/{features/Footer/index.tsx → (desktop)/features/Footer.tsx} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ActionIcon, DiscordIcon, Icon } from '@lobehub/ui';
|
|
2
|
-
import { Dropdown, MenuProps, Upload } from 'antd';
|
|
2
|
+
import { Badge, ConfigProvider, Dropdown, MenuProps, Upload } from 'antd';
|
|
3
3
|
import {
|
|
4
4
|
Feather,
|
|
5
5
|
FileClock,
|
|
@@ -11,13 +11,14 @@ import {
|
|
|
11
11
|
Settings2,
|
|
12
12
|
} from 'lucide-react';
|
|
13
13
|
import { useRouter } from 'next/navigation';
|
|
14
|
-
import { memo
|
|
14
|
+
import { memo } from 'react';
|
|
15
15
|
import { useTranslation } from 'react-i18next';
|
|
16
|
+
import { Flexbox } from 'react-layout-kit';
|
|
16
17
|
|
|
17
18
|
import { ABOUT, CHANGELOG, DISCORD, FEEDBACK, GITHUB } from '@/const/url';
|
|
18
19
|
import { useExportConfig } from '@/hooks/useExportConfig';
|
|
19
20
|
import { useImportConfig } from '@/hooks/useImportConfig';
|
|
20
|
-
import { GlobalStore } from '@/store/global';
|
|
21
|
+
import { GlobalStore, useGlobalStore } from '@/store/global';
|
|
21
22
|
import { SidebarTabKey } from '@/store/global/initialState';
|
|
22
23
|
|
|
23
24
|
export interface BottomActionProps {
|
|
@@ -31,83 +32,91 @@ const BottomActions = memo<BottomActionProps>(({ tab, setTab }) => {
|
|
|
31
32
|
const { exportSessions, exportSettings, exportAll, exportAgents } = useExportConfig();
|
|
32
33
|
const { importConfig } = useImportConfig();
|
|
33
34
|
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
{
|
|
66
|
-
|
|
67
|
-
label: <div>{t('exportType.all')}</div>,
|
|
68
|
-
onClick: exportAll,
|
|
69
|
-
},
|
|
70
|
-
],
|
|
71
|
-
icon: <Icon icon={HardDriveDownload} />,
|
|
72
|
-
key: 'export',
|
|
73
|
-
label: t('export'),
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
type: 'divider',
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
icon: <Icon icon={Feather} />,
|
|
80
|
-
key: 'feedback',
|
|
81
|
-
label: t('feedback'),
|
|
82
|
-
onClick: () => window.open(FEEDBACK, '__blank'),
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
icon: <Icon icon={FileClock} />,
|
|
86
|
-
key: 'changelog',
|
|
87
|
-
label: t('changelog'),
|
|
88
|
-
onClick: () => window.open(CHANGELOG, '__blank'),
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
icon: <Icon icon={Heart} />,
|
|
92
|
-
key: 'about',
|
|
93
|
-
label: t('about'),
|
|
94
|
-
onClick: () => window.open(ABOUT, '__blank'),
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
type: 'divider',
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
icon: <Icon icon={Settings} />,
|
|
101
|
-
key: 'setting',
|
|
102
|
-
label: t('setting'),
|
|
103
|
-
onClick: () => {
|
|
104
|
-
setTab(SidebarTabKey.Setting);
|
|
105
|
-
router.push('/settings');
|
|
35
|
+
const [hasNewVersion, useCheckLatestVersion] = useGlobalStore((s) => [
|
|
36
|
+
s.hasNewVersion,
|
|
37
|
+
s.useCheckLatestVersion,
|
|
38
|
+
]);
|
|
39
|
+
|
|
40
|
+
useCheckLatestVersion();
|
|
41
|
+
|
|
42
|
+
const items: MenuProps['items'] = [
|
|
43
|
+
{
|
|
44
|
+
icon: <Icon icon={HardDriveUpload} />,
|
|
45
|
+
key: 'import',
|
|
46
|
+
label: (
|
|
47
|
+
<Upload maxCount={1} onChange={importConfig} showUploadList={false}>
|
|
48
|
+
{t('import')}
|
|
49
|
+
</Upload>
|
|
50
|
+
),
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
children: [
|
|
54
|
+
{
|
|
55
|
+
key: 'allAgent',
|
|
56
|
+
label: <div>{t('exportType.allAgent')}</div>,
|
|
57
|
+
onClick: exportAgents,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
key: 'allAgentWithMessage',
|
|
61
|
+
label: <div>{t('exportType.allAgentWithMessage')}</div>,
|
|
62
|
+
onClick: exportSessions,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
key: 'globalSetting',
|
|
66
|
+
label: <div>{t('exportType.globalSetting')}</div>,
|
|
67
|
+
onClick: exportSettings,
|
|
106
68
|
},
|
|
69
|
+
{
|
|
70
|
+
type: 'divider',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
key: 'all',
|
|
74
|
+
label: <div>{t('exportType.all')}</div>,
|
|
75
|
+
onClick: exportAll,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
icon: <Icon icon={HardDriveDownload} />,
|
|
79
|
+
key: 'export',
|
|
80
|
+
label: t('export'),
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: 'divider',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
icon: <Icon icon={Feather} />,
|
|
87
|
+
key: 'feedback',
|
|
88
|
+
label: t('feedback'),
|
|
89
|
+
onClick: () => window.open(FEEDBACK, '__blank'),
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
icon: <Icon icon={FileClock} />,
|
|
93
|
+
key: 'changelog',
|
|
94
|
+
label: t('changelog'),
|
|
95
|
+
onClick: () => window.open(CHANGELOG, '__blank'),
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
icon: <Icon icon={Heart} />,
|
|
99
|
+
key: 'about',
|
|
100
|
+
label: t('about'),
|
|
101
|
+
onClick: () => window.open(ABOUT, '__blank'),
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
type: 'divider',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
icon: <Icon icon={Settings} />,
|
|
108
|
+
key: 'setting',
|
|
109
|
+
label: (
|
|
110
|
+
<Flexbox align={'center'} distribution={'space-between'} gap={8} horizontal>
|
|
111
|
+
{t('setting')} {hasNewVersion && <Badge count={t('upgradeVersion.hasNew')} />}
|
|
112
|
+
</Flexbox>
|
|
113
|
+
),
|
|
114
|
+
onClick: () => {
|
|
115
|
+
setTab(SidebarTabKey.Setting);
|
|
116
|
+
router.push('/settings/common');
|
|
107
117
|
},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
);
|
|
118
|
+
},
|
|
119
|
+
];
|
|
111
120
|
|
|
112
121
|
return (
|
|
113
122
|
<>
|
|
@@ -124,7 +133,17 @@ const BottomActions = memo<BottomActionProps>(({ tab, setTab }) => {
|
|
|
124
133
|
title={'Github'}
|
|
125
134
|
/>
|
|
126
135
|
<Dropdown arrow={false} menu={{ items }} trigger={['click']}>
|
|
127
|
-
|
|
136
|
+
{hasNewVersion ? (
|
|
137
|
+
<Flexbox>
|
|
138
|
+
<ConfigProvider theme={{ components: { Badge: { dotSize: 8 } } }}>
|
|
139
|
+
<Badge dot offset={[-4, 4]}>
|
|
140
|
+
<ActionIcon active={tab === SidebarTabKey.Setting} icon={Settings2} />
|
|
141
|
+
</Badge>
|
|
142
|
+
</ConfigProvider>
|
|
143
|
+
</Flexbox>
|
|
144
|
+
) : (
|
|
145
|
+
<ActionIcon active={tab === SidebarTabKey.Setting} icon={Settings2} />
|
|
146
|
+
)}
|
|
128
147
|
</Dropdown>
|
|
129
148
|
</>
|
|
130
149
|
);
|
|
@@ -5,7 +5,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
5
5
|
import SideBar from '@/features/SideBar';
|
|
6
6
|
import { useIsPWA } from '@/hooks/useIsPWA';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const AppLayoutDesktop = memo<PropsWithChildren>(({ children }) => {
|
|
9
9
|
const isPWA = useIsPWA();
|
|
10
10
|
const theme = useTheme();
|
|
11
11
|
return (
|
|
@@ -20,4 +20,4 @@ const AppLayout = memo<PropsWithChildren>(({ children }) => {
|
|
|
20
20
|
);
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
export default
|
|
23
|
+
export default AppLayoutDesktop;
|
|
@@ -43,7 +43,7 @@ interface AppMobileLayoutProps extends PropsWithChildren {
|
|
|
43
43
|
title?: MobileNavBarTitleProps;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
const
|
|
46
|
+
const AppLayoutMobile = memo<AppMobileLayoutProps>(
|
|
47
47
|
({ children, showTabBar, navBar, style, className }) => {
|
|
48
48
|
const { styles, cx } = useStyles();
|
|
49
49
|
|
|
@@ -67,4 +67,4 @@ const AppMobileLayout = memo<AppMobileLayoutProps>(
|
|
|
67
67
|
},
|
|
68
68
|
);
|
|
69
69
|
|
|
70
|
-
export default
|
|
70
|
+
export default AppLayoutMobile;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { useResponsive } from 'antd-style';
|
|
1
2
|
import { useRouter } from 'next/navigation';
|
|
2
3
|
import { memo, useEffect } from 'react';
|
|
3
4
|
|
|
4
5
|
import { useGlobalStore } from '@/store/global';
|
|
5
6
|
import { usePluginStore } from '@/store/plugin';
|
|
6
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
useEffectAfterSessionHydrated,
|
|
9
|
+
useOnFinishHydrationSession,
|
|
10
|
+
useSessionStore,
|
|
11
|
+
} from '@/store/session';
|
|
7
12
|
|
|
8
13
|
const StoreHydration = memo(() => {
|
|
9
14
|
const router = useRouter();
|
|
@@ -22,6 +27,15 @@ const StoreHydration = memo(() => {
|
|
|
22
27
|
store.setState({ router });
|
|
23
28
|
});
|
|
24
29
|
|
|
30
|
+
const { mobile } = useResponsive();
|
|
31
|
+
|
|
32
|
+
useEffectAfterSessionHydrated(
|
|
33
|
+
(store) => {
|
|
34
|
+
store.setState({ isMobile: mobile });
|
|
35
|
+
},
|
|
36
|
+
[mobile],
|
|
37
|
+
);
|
|
38
|
+
|
|
25
39
|
return null;
|
|
26
40
|
});
|
|
27
41
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { PropsWithChildren, ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useIsMobile } from '@/hooks/useIsMobile';
|
|
6
|
+
|
|
7
|
+
interface ServerResponsiveLayoutProps {
|
|
8
|
+
Desktop: (props: PropsWithChildren) => ReactNode;
|
|
9
|
+
Mobile: (props: PropsWithChildren) => ReactNode;
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
}
|
|
12
|
+
const ResponsiveLayout = ({ children, Desktop, Mobile }: ServerResponsiveLayoutProps) => {
|
|
13
|
+
const mobile = useIsMobile();
|
|
14
|
+
|
|
15
|
+
return mobile ? <Mobile>{children}</Mobile> : <Desktop>{children}</Desktop>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default ResponsiveLayout;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { PropsWithChildren, ReactNode } from 'react';
|
|
2
2
|
|
|
3
|
+
import { isMobileDevice } from '@/utils/responsive';
|
|
4
|
+
|
|
3
5
|
interface ServerResponsiveLayoutProps {
|
|
4
6
|
Desktop: (props: PropsWithChildren) => ReactNode;
|
|
5
7
|
Mobile: (props: PropsWithChildren) => ReactNode;
|
|
6
8
|
children?: ReactNode;
|
|
7
|
-
isMobile: () => boolean;
|
|
8
9
|
}
|
|
9
|
-
const ResponsiveLayout = ({ children, Desktop, Mobile
|
|
10
|
-
const mobile =
|
|
10
|
+
const ResponsiveLayout = ({ children, Desktop, Mobile }: ServerResponsiveLayoutProps) => {
|
|
11
|
+
const mobile = isMobileDevice();
|
|
11
12
|
|
|
12
13
|
return mobile ? <Mobile>{children}</Mobile> : <Desktop>{children}</Desktop>;
|
|
13
14
|
};
|
|
@@ -1 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
const VERSION_URL = 'https://registry.npmmirror.com/@lobehub/chat';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* get latest version from npm
|
|
5
|
+
*/
|
|
6
|
+
export const featLatestVersion = async (): Promise<string> => {
|
|
7
|
+
const res = await fetch(VERSION_URL);
|
|
8
|
+
const data = await res.json();
|
|
9
|
+
|
|
10
|
+
return data['dist-tags']?.latest;
|
|
11
|
+
};
|
|
@@ -18,7 +18,18 @@ export interface Guide {
|
|
|
18
18
|
topic?: boolean;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export interface GlobalPreference {
|
|
22
|
+
guide?: Guide;
|
|
23
|
+
inputHeight: number;
|
|
24
|
+
mobileShowTopic?: boolean;
|
|
25
|
+
sessionsWidth: number;
|
|
26
|
+
showChatSideBar?: boolean;
|
|
27
|
+
showSessionPanel?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
21
30
|
export interface GlobalState {
|
|
31
|
+
hasNewVersion?: boolean;
|
|
32
|
+
latestVersion?: string;
|
|
22
33
|
/**
|
|
23
34
|
* 用户偏好的 UI 状态
|
|
24
35
|
* @localStorage
|
|
@@ -33,15 +44,6 @@ export interface GlobalState {
|
|
|
33
44
|
sidebarKey: SidebarTabKey;
|
|
34
45
|
}
|
|
35
46
|
|
|
36
|
-
export interface GlobalPreference {
|
|
37
|
-
guide?: Guide;
|
|
38
|
-
inputHeight: number;
|
|
39
|
-
mobileShowTopic?: boolean;
|
|
40
|
-
sessionsWidth: number;
|
|
41
|
-
showChatSideBar?: boolean;
|
|
42
|
-
showSessionPanel?: boolean;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
47
|
export const initialState: GlobalState = {
|
|
46
48
|
preference: {
|
|
47
49
|
guide: {},
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { produce } from 'immer';
|
|
2
|
+
import { gt } from 'semver';
|
|
3
|
+
import useSWR, { SWRResponse } from 'swr';
|
|
2
4
|
import type { StateCreator } from 'zustand/vanilla';
|
|
3
5
|
|
|
6
|
+
import { CURRENT_VERSION } from '@/const/version';
|
|
7
|
+
import { featLatestVersion } from '@/services/latestVersion';
|
|
4
8
|
import { merge } from '@/utils/merge';
|
|
5
9
|
import { setNamespace } from '@/utils/storeDebug';
|
|
6
10
|
|
|
@@ -22,6 +26,7 @@ export interface CommonAction {
|
|
|
22
26
|
toggleMobileTopic: (visible?: boolean) => void;
|
|
23
27
|
updateGuideState: (guide: Partial<Guide>) => void;
|
|
24
28
|
updatePreference: (preference: Partial<GlobalPreference>, action?: string) => void;
|
|
29
|
+
useCheckLatestVersion: () => SWRResponse<string>;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
export const createCommonSlice: StateCreator<
|
|
@@ -59,4 +64,11 @@ export const createCommonSlice: StateCreator<
|
|
|
59
64
|
action,
|
|
60
65
|
);
|
|
61
66
|
},
|
|
67
|
+
useCheckLatestVersion: () =>
|
|
68
|
+
useSWR('checkLatestVersion', featLatestVersion, {
|
|
69
|
+
onSuccess: (data: string) => {
|
|
70
|
+
if (gt(data, CURRENT_VERSION))
|
|
71
|
+
set({ hasNewVersion: true, latestVersion: data }, false, t('checkLatestVersion'));
|
|
72
|
+
},
|
|
73
|
+
}),
|
|
62
74
|
});
|
|
@@ -33,7 +33,7 @@ export const initLobeSession: LobeAgentSession = {
|
|
|
33
33
|
|
|
34
34
|
export const initInbox = merge({}, initLobeSession, {
|
|
35
35
|
config: {
|
|
36
|
-
systemRole: '
|
|
36
|
+
systemRole: '',
|
|
37
37
|
} as LobeAgentConfig,
|
|
38
38
|
id: 'inbox',
|
|
39
39
|
meta: {
|
|
@@ -42,7 +42,7 @@ export const initInbox = merge({}, initLobeSession, {
|
|
|
42
42
|
} as Partial<LobeAgentSession>);
|
|
43
43
|
|
|
44
44
|
export const initialSessionState: SessionState = {
|
|
45
|
-
activeId:
|
|
45
|
+
activeId: 'inbox',
|
|
46
46
|
inbox: initInbox,
|
|
47
47
|
isMobile: false,
|
|
48
48
|
searchKeywords: '',
|
package/.dockerignore
DELETED
package/Dockerfile
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
FROM node:20-slim AS base
|
|
2
|
-
ENV PNPM_HOME="/pnpm"
|
|
3
|
-
ENV PATH="$PNPM_HOME:$PATH"
|
|
4
|
-
RUN corepack enable
|
|
5
|
-
|
|
6
|
-
## Install dependencies only when needed
|
|
7
|
-
FROM base AS builder
|
|
8
|
-
WORKDIR /app
|
|
9
|
-
|
|
10
|
-
COPY package.json ./
|
|
11
|
-
|
|
12
|
-
# If you want to build docker in China
|
|
13
|
-
RUN npm config set registry https://registry.npmmirror.com/
|
|
14
|
-
RUN pnpm install
|
|
15
|
-
|
|
16
|
-
COPY . .
|
|
17
|
-
RUN pnpm run build:docker # run build standalone for docker version
|
|
18
|
-
|
|
19
|
-
## Production image, copy all the files and run next
|
|
20
|
-
FROM base AS runner
|
|
21
|
-
WORKDIR /app
|
|
22
|
-
|
|
23
|
-
ENV NODE_ENV production
|
|
24
|
-
|
|
25
|
-
RUN addgroup --system --gid 1001 nodejs
|
|
26
|
-
RUN adduser --system --uid 1001 nextjs
|
|
27
|
-
|
|
28
|
-
COPY --from=builder /app/public ./public
|
|
29
|
-
|
|
30
|
-
# Set the correct permission for prerender cache
|
|
31
|
-
RUN mkdir .next
|
|
32
|
-
RUN chown nextjs:nodejs .next
|
|
33
|
-
|
|
34
|
-
# Automatically leverage output traces to reduce image size
|
|
35
|
-
# https://nextjs.org/docs/advanced-features/output-file-tracing
|
|
36
|
-
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
|
37
|
-
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
|
38
|
-
|
|
39
|
-
USER nextjs
|
|
40
|
-
|
|
41
|
-
EXPOSE 3000
|
|
42
|
-
|
|
43
|
-
# set hostname to localhost
|
|
44
|
-
ENV HOSTNAME "0.0.0.0"
|
|
45
|
-
|
|
46
|
-
CMD ["node", "server.js"]
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { useResponsive } from 'antd-style';
|
|
2
|
-
import { memo } from 'react';
|
|
3
|
-
|
|
4
|
-
import Mobile from '../../../components/ChatHeader/Mobile';
|
|
5
|
-
import Desktop from './Desktop';
|
|
6
|
-
|
|
7
|
-
const Header = memo(() => {
|
|
8
|
-
const { mobile } = useResponsive();
|
|
9
|
-
const Render = mobile ? Mobile : Desktop;
|
|
10
|
-
|
|
11
|
-
return <Render />;
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
export default Header;
|
|
@@ -1,22 +0,0 @@
|
|
|
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);
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { useResponsive } from 'antd-style';
|
|
2
|
-
import { memo } from 'react';
|
|
3
|
-
|
|
4
|
-
import Mobile from '../../../(mobile)/features/SessionHeader';
|
|
5
|
-
import Desktop from './Desktop';
|
|
6
|
-
|
|
7
|
-
const Header = memo(() => {
|
|
8
|
-
const { mobile } = useResponsive();
|
|
9
|
-
const Render = mobile ? Mobile : Desktop;
|
|
10
|
-
|
|
11
|
-
return <Render />;
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
export default Header;
|
|
@@ -1,20 +0,0 @@
|
|
|
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;
|
|
@@ -1,20 +0,0 @@
|
|
|
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;
|
|
@@ -1,25 +0,0 @@
|
|
|
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;
|
|
@@ -1,12 +0,0 @@
|
|
|
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;
|
|
@@ -1,15 +0,0 @@
|
|
|
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;
|