@lobehub/chat 0.82.1 → 0.82.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +22 -6
- package/README.zh-CN.md +21 -5
- package/docs/Environment-Variable.md +45 -9
- package/locales/en_US/common.json +1 -1
- package/locales/ru_RU/common.json +1 -1
- package/locales/zh_CN/common.json +1 -1
- package/locales/zh_TW/common.json +1 -1
- package/package.json +1 -1
- package/public/images/screenshot_background.webp +0 -0
- package/src/app/chat/features/Header/Mobile.tsx +12 -7
- package/src/app/chat/features/Header/ShareButton/Inner.tsx +31 -26
- package/src/app/chat/features/Header/ShareButton/index.tsx +6 -1
- package/src/app/chat/features/SessionList/Header/Desktop.tsx +2 -4
- package/src/app/chat/features/SessionList/Header/Mobile.tsx +15 -14
- package/src/app/chat/features/Sidebar/Mobile.tsx +3 -17
- package/src/app/chat/layout.desktop.tsx +2 -1
- package/src/app/chat/layout.mobile.tsx +2 -1
- package/src/app/chat/settings/features/Header/index.tsx +3 -3
- package/src/app/chat/settings/layout.mobile.tsx +1 -8
- package/src/app/market/features/AgentCard/AgentCardBanner.tsx +2 -1
- package/src/app/market/features/Header/Mobile.tsx +2 -21
- package/src/app/market/features/SideBar/AgentInfo/Header.tsx +2 -1
- package/src/app/market/features/SideBar/AgentInfo/index.tsx +10 -2
- package/src/app/market/features/SideBar/Mobile.tsx +3 -17
- package/src/app/market/layout.desktop.tsx +2 -1
- package/src/app/market/layout.mobile.tsx +2 -1
- package/src/app/settings/agent/index.tsx +20 -0
- package/src/app/settings/agent/page.tsx +7 -0
- package/src/app/settings/{features/Settings → common}/Common.tsx +1 -1
- package/src/app/settings/common/index.tsx +20 -0
- package/src/app/settings/common/page.tsx +7 -0
- package/src/app/settings/features/Header/Desktop.tsx +9 -2
- package/src/app/settings/features/Header/Mobile.tsx +5 -2
- package/src/app/settings/features/SideBar/Item.tsx +39 -0
- package/src/app/settings/features/SideBar/List.tsx +30 -0
- package/src/app/settings/features/SideBar/index.tsx +38 -0
- package/src/app/settings/index.tsx +5 -7
- package/src/app/settings/layout.desktop.tsx +6 -2
- package/src/app/settings/layout.mobile.tsx +1 -3
- package/src/app/settings/{features/Settings → llm}/LLM/index.tsx +4 -2
- package/src/app/settings/llm/index.tsx +20 -0
- package/src/app/settings/llm/page.tsx +7 -0
- package/src/app/settings/mobile/ExtraList.tsx +61 -0
- package/src/app/settings/mobile/index.tsx +43 -0
- package/src/app/settings/mobile/page.tsx +7 -0
- package/src/app/settings/page.tsx +1 -7
- package/src/components/MobilePadding/index.tsx +32 -0
- package/src/const/layoutTokens.ts +1 -0
- package/src/features/AgentSetting/AgentMeta/index.tsx +0 -1
- package/src/features/AgentSetting/AgentPlugin/MarketSettingModal.tsx +29 -16
- package/src/features/MobileTabBar/index.tsx +15 -3
- package/src/features/PluginDevModal/PluginPreview.tsx +11 -4
- package/src/features/PluginDevModal/index.tsx +14 -10
- package/src/features/SideBar/BottomActions.tsx +3 -3
- package/src/features/SideBar/TopActions.tsx +5 -4
- package/src/locales/default/common.ts +1 -1
- package/src/locales/default/plugin.ts +2 -1
- package/src/store/global/hooks/useSwitchSettingsOnInit.ts +9 -0
- package/src/store/global/initialState.ts +13 -4
- package/src/store/global/store.ts +0 -4
- package/src/store/session/slices/chat/actions/share.ts +1 -1
- package/src/styles/antdOverride.ts +2 -26
- package/src/styles/global.ts +9 -0
- package/src/app/settings/features/Banner/index.tsx +0 -94
- package/src/app/settings/features/Settings/index.tsx +0 -53
- /package/src/app/settings/{features/Settings → agent}/Agent.tsx +0 -0
- /package/src/app/settings/{features/Settings → llm}/LLM/Checker.tsx +0 -0
- /package/src/app/settings/{features/Settings → llm}/LLM/ModelList.tsx +0 -0
- /package/src/app/settings/{features/Settings → llm}/LLM/getModelList.ts +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ActionIcon } from '@lobehub/ui';
|
|
2
2
|
import { Dropdown, MenuProps } from 'antd';
|
|
3
3
|
import { useResponsive } from 'antd-style';
|
|
4
|
-
import { HardDriveDownload
|
|
4
|
+
import { HardDriveDownload } from 'lucide-react';
|
|
5
5
|
import { memo, useMemo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
|
|
8
|
+
import { MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
|
8
9
|
import { exportSingleAgent, exportSingleSession } from '@/helpers/export';
|
|
9
10
|
import { useSessionStore } from '@/store/session';
|
|
10
11
|
|
|
@@ -42,11 +43,10 @@ const Header = memo<{ mobile?: boolean }>(() => {
|
|
|
42
43
|
[],
|
|
43
44
|
);
|
|
44
45
|
|
|
45
|
-
const size = mobile ?
|
|
46
|
+
const size = mobile ? MOBILE_HEADER_ICON_SIZE : { fontSize: 24 };
|
|
46
47
|
|
|
47
48
|
return (
|
|
48
49
|
<Render>
|
|
49
|
-
<ActionIcon icon={Share2} size={size} title={t('share', { ns: 'common' })} />
|
|
50
50
|
<Dropdown arrow={false} menu={{ items }} trigger={['click']}>
|
|
51
51
|
<ActionIcon icon={HardDriveDownload} size={size} title={t('export', { ns: 'common' })} />
|
|
52
52
|
</Dropdown>
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import { PropsWithChildren, memo } from 'react';
|
|
2
|
-
import { Flexbox } from 'react-layout-kit';
|
|
3
2
|
|
|
4
3
|
import AppMobileLayout from '@/layout/AppMobileLayout';
|
|
5
4
|
|
|
6
5
|
import Header from './features/Header';
|
|
7
6
|
|
|
8
7
|
const MobileLayout = memo<PropsWithChildren>(({ children }) => {
|
|
9
|
-
return
|
|
10
|
-
<AppMobileLayout navBar={<Header />}>
|
|
11
|
-
<Flexbox gap={16} padding={16}>
|
|
12
|
-
{children}
|
|
13
|
-
</Flexbox>
|
|
14
|
-
</AppMobileLayout>
|
|
15
|
-
);
|
|
8
|
+
return <AppMobileLayout navBar={<Header />}>{children}</AppMobileLayout>;
|
|
16
9
|
});
|
|
17
10
|
|
|
18
11
|
export default MobileLayout;
|
|
@@ -39,7 +39,7 @@ interface AgentCardBannerProps extends DivProps {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
const AgentCardBanner = memo<AgentCardBannerProps>(
|
|
42
|
-
({ meta, className, mask, size = 8, maskColor, ...props }) => {
|
|
42
|
+
({ meta, className, mask, size = 8, maskColor, children, ...props }) => {
|
|
43
43
|
const { styles, theme, cx } = useStyles(maskColor);
|
|
44
44
|
|
|
45
45
|
return (
|
|
@@ -56,6 +56,7 @@ const AgentCardBanner = memo<AgentCardBannerProps>(
|
|
|
56
56
|
style={{ transform: `scale(${size})` }}
|
|
57
57
|
/>
|
|
58
58
|
{mask && <div className={styles.bannerMask} />}
|
|
59
|
+
{children}
|
|
59
60
|
</Flexbox>
|
|
60
61
|
);
|
|
61
62
|
},
|
|
@@ -1,27 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Settings2 } from 'lucide-react';
|
|
3
|
-
import { useRouter } from 'next/navigation';
|
|
1
|
+
import { Logo, MobileNavBar } from '@lobehub/ui';
|
|
4
2
|
import { memo } from 'react';
|
|
5
3
|
|
|
6
|
-
import AvatarWithUpload from '@/features/AvatarWithUpload';
|
|
7
|
-
|
|
8
4
|
const Header = memo(() => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return (
|
|
12
|
-
<MobileNavBar
|
|
13
|
-
center={<Logo type={'text'} />}
|
|
14
|
-
left={<AvatarWithUpload size={28} style={{ marginLeft: 8 }} />}
|
|
15
|
-
right={
|
|
16
|
-
<ActionIcon
|
|
17
|
-
icon={Settings2}
|
|
18
|
-
onClick={() => {
|
|
19
|
-
router.push('/settings');
|
|
20
|
-
}}
|
|
21
|
-
/>
|
|
22
|
-
}
|
|
23
|
-
/>
|
|
24
|
-
);
|
|
5
|
+
return <MobileNavBar center={<Logo type={'text'} />} />;
|
|
25
6
|
});
|
|
26
7
|
|
|
27
8
|
export default Header;
|
|
@@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
6
6
|
import { Center } from 'react-layout-kit';
|
|
7
7
|
|
|
8
8
|
import { useGlobalStore } from '@/store/global';
|
|
9
|
+
import { SidebarTabKey } from '@/store/global/initialState';
|
|
9
10
|
import { agentMarketSelectors, useMarketStore } from '@/store/market';
|
|
10
11
|
import { useSessionStore } from '@/store/session';
|
|
11
12
|
|
|
@@ -54,7 +55,7 @@ const Header = memo(() => {
|
|
|
54
55
|
if (!agentItem) return;
|
|
55
56
|
|
|
56
57
|
createSession({ config, meta });
|
|
57
|
-
switchSideBar(
|
|
58
|
+
switchSideBar(SidebarTabKey.Chat);
|
|
58
59
|
}}
|
|
59
60
|
type={'primary'}
|
|
60
61
|
>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Markdown, TabsNav } from '@lobehub/ui';
|
|
2
|
+
import { useResponsive } from 'antd-style';
|
|
2
3
|
import { memo, useState } from 'react';
|
|
3
4
|
import { useTranslation } from 'react-i18next';
|
|
4
5
|
import { Flexbox } from 'react-layout-kit';
|
|
@@ -22,7 +23,8 @@ const AgentModalInner = memo(() => {
|
|
|
22
23
|
s.useFetchAgent,
|
|
23
24
|
s.currentIdentifier,
|
|
24
25
|
]);
|
|
25
|
-
const { styles } = useStyles();
|
|
26
|
+
const { styles, theme } = useStyles();
|
|
27
|
+
const { mobile } = useResponsive();
|
|
26
28
|
const { data, isLoading } = useFetchAgent(currentIdentifier);
|
|
27
29
|
const { t } = useTranslation('market');
|
|
28
30
|
const [tab, setTab] = useState<string>(InfoTabs.prompt);
|
|
@@ -34,7 +36,13 @@ const AgentModalInner = memo(() => {
|
|
|
34
36
|
|
|
35
37
|
return (
|
|
36
38
|
<>
|
|
37
|
-
<AgentCardBanner
|
|
39
|
+
<AgentCardBanner
|
|
40
|
+
mask
|
|
41
|
+
maskColor={mobile ? theme.colorBgContainer : undefined}
|
|
42
|
+
meta={meta}
|
|
43
|
+
size={10}
|
|
44
|
+
style={{ height: 120, marginBottom: -60 }}
|
|
45
|
+
/>
|
|
38
46
|
<Header />
|
|
39
47
|
<Flexbox align={'center'}>
|
|
40
48
|
<TabsNav
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Drawer } from 'antd';
|
|
3
|
-
import { useTheme } from 'antd-style';
|
|
4
|
-
import { X } from 'lucide-react';
|
|
1
|
+
import { Modal } from '@lobehub/ui';
|
|
5
2
|
import { PropsWithChildren, memo } from 'react';
|
|
6
3
|
import { useTranslation } from 'react-i18next';
|
|
7
4
|
|
|
8
5
|
import { agentMarketSelectors, useMarketStore } from '@/store/market';
|
|
9
6
|
|
|
10
7
|
const Mobile = memo<PropsWithChildren>(({ children }) => {
|
|
11
|
-
const theme = useTheme();
|
|
12
8
|
const [showAgentSidebar, deactivateAgent] = useMarketStore((s) => [
|
|
13
9
|
agentMarketSelectors.showSideBar(s),
|
|
14
10
|
s.deactivateAgent,
|
|
@@ -17,19 +13,9 @@ const Mobile = memo<PropsWithChildren>(({ children }) => {
|
|
|
17
13
|
const { t } = useTranslation('market');
|
|
18
14
|
|
|
19
15
|
return (
|
|
20
|
-
<
|
|
21
|
-
bodyStyle={{ padding: 0 }}
|
|
22
|
-
closeIcon={<ActionIcon icon={X} size={{ blockSize: 32, fontSize: 20 }} />}
|
|
23
|
-
drawerStyle={{ background: theme.colorBgLayout }}
|
|
24
|
-
headerStyle={{ padding: '8px 4px' }}
|
|
25
|
-
height={'75vh'}
|
|
26
|
-
onClose={deactivateAgent}
|
|
27
|
-
open={showAgentSidebar}
|
|
28
|
-
placement={'bottom'}
|
|
29
|
-
title={t('sidebar.title')}
|
|
30
|
-
>
|
|
16
|
+
<Modal onCancel={deactivateAgent} open={showAgentSidebar} title={t('sidebar.title')}>
|
|
31
17
|
{children}
|
|
32
|
-
</
|
|
18
|
+
</Modal>
|
|
33
19
|
);
|
|
34
20
|
});
|
|
35
21
|
|
|
@@ -6,6 +6,7 @@ import { Center, Flexbox } from 'react-layout-kit';
|
|
|
6
6
|
import SafeSpacing from '@/components/SafeSpacing';
|
|
7
7
|
import { MAX_WIDTH } from '@/const/layoutTokens';
|
|
8
8
|
import { useSwitchSideBarOnInit } from '@/store/global';
|
|
9
|
+
import { SidebarTabKey } from '@/store/global/initialState';
|
|
9
10
|
|
|
10
11
|
import AppLayout from '../../layout/AppLayout';
|
|
11
12
|
import Header from './features/Header';
|
|
@@ -27,7 +28,7 @@ const useStyles = createStyles(({ css }) => ({
|
|
|
27
28
|
const MarketLayout = memo<PropsWithChildren>(({ children }) => {
|
|
28
29
|
const { theme, styles } = useStyles();
|
|
29
30
|
|
|
30
|
-
useSwitchSideBarOnInit(
|
|
31
|
+
useSwitchSideBarOnInit(SidebarTabKey.Market);
|
|
31
32
|
|
|
32
33
|
return (
|
|
33
34
|
<AppLayout>
|
|
@@ -3,12 +3,13 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
3
3
|
|
|
4
4
|
import AppMobileLayout from '@/layout/AppMobileLayout';
|
|
5
5
|
import { useSwitchSideBarOnInit } from '@/store/global';
|
|
6
|
+
import { SidebarTabKey } from '@/store/global/initialState';
|
|
6
7
|
|
|
7
8
|
import Header from './features/Header';
|
|
8
9
|
import SideBar from './features/SideBar';
|
|
9
10
|
|
|
10
11
|
const MarketLayout = memo<{ children: ReactNode }>(({ children }) => {
|
|
11
|
-
useSwitchSideBarOnInit(
|
|
12
|
+
useSwitchSideBarOnInit(SidebarTabKey.Market);
|
|
12
13
|
|
|
13
14
|
return (
|
|
14
15
|
<AppMobileLayout navBar={<Header />} showTabBar>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useSwitchSideBarOnInit } from '@/store/global/hooks/useSwitchSettingsOnInit';
|
|
6
|
+
import { SettingsTabs } from '@/store/global/initialState';
|
|
7
|
+
|
|
8
|
+
import Layout from '../index';
|
|
9
|
+
import Agent from './Agent';
|
|
10
|
+
|
|
11
|
+
const AgentSetting = memo(() => {
|
|
12
|
+
useSwitchSideBarOnInit(SettingsTabs.Agent);
|
|
13
|
+
return (
|
|
14
|
+
<Layout>
|
|
15
|
+
<Agent />
|
|
16
|
+
</Layout>
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export default AgentSetting;
|
|
@@ -15,7 +15,7 @@ import { useSessionStore } from '@/store/session';
|
|
|
15
15
|
import { ConfigKeys } from '@/types/settings';
|
|
16
16
|
import { switchLang } from '@/utils/switchLang';
|
|
17
17
|
|
|
18
|
-
import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from '../ThemeSwatches';
|
|
18
|
+
import { ThemeSwatchesNeutral, ThemeSwatchesPrimary } from '../features/ThemeSwatches';
|
|
19
19
|
|
|
20
20
|
type SettingItemGroup = ItemGroup & {
|
|
21
21
|
children: {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useSwitchSideBarOnInit } from '@/store/global/hooks/useSwitchSettingsOnInit';
|
|
6
|
+
import { SettingsTabs } from '@/store/global/initialState';
|
|
7
|
+
|
|
8
|
+
import Layout from '../index';
|
|
9
|
+
import Common from './Common';
|
|
10
|
+
|
|
11
|
+
const CommonSetting = memo(() => {
|
|
12
|
+
useSwitchSideBarOnInit(SettingsTabs.Common);
|
|
13
|
+
return (
|
|
14
|
+
<Layout>
|
|
15
|
+
<Common />
|
|
16
|
+
</Layout>
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export default CommonSetting;
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import { ChatHeader, ChatHeaderTitle
|
|
1
|
+
import { ChatHeader, ChatHeaderTitle } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
|
|
5
|
+
import { useGlobalStore } from '@/store/global';
|
|
6
|
+
|
|
5
7
|
const Index = memo(() => {
|
|
6
8
|
const { t } = useTranslation('setting');
|
|
9
|
+
const tab = useGlobalStore((s) => s.settingsTab);
|
|
7
10
|
|
|
8
11
|
return (
|
|
9
12
|
<ChatHeader
|
|
10
|
-
left={
|
|
13
|
+
left={
|
|
14
|
+
<div style={{ paddingLeft: 8 }}>
|
|
15
|
+
<ChatHeaderTitle title={t(`tab.${tab}`)} />
|
|
16
|
+
</div>
|
|
17
|
+
}
|
|
11
18
|
/>
|
|
12
19
|
);
|
|
13
20
|
});
|
|
@@ -3,14 +3,17 @@ import { useRouter } from 'next/navigation';
|
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
|
|
6
|
+
import { useGlobalStore } from '@/store/global';
|
|
7
|
+
|
|
6
8
|
const Header = memo(() => {
|
|
7
9
|
const { t } = useTranslation('setting');
|
|
10
|
+
const tab = useGlobalStore((s) => s.settingsTab);
|
|
8
11
|
const router = useRouter();
|
|
9
12
|
|
|
10
13
|
return (
|
|
11
14
|
<MobileNavBar
|
|
12
|
-
center={<MobileNavBarTitle title={t(
|
|
13
|
-
onBackClick={() => router.
|
|
15
|
+
center={<MobileNavBarTitle title={t(`tab.${tab}`)} />}
|
|
16
|
+
onBackClick={() => router.back()}
|
|
14
17
|
showBackButton
|
|
15
18
|
/>
|
|
16
19
|
);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Icon, List } from '@lobehub/ui';
|
|
2
|
+
import { createStyles, useResponsive } from 'antd-style';
|
|
3
|
+
import { ChevronRight, type LucideIcon } from 'lucide-react';
|
|
4
|
+
import { CSSProperties, ReactNode, memo } from 'react';
|
|
5
|
+
|
|
6
|
+
const { Item } = List;
|
|
7
|
+
|
|
8
|
+
const useStyles = createStyles(({ css }) => ({
|
|
9
|
+
container: css`
|
|
10
|
+
padding-top: 20px;
|
|
11
|
+
padding-bottom: 20px;
|
|
12
|
+
`,
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
export interface ItemProps {
|
|
16
|
+
active?: boolean;
|
|
17
|
+
className?: string;
|
|
18
|
+
icon: LucideIcon;
|
|
19
|
+
label: ReactNode;
|
|
20
|
+
style?: CSSProperties;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const SettingItem = memo<ItemProps>(({ label, icon, active = false, style, className }) => {
|
|
24
|
+
const { cx, styles } = useStyles();
|
|
25
|
+
const { mobile } = useResponsive();
|
|
26
|
+
return (
|
|
27
|
+
<Item
|
|
28
|
+
active={active}
|
|
29
|
+
avatar={<Icon icon={icon} size={{ fontSize: 16 }} />}
|
|
30
|
+
className={cx(styles.container, className)}
|
|
31
|
+
style={style}
|
|
32
|
+
title={label as string}
|
|
33
|
+
>
|
|
34
|
+
{mobile && <Icon icon={ChevronRight} size={{ fontSize: 16 }} />}
|
|
35
|
+
</Item>
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export default SettingItem;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useResponsive } from 'antd-style';
|
|
2
|
+
import { Bot, Settings2, Webhook } from 'lucide-react';
|
|
3
|
+
import { useRouter } from 'next/navigation';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
|
|
7
|
+
import { useGlobalStore } from '@/store/global';
|
|
8
|
+
import { SettingsTabs } from '@/store/global/initialState';
|
|
9
|
+
|
|
10
|
+
import Item from './Item';
|
|
11
|
+
|
|
12
|
+
const List = memo(() => {
|
|
13
|
+
const { t } = useTranslation('setting');
|
|
14
|
+
const tab = useGlobalStore((s) => s.settingsTab);
|
|
15
|
+
const router = useRouter();
|
|
16
|
+
const { mobile } = useResponsive();
|
|
17
|
+
const items = [
|
|
18
|
+
{ icon: Settings2, label: t('tab.common'), value: SettingsTabs.Common },
|
|
19
|
+
{ icon: Webhook, label: t('tab.llm'), value: SettingsTabs.LLM },
|
|
20
|
+
{ icon: Bot, label: t('tab.agent'), value: SettingsTabs.Agent },
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
return items.map(({ value, icon, label }) => (
|
|
24
|
+
<div key={value} onClick={() => router.push(`/settings/${value}`)}>
|
|
25
|
+
<Item active={mobile ? false : tab === value} icon={icon} label={label} />
|
|
26
|
+
</div>
|
|
27
|
+
));
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export default List;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DraggablePanelBody, Logo } from '@lobehub/ui';
|
|
2
|
+
import { createStyles } from 'antd-style';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
import { Flexbox } from 'react-layout-kit';
|
|
5
|
+
|
|
6
|
+
import FolderPanel from '@/features/FolderPanel';
|
|
7
|
+
|
|
8
|
+
import List from './List';
|
|
9
|
+
|
|
10
|
+
const useStyles = createStyles(({ stylish, token, css }) => ({
|
|
11
|
+
body: stylish.noScrollbar,
|
|
12
|
+
logo: css`
|
|
13
|
+
fill: ${token.colorText};
|
|
14
|
+
`,
|
|
15
|
+
top: css`
|
|
16
|
+
position: sticky;
|
|
17
|
+
top: 0;
|
|
18
|
+
`,
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
const SideBar = memo(() => {
|
|
22
|
+
const { styles } = useStyles();
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<FolderPanel>
|
|
26
|
+
<DraggablePanelBody className={styles.body} style={{ padding: 0 }}>
|
|
27
|
+
<Flexbox className={styles.top} padding={16}>
|
|
28
|
+
<div>
|
|
29
|
+
<Logo className={styles.logo} size={36} type={'text'} />
|
|
30
|
+
</div>
|
|
31
|
+
</Flexbox>
|
|
32
|
+
<List />
|
|
33
|
+
</DraggablePanelBody>
|
|
34
|
+
</FolderPanel>
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export default SideBar;
|
|
@@ -2,33 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
import { useResponsive } from 'antd-style';
|
|
4
4
|
import Head from 'next/head';
|
|
5
|
-
import { memo } from 'react';
|
|
5
|
+
import { ReactNode, memo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
|
|
8
8
|
import { useSwitchSideBarOnInit } from '@/store/global';
|
|
9
|
+
import { SidebarTabKey } from '@/store/global/initialState';
|
|
9
10
|
import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
|
|
10
11
|
|
|
11
|
-
import Settings from './features/Settings';
|
|
12
12
|
import DesktopLayout from './layout.desktop';
|
|
13
13
|
import MobileLayout from './layout.mobile';
|
|
14
14
|
|
|
15
|
-
const Setting = memo(() => {
|
|
15
|
+
const Setting = memo<{ children: ReactNode }>(({ children }) => {
|
|
16
16
|
const { mobile } = useResponsive();
|
|
17
17
|
const { t } = useTranslation('setting');
|
|
18
18
|
const pageTitle = genSiteHeadTitle(t('header.global'));
|
|
19
19
|
|
|
20
20
|
const RenderLayout = mobile ? MobileLayout : DesktopLayout;
|
|
21
21
|
|
|
22
|
-
useSwitchSideBarOnInit(
|
|
22
|
+
useSwitchSideBarOnInit(SidebarTabKey.Setting);
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<>
|
|
26
26
|
<Head>
|
|
27
27
|
<title>{pageTitle}</title>
|
|
28
28
|
</Head>
|
|
29
|
-
<RenderLayout>
|
|
30
|
-
<Settings />
|
|
31
|
-
</RenderLayout>
|
|
29
|
+
<RenderLayout>{children}</RenderLayout>
|
|
32
30
|
</>
|
|
33
31
|
);
|
|
34
32
|
});
|
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
import { ReactNode, memo } from 'react';
|
|
2
|
-
import { Flexbox } from 'react-layout-kit';
|
|
2
|
+
import { Center, Flexbox } from 'react-layout-kit';
|
|
3
3
|
|
|
4
4
|
import SafeSpacing from '@/components/SafeSpacing';
|
|
5
5
|
import AppLayout from '@/layout/AppLayout';
|
|
6
6
|
|
|
7
7
|
import Header from './features/Header';
|
|
8
|
+
import SideBar from './features/SideBar';
|
|
8
9
|
|
|
9
10
|
const SettingLayout = memo<{ children: ReactNode }>(({ children }) => {
|
|
10
11
|
return (
|
|
11
12
|
<AppLayout>
|
|
13
|
+
<SideBar />
|
|
12
14
|
<Flexbox flex={1} height={'100vh'} style={{ position: 'relative' }}>
|
|
13
15
|
<Header />
|
|
14
16
|
<Flexbox align={'center'} flex={1} padding={24} style={{ overflow: 'auto' }}>
|
|
15
17
|
<SafeSpacing />
|
|
16
|
-
{
|
|
18
|
+
<Center gap={16} width={'100%'}>
|
|
19
|
+
{children}
|
|
20
|
+
</Center>
|
|
17
21
|
</Flexbox>
|
|
18
22
|
</Flexbox>
|
|
19
23
|
</AppLayout>
|
|
@@ -8,9 +8,7 @@ import Header from './features/Header';
|
|
|
8
8
|
const SettingLayout = memo<{ children: ReactNode }>(({ children }) => {
|
|
9
9
|
return (
|
|
10
10
|
<AppMobileLayout navBar={<Header />}>
|
|
11
|
-
<Flexbox
|
|
12
|
-
{children}
|
|
13
|
-
</Flexbox>
|
|
11
|
+
<Flexbox style={{ overflow: 'auto' }}>{children}</Flexbox>
|
|
14
12
|
</AppMobileLayout>
|
|
15
13
|
);
|
|
16
14
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Form, Markdown } from '@lobehub/ui';
|
|
1
|
+
import { Form, type ItemGroup, Markdown } from '@lobehub/ui';
|
|
2
2
|
import { Form as AntForm, AutoComplete, Input, Switch } from 'antd';
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
4
|
import { debounce } from 'lodash-es';
|
|
@@ -49,7 +49,7 @@ const LLM = memo(() => {
|
|
|
49
49
|
|
|
50
50
|
const useAzure = useGlobalStore((s) => s.settings.languageModel.openAI.useAzure);
|
|
51
51
|
|
|
52
|
-
const openAI = {
|
|
52
|
+
const openAI: ItemGroup = {
|
|
53
53
|
children: [
|
|
54
54
|
{
|
|
55
55
|
children: (
|
|
@@ -94,6 +94,7 @@ const LLM = memo(() => {
|
|
|
94
94
|
),
|
|
95
95
|
desc: t('llm.OpenAI.useAzure.desc'),
|
|
96
96
|
label: t('llm.OpenAI.useAzure.title'),
|
|
97
|
+
minWidth: undefined,
|
|
97
98
|
name: [configKey, 'openAI', 'useAzure'],
|
|
98
99
|
valuePropName: 'checked',
|
|
99
100
|
},
|
|
@@ -124,6 +125,7 @@ const LLM = memo(() => {
|
|
|
124
125
|
children: <Checker checkModel={!useAzure} />,
|
|
125
126
|
desc: t('llm.OpenAI.check.desc'),
|
|
126
127
|
label: t('llm.OpenAI.check.title'),
|
|
128
|
+
minWidth: undefined,
|
|
127
129
|
},
|
|
128
130
|
// {
|
|
129
131
|
// children: useAzure ? <Flexbox>{t('llm.OpenAI.models.notSupport')}</Flexbox> : <ModelList />,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
|
|
5
|
+
import { useSwitchSideBarOnInit } from '@/store/global/hooks/useSwitchSettingsOnInit';
|
|
6
|
+
import { SettingsTabs } from '@/store/global/initialState';
|
|
7
|
+
|
|
8
|
+
import Layout from '../index';
|
|
9
|
+
import LLM from './LLM';
|
|
10
|
+
|
|
11
|
+
const LLMSetting = memo(() => {
|
|
12
|
+
useSwitchSideBarOnInit(SettingsTabs.LLM);
|
|
13
|
+
return (
|
|
14
|
+
<Layout>
|
|
15
|
+
<LLM />
|
|
16
|
+
</Layout>
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export default LLMSetting;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Upload } from 'antd';
|
|
2
|
+
import { useResponsive } from 'antd-style';
|
|
3
|
+
import { Feather, FileClock, HardDriveDownload, HardDriveUpload, Heart } from 'lucide-react';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
|
|
7
|
+
import { ABOUT, CHANGELOG, FEEDBACK } from '@/const/url';
|
|
8
|
+
import { useExportConfig } from '@/hooks/useExportConfig';
|
|
9
|
+
import { useImportConfig } from '@/hooks/useImportConfig';
|
|
10
|
+
import { useGlobalStore } from '@/store/global';
|
|
11
|
+
|
|
12
|
+
import Item from '../features/SideBar/Item';
|
|
13
|
+
|
|
14
|
+
const ExtraList = memo(() => {
|
|
15
|
+
const { t } = useTranslation('common');
|
|
16
|
+
const { exportAll } = useExportConfig();
|
|
17
|
+
const { importConfig } = useImportConfig();
|
|
18
|
+
const tab = useGlobalStore((s) => s.settingsTab);
|
|
19
|
+
const { mobile } = useResponsive();
|
|
20
|
+
const items = [
|
|
21
|
+
{
|
|
22
|
+
icon: HardDriveDownload,
|
|
23
|
+
label: t('export'),
|
|
24
|
+
onClick: exportAll,
|
|
25
|
+
value: 'export',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
icon: Feather,
|
|
29
|
+
label: t('feedback'),
|
|
30
|
+
onClick: () => window.open(FEEDBACK, '__blank'),
|
|
31
|
+
value: 'feedback',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
icon: FileClock,
|
|
35
|
+
label: t('changelog'),
|
|
36
|
+
onClick: () => window.open(CHANGELOG, '__blank'),
|
|
37
|
+
value: 'changelog',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
icon: Heart,
|
|
41
|
+
label: t('about'),
|
|
42
|
+
onClick: () => window.open(ABOUT, '__blank'),
|
|
43
|
+
value: 'about',
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<>
|
|
49
|
+
<Upload maxCount={1} onChange={importConfig} showUploadList={false}>
|
|
50
|
+
<Item icon={HardDriveUpload} label={t('import')} style={{ width: '100vw' }} />
|
|
51
|
+
</Upload>
|
|
52
|
+
{items.map(({ value, icon, label, onClick }) => (
|
|
53
|
+
<div key={value} onClick={onClick}>
|
|
54
|
+
<Item active={mobile ? false : tab === value} icon={icon} label={label} />
|
|
55
|
+
</div>
|
|
56
|
+
))}
|
|
57
|
+
</>
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
export default ExtraList;
|