@lobehub/chat 0.116.0 → 0.116.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.
Files changed (26) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +3 -0
  3. package/package.json +2 -1
  4. package/src/app/chat/(mobile)/features/TopicList.tsx +6 -1
  5. package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +23 -77
  6. package/src/app/chat/features/ChatHeader/ShareButton/ShareModal.tsx +141 -0
  7. package/src/app/chat/features/ChatHeader/ShareButton/index.tsx +3 -11
  8. package/src/app/chat/features/ChatHeader/ShareButton/type.ts +14 -0
  9. package/src/app/chat/features/ChatHeader/ShareButton/useScreenshot.ts +60 -0
  10. package/src/app/chat/features/SystemRole/index.tsx +0 -1
  11. package/src/app/chat/features/TopicListContent/index.tsx +3 -9
  12. package/src/app/chat/settings/features/SubmitAgentButton/{Inner.tsx → SubmitAgentModal.tsx} +23 -17
  13. package/src/app/chat/settings/features/SubmitAgentButton/index.tsx +3 -10
  14. package/src/app/market/(mobile)/features/AgentDetail.tsx +7 -1
  15. package/src/app/market/features/ShareAgentButton/Inner.tsx +2 -3
  16. package/src/features/PluginDetailModal/index.tsx +27 -29
  17. package/src/features/PluginDevModal/PluginPreview.tsx +1 -1
  18. package/src/features/PluginDevModal/index.tsx +73 -76
  19. package/src/features/PluginSettings/PluginSettingRender.tsx +22 -2
  20. package/src/features/PluginSettings/index.tsx +7 -1
  21. package/src/features/PluginStore/InstalledPluginList.tsx +2 -2
  22. package/src/features/PluginStore/OnlineList.tsx +2 -2
  23. package/src/features/PluginStore/index.tsx +17 -22
  24. package/src/app/chat/features/ChatHeader/ShareButton/Inner.tsx +0 -125
  25. package/src/components/MobilePadding/index.tsx +0 -32
  26. package/src/features/PluginStore/StoreSetting.tsx +0 -56
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.116.2](https://github.com/lobehub/lobe-chat/compare/v0.116.1...v0.116.2)
6
+
7
+ <sup>Released on **2023-12-26**</sup>
8
+
9
+ #### 💄 Styles
10
+
11
+ - **misc**: Update Modal style.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Styles
19
+
20
+ - **misc**: Update Modal style ([ac7d309](https://github.com/lobehub/lobe-chat/commit/ac7d309))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 0.116.1](https://github.com/lobehub/lobe-chat/compare/v0.116.0...v0.116.1)
31
+
32
+ <sup>Released on **2023-12-26**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **misc**: Support slider and select plugin setting render.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **misc**: Support slider and select plugin setting render, closes [#819](https://github.com/lobehub/lobe-chat/issues/819) ([3190b44](https://github.com/lobehub/lobe-chat/commit/3190b44))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ## [Version 0.116.0](https://github.com/lobehub/lobe-chat/compare/v0.115.13...v0.116.0)
6
56
 
7
57
  <sup>Released on **2023-12-26**</sup>
package/README.md CHANGED
@@ -37,6 +37,7 @@ Supports one-click free deployment of your private ChatGPT/LLM web application.
37
37
  [![][share-reddit-shield]][share-reddit-link]
38
38
  [![][share-weibo-shield]][share-weibo-link]
39
39
  [![][share-mastodon-shield]][share-mastodon-link]
40
+ [![][share-linkedin-shield]][share-linkedin-link]
40
41
 
41
42
  <sup>Pioneering the new age of thinking and creating. Built for you, the Super Individual.</sup>
42
43
 
@@ -626,6 +627,8 @@ This project is [MIT](./LICENSE) licensed.
626
627
  [pr-welcome-link]: https://github.com/lobehub/lobe-chat/pulls
627
628
  [pr-welcome-shield]: https://img.shields.io/badge/🤯_pr_welcome-%E2%86%92-ffcb47?labelColor=black&style=for-the-badge
628
629
  [profile-link]: https://github.com/lobehub
630
+ [share-linkedin-link]: https://linkedin.com/feed
631
+ [share-linkedin-shield]: https://img.shields.io/badge/-share%20on%20linkedin-black?labelColor=black&logo=linkedin&logoColor=white&style=flat-square
629
632
  [share-mastodon-link]: https://mastodon.social/share?text=Check%20this%20GitHub%20repository%20out%20%F0%9F%A4%AF%20LobeChat%20-%20An%20open-source,%20extensible%20(Function%20Calling),%20high-performance%20chatbot%20framework.%20It%20supports%20one-click%20free%20deployment%20of%20your%20private%20ChatGPT/LLM%20web%20application.%20https://github.com/lobehub/lobe-chat%20#chatbot%20#chatGPT%20#openAI
630
633
  [share-mastodon-shield]: https://img.shields.io/badge/-share%20on%20mastodon-black?labelColor=black&logo=mastodon&logoColor=white&style=flat-square
631
634
  [share-reddit-link]: https://www.reddit.com/submit?title=Check%20this%20GitHub%20repository%20out%20%F0%9F%A4%AF%20LobeChat%20-%20An%20open-source%2C%20extensible%20%28Function%20Calling%29%2C%20high-performance%20chatbot%20framework.%20It%20supports%20one-click%20free%20deployment%20of%20your%20private%20ChatGPT%2FLLM%20web%20application.%20%23chatbot%20%23chatGPT%20%23openAI&url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.116.0",
3
+ "version": "0.116.2",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -140,6 +140,7 @@
140
140
  "@testing-library/jest-dom": "^6",
141
141
  "@testing-library/react": "^14",
142
142
  "@types/chroma-js": "^2",
143
+ "@types/json-schema": "^7.0.15",
143
144
  "@types/lodash": "^4",
144
145
  "@types/lodash-es": "^4",
145
146
  "@types/node": "^20",
@@ -15,7 +15,12 @@ const Topics = memo(() => {
15
15
  const { t } = useTranslation('chat');
16
16
 
17
17
  return (
18
- <Modal onCancel={() => toggleConfig(false)} open={showAgentSettings} title={t('topic.title')}>
18
+ <Modal
19
+ allowFullscreen
20
+ onCancel={() => toggleConfig(false)}
21
+ open={showAgentSettings}
22
+ title={t('topic.title')}
23
+ >
19
24
  <TopicListContent mobile />
20
25
  </Modal>
21
26
  );
@@ -1,9 +1,7 @@
1
1
  import { SiOpenai } from '@icons-pack/react-simple-icons';
2
2
  import { Avatar, ChatHeaderTitle, Logo, Markdown, Tag } from '@lobehub/ui';
3
- import { Button, SegmentedProps } from 'antd';
4
- import dayjs from 'dayjs';
5
- import { domToJpeg, domToPng, domToSvg, domToWebp } from 'modern-screenshot';
6
- import { memo, useCallback, useState } from 'react';
3
+ import { SegmentedProps } from 'antd';
4
+ import { memo } from 'react';
7
5
  import { useTranslation } from 'react-i18next';
8
6
  import { Flexbox } from 'react-layout-kit';
9
7
 
@@ -14,6 +12,7 @@ import { agentSelectors, sessionSelectors } from '@/store/session/selectors';
14
12
 
15
13
  import PluginTag from '../../ChatHeader/PluginTag';
16
14
  import { useStyles } from './style';
15
+ import { FieldType } from './type';
17
16
 
18
17
  export enum ImageType {
19
18
  JPG = 'jpg',
@@ -41,75 +40,25 @@ export const imageTypeOptions: SegmentedProps['options'] = [
41
40
  },
42
41
  ];
43
42
 
44
- interface PreviewProps {
45
- imageType: ImageType;
46
- withBackground: boolean;
47
- withFooter: boolean;
48
- withSystemRole: boolean;
49
- }
50
-
51
- const Preview = memo<PreviewProps>(({ withSystemRole, imageType, withBackground, withFooter }) => {
52
- const [loading, setLoading] = useState(false);
53
- const [isInbox, title, description, avatar, backgroundColor, model, plugins, systemRole] =
54
- useSessionStore((s) => [
55
- sessionSelectors.isInboxSession(s),
56
- agentSelectors.currentAgentTitle(s),
57
- agentSelectors.currentAgentDescription(s),
58
- agentSelectors.currentAgentAvatar(s),
59
- agentSelectors.currentAgentBackgroundColor(s),
60
- agentSelectors.currentAgentModel(s),
61
- agentSelectors.currentAgentPlugins(s),
62
- agentSelectors.currentAgentSystemRole(s),
63
- ]);
64
- const { t } = useTranslation('chat');
65
- const { styles } = useStyles(withBackground);
66
-
67
- const displayTitle = isInbox ? t('inbox.title') : title;
68
- const displayDesc = isInbox ? t('inbox.desc') : description;
43
+ const Preview = memo<FieldType & { title?: string }>(
44
+ ({ title, withSystemRole, withBackground, withFooter }) => {
45
+ const [isInbox, description, avatar, backgroundColor, model, plugins, systemRole] =
46
+ useSessionStore((s) => [
47
+ sessionSelectors.isInboxSession(s),
48
+ agentSelectors.currentAgentDescription(s),
49
+ agentSelectors.currentAgentAvatar(s),
50
+ agentSelectors.currentAgentBackgroundColor(s),
51
+ agentSelectors.currentAgentModel(s),
52
+ agentSelectors.currentAgentPlugins(s),
53
+ agentSelectors.currentAgentSystemRole(s),
54
+ ]);
55
+ const { t } = useTranslation('chat');
56
+ const { styles } = useStyles(withBackground);
69
57
 
70
- const handleDownload = useCallback(async () => {
71
- setLoading(true);
72
- try {
73
- let screenshotFn: any;
74
- switch (imageType) {
75
- case ImageType.JPG: {
76
- screenshotFn = domToJpeg;
77
- break;
78
- }
79
- case ImageType.PNG: {
80
- screenshotFn = domToPng;
81
- break;
82
- }
83
- case ImageType.SVG: {
84
- screenshotFn = domToSvg;
85
- break;
86
- }
87
- case ImageType.WEBP: {
88
- screenshotFn = domToWebp;
89
- break;
90
- }
91
- }
58
+ const displayTitle = isInbox ? t('inbox.title') : title;
59
+ const displayDesc = isInbox ? t('inbox.desc') : description;
92
60
 
93
- const dataUrl = await screenshotFn(document.querySelector('#preview') as HTMLDivElement, {
94
- features: {
95
- // 不启用移除控制符,否则会导致 safari emoji 报错
96
- removeControlCharacter: false,
97
- },
98
- scale: 2,
99
- });
100
- const link = document.createElement('a');
101
- link.download = `LobeChat_${title}_${dayjs().format('YYYY-MM-DD')}.${imageType}`;
102
- link.href = dataUrl;
103
- link.click();
104
- setLoading(false);
105
- } catch (error) {
106
- console.error('Failed to download image', error);
107
- setLoading(false);
108
- }
109
- }, [imageType, title]);
110
-
111
- return (
112
- <>
61
+ return (
113
62
  <div className={styles.preview}>
114
63
  <div className={withBackground ? styles.background : undefined} id={'preview'}>
115
64
  <Flexbox className={styles.container} gap={16}>
@@ -145,11 +94,8 @@ const Preview = memo<PreviewProps>(({ withSystemRole, imageType, withBackground,
145
94
  </Flexbox>
146
95
  </div>
147
96
  </div>
148
- <Button block loading={loading} onClick={handleDownload} size={'large'} type={'primary'}>
149
- {t('shareModal.download')}
150
- </Button>
151
- </>
152
- );
153
- });
97
+ );
98
+ },
99
+ );
154
100
 
155
101
  export default Preview;
@@ -0,0 +1,141 @@
1
+ import { Form, type FormItemProps, Modal, type ModalProps } from '@lobehub/ui';
2
+ import { Button, Segmented, SegmentedProps, Switch } from 'antd';
3
+ import { memo, useMemo, useState } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { Flexbox } from 'react-layout-kit';
6
+
7
+ import { useScreenshot } from '@/app/chat/features/ChatHeader/ShareButton/useScreenshot';
8
+ import { FORM_STYLE } from '@/const/layoutTokens';
9
+ import { useChatStore } from '@/store/chat';
10
+ import { useGlobalStore } from '@/store/global';
11
+
12
+ import Preview, { ImageType, imageTypeOptions } from './Preview';
13
+ import { FieldType } from './type';
14
+
15
+ enum Tab {
16
+ Screenshot = 'screenshot',
17
+ ShareGPT = 'sharegpt',
18
+ }
19
+
20
+ const DEFAULT_FIELD_VALUE: FieldType = {
21
+ imageType: ImageType.JPG,
22
+ withBackground: true,
23
+ withFooter: false,
24
+ withPluginInfo: false,
25
+ withSystemRole: false,
26
+ };
27
+
28
+ const ShareModal = memo<ModalProps>(({ onCancel, open }) => {
29
+ const [fieldValue, setFieldValue] = useState<FieldType>(DEFAULT_FIELD_VALUE);
30
+ const [tab, setTab] = useState<Tab>(Tab.Screenshot);
31
+ const { t } = useTranslation('chat');
32
+ const avatar = useGlobalStore((s) => s.settings.avatar);
33
+ const [shareLoading, shareToShareGPT] = useChatStore((s) => [s.shareLoading, s.shareToShareGPT]);
34
+ const { loading, onDwnload, title } = useScreenshot(fieldValue.imageType);
35
+
36
+ const options: SegmentedProps['options'] = useMemo(
37
+ () => [
38
+ {
39
+ label: t('shareModal.screenshot'),
40
+ value: Tab.Screenshot,
41
+ },
42
+ {
43
+ label: 'ShareGPT',
44
+ value: Tab.ShareGPT,
45
+ },
46
+ ],
47
+ [],
48
+ );
49
+
50
+ const settings: FormItemProps[] = useMemo(
51
+ () =>
52
+ [
53
+ {
54
+ children: <Switch />,
55
+ label: t('shareModal.withSystemRole'),
56
+ minWidth: undefined,
57
+ name: 'withSystemRole',
58
+ valuePropName: 'checked',
59
+ },
60
+ tab === Tab.Screenshot && {
61
+ children: <Switch />,
62
+ label: t('shareModal.withBackground'),
63
+ minWidth: undefined,
64
+ name: 'withBackground',
65
+ valuePropName: 'checked',
66
+ },
67
+ tab === Tab.Screenshot && {
68
+ children: <Switch />,
69
+ label: t('shareModal.withFooter'),
70
+ minWidth: undefined,
71
+ name: 'withFooter',
72
+ valuePropName: 'checked',
73
+ },
74
+ tab === Tab.Screenshot && {
75
+ children: <Segmented options={imageTypeOptions} />,
76
+ label: t('shareModal.imageType'),
77
+ minWidth: undefined,
78
+ name: 'imageType',
79
+ },
80
+ tab === Tab.ShareGPT && {
81
+ children: <Switch />,
82
+ label: t('shareModal.withPluginInfo'),
83
+ minWidth: undefined,
84
+ name: 'withPluginInfo',
85
+ valuePropName: 'checked',
86
+ },
87
+ ].filter(Boolean) as FormItemProps[],
88
+ [],
89
+ );
90
+
91
+ return (
92
+ <Modal
93
+ allowFullscreen
94
+ centered={false}
95
+ footer={
96
+ <>
97
+ {tab === Tab.Screenshot && (
98
+ <Button block loading={loading} onClick={onDwnload} size={'large'} type={'primary'}>
99
+ {t('shareModal.download')}
100
+ </Button>
101
+ )}
102
+ {tab === Tab.ShareGPT && (
103
+ <Button
104
+ block
105
+ loading={shareLoading}
106
+ onClick={() => shareToShareGPT({ avatar, ...fieldValue })}
107
+ size={'large'}
108
+ type={'primary'}
109
+ >
110
+ {t('shareModal.shareToShareGPT')}
111
+ </Button>
112
+ )}
113
+ </>
114
+ }
115
+ maxHeight={false}
116
+ onCancel={onCancel}
117
+ open={open}
118
+ title={t('share', { ns: 'common' })}
119
+ >
120
+ <Flexbox gap={16}>
121
+ <Segmented
122
+ block
123
+ onChange={(value) => setTab(value as Tab)}
124
+ options={options}
125
+ style={{ width: '100%' }}
126
+ value={tab}
127
+ />
128
+ <Form
129
+ initialValues={DEFAULT_FIELD_VALUE}
130
+ items={settings}
131
+ itemsType={'flat'}
132
+ onValuesChange={(_, v) => setFieldValue(v)}
133
+ {...FORM_STYLE}
134
+ />
135
+ {tab === Tab.Screenshot && <Preview title={title} {...fieldValue} />}
136
+ </Flexbox>
137
+ </Modal>
138
+ );
139
+ });
140
+
141
+ export default ShareModal;
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Modal } from '@lobehub/ui';
1
+ import { ActionIcon } from '@lobehub/ui';
2
2
  import { Share2 } from 'lucide-react';
3
3
  import dynamic from 'next/dynamic';
4
4
  import { memo } from 'react';
@@ -8,7 +8,7 @@ import useMergeState from 'use-merge-value';
8
8
  import { DESKTOP_HEADER_ICON_SIZE, MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
9
9
  import { useChatStore } from '@/store/chat';
10
10
 
11
- const Inner = dynamic(() => import('./Inner'));
11
+ const ShareModal = dynamic(() => import('./ShareModal'));
12
12
  interface ShareButtonProps {
13
13
  mobile?: boolean;
14
14
  open?: boolean;
@@ -34,15 +34,7 @@ const ShareButton = memo<ShareButtonProps>(({ mobile, setOpen, open }) => {
34
34
  title={t('share')}
35
35
  />
36
36
 
37
- <Modal
38
- centered={false}
39
- footer={null}
40
- onCancel={() => setIsModalOpen(false)}
41
- open={isModalOpen}
42
- title={t('share')}
43
- >
44
- <Inner />
45
- </Modal>
37
+ <ShareModal onCancel={() => setIsModalOpen(false)} open={isModalOpen} />
46
38
  </>
47
39
  );
48
40
  });
@@ -0,0 +1,14 @@
1
+ export enum ImageType {
2
+ JPG = 'jpg',
3
+ PNG = 'png',
4
+ SVG = 'svg',
5
+ WEBP = 'webp',
6
+ }
7
+
8
+ export type FieldType = {
9
+ imageType: ImageType;
10
+ withBackground: boolean;
11
+ withFooter: boolean;
12
+ withPluginInfo: boolean;
13
+ withSystemRole: boolean;
14
+ };
@@ -0,0 +1,60 @@
1
+ import dayjs from 'dayjs';
2
+ import { domToJpeg, domToPng, domToSvg, domToWebp } from 'modern-screenshot';
3
+ import { useCallback, useState } from 'react';
4
+
5
+ import { useSessionStore } from '@/store/session';
6
+ import { agentSelectors } from '@/store/session/slices/agent';
7
+
8
+ import { ImageType } from './type';
9
+
10
+ export const useScreenshot = (imageType: ImageType) => {
11
+ const [loading, setLoading] = useState(false);
12
+ const title = useSessionStore(agentSelectors.currentAgentTitle);
13
+
14
+ const handleDownload = useCallback(async () => {
15
+ setLoading(true);
16
+ try {
17
+ let screenshotFn: any;
18
+ switch (imageType) {
19
+ case ImageType.JPG: {
20
+ screenshotFn = domToJpeg;
21
+ break;
22
+ }
23
+ case ImageType.PNG: {
24
+ screenshotFn = domToPng;
25
+ break;
26
+ }
27
+ case ImageType.SVG: {
28
+ screenshotFn = domToSvg;
29
+ break;
30
+ }
31
+ case ImageType.WEBP: {
32
+ screenshotFn = domToWebp;
33
+ break;
34
+ }
35
+ }
36
+
37
+ const dataUrl = await screenshotFn(document.querySelector('#preview') as HTMLDivElement, {
38
+ features: {
39
+ // 不启用移除控制符,否则会导致 safari emoji 报错
40
+ removeControlCharacter: false,
41
+ },
42
+ scale: 2,
43
+ });
44
+ const link = document.createElement('a');
45
+ link.download = `LobeChat_${title}_${dayjs().format('YYYY-MM-DD')}.${imageType}`;
46
+ link.href = dataUrl;
47
+ link.click();
48
+ setLoading(false);
49
+ } catch (error) {
50
+ console.error('Failed to download image', error);
51
+ setLoading(false);
52
+ }
53
+ }, [imageType, title]);
54
+
55
+ return {
56
+ loading,
57
+ onDwnload: handleDownload,
58
+ title,
59
+ };
60
+ };
@@ -78,7 +78,6 @@ const SystemRole = memo(() => {
78
78
  <EditableMessage
79
79
  classNames={{ markdown: styles.prompt }}
80
80
  editing={editing}
81
- height={editing ? 'calc(70vh - 108px)' : 'calc(70vh - 357.43px)'}
82
81
  model={{
83
82
  extra: (
84
83
  <AgentInfo
@@ -7,17 +7,11 @@ import TopicSearchBar from './TopicSearchBar';
7
7
 
8
8
  const TopicListContent = memo<{ mobile?: boolean }>(({ mobile }) => {
9
9
  return (
10
- <Flexbox height={'100%'} style={{ overflow: 'hidden' }}>
11
- {mobile ? (
12
- <Flexbox padding={'12px 16px'}>
13
- <TopicSearchBar />
14
- </Flexbox>
15
- ) : (
16
- <Header />
17
- )}
10
+ <Flexbox gap={mobile ? 8 : 0} height={'100%'} style={{ overflow: 'hidden' }}>
11
+ {mobile ? <TopicSearchBar /> : <Header />}
18
12
  <Flexbox
19
13
  gap={16}
20
- paddingInline={mobile ? 16 : 8}
14
+ paddingInline={mobile ? 0 : 8}
21
15
  style={{ overflowY: 'auto', paddingTop: 6, position: 'relative' }}
22
16
  >
23
17
  <Topic />
@@ -1,4 +1,4 @@
1
- import { Alert } from '@lobehub/ui';
1
+ import { Alert, Modal, type ModalProps } from '@lobehub/ui';
2
2
  import { Button, Divider, Input } from 'antd';
3
3
  import { useTheme } from 'antd-style';
4
4
  import isEqual from 'fast-deep-equal';
@@ -8,14 +8,13 @@ import { memo, useState } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
  import { Flexbox } from 'react-layout-kit';
10
10
 
11
- import MobilePadding from '@/components/MobilePadding';
12
11
  import { AGENTS_INDEX_GITHUB_ISSUE } from '@/const/url';
13
12
  import AgentInfo from '@/features/AgentInfo';
14
13
  import { useGlobalStore } from '@/store/global';
15
14
  import { useSessionStore } from '@/store/session';
16
15
  import { agentSelectors } from '@/store/session/selectors';
17
16
 
18
- const Inner = memo(() => {
17
+ const SubmitAgentModal = memo<ModalProps>(({ open, onCancel }) => {
19
18
  const { t } = useTranslation('setting');
20
19
  const [identifier, setIdentifier] = useState('');
21
20
  const systemRole = useSessionStore(agentSelectors.currentAgentSystemRole);
@@ -54,8 +53,24 @@ const Inner = memo(() => {
54
53
  };
55
54
 
56
55
  return (
57
- <Flexbox gap={16}>
58
- <MobilePadding gap={16}>
56
+ <Modal
57
+ allowFullscreen
58
+ footer={
59
+ <Button
60
+ block
61
+ disabled={!isMetaPass || !identifier}
62
+ onClick={handleSubmit}
63
+ size={'large'}
64
+ type={'primary'}
65
+ >
66
+ {t('submitAgentModal.button')}
67
+ </Button>
68
+ }
69
+ onCancel={onCancel}
70
+ open={open}
71
+ title={t('submitAgentModal.tooltips')}
72
+ >
73
+ <Flexbox gap={16}>
59
74
  {!isMetaPass && (
60
75
  <Alert message={t('submitAgentModal.metaMiss')} showIcon type={'warning'} />
61
76
  )}
@@ -70,18 +85,9 @@ const Inner = memo(() => {
70
85
  placeholder={t('submitAgentModal.placeholder')}
71
86
  value={identifier}
72
87
  />
73
- <Button
74
- block
75
- disabled={!isMetaPass || !identifier}
76
- onClick={handleSubmit}
77
- size={'large'}
78
- type={'primary'}
79
- >
80
- {t('submitAgentModal.button')}
81
- </Button>
82
- </MobilePadding>
83
- </Flexbox>
88
+ </Flexbox>
89
+ </Modal>
84
90
  );
85
91
  });
86
92
 
87
- export default Inner;
93
+ export default SubmitAgentModal;
@@ -1,4 +1,4 @@
1
- import { ActionIcon, Modal } from '@lobehub/ui';
1
+ import { ActionIcon } from '@lobehub/ui';
2
2
  import { useResponsive } from 'antd-style';
3
3
  import { Share2 } from 'lucide-react';
4
4
  import { memo, useState } from 'react';
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
 
7
7
  import { HEADER_ICON_SIZE } from '@/const/layoutTokens';
8
8
 
9
- import Inner from './Inner';
9
+ import SubmitAgentModal from './SubmitAgentModal';
10
10
 
11
11
  const SubmitAgentButton = memo(() => {
12
12
  const { t } = useTranslation('setting');
@@ -20,14 +20,7 @@ const SubmitAgentButton = memo(() => {
20
20
  size={HEADER_ICON_SIZE(mobile)}
21
21
  title={t('submitAgentModal.tooltips')}
22
22
  />
23
- <Modal
24
- footer={null}
25
- onCancel={() => setIsModalOpen(false)}
26
- open={isModalOpen}
27
- title={t('submitAgentModal.tooltips')}
28
- >
29
- <Inner />
30
- </Modal>
23
+ <SubmitAgentModal onCancel={() => setIsModalOpen(false)} open={isModalOpen} />
31
24
  </>
32
25
  );
33
26
  });
@@ -15,7 +15,13 @@ const AgentDetail = memo(() => {
15
15
  const { t } = useTranslation('market');
16
16
 
17
17
  return (
18
- <Modal onCancel={deactivateAgent} open={showAgentSidebar} title={t('sidebar.title')}>
18
+ <Modal
19
+ allowFullscreen
20
+ onCancel={deactivateAgent}
21
+ open={showAgentSidebar}
22
+ styles={{ body: { padding: 0 } }}
23
+ title={t('sidebar.title')}
24
+ >
19
25
  <AgentDetailContent />
20
26
  </Modal>
21
27
  );
@@ -5,13 +5,12 @@ import Image from 'next/image';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
8
- import MobilePadding from '@/components/MobilePadding';
9
8
  import { AGENTS_INDEX_GITHUB } from '@/const/url';
10
9
 
11
10
  const Inner = memo(() => {
12
11
  const { t } = useTranslation('market');
13
12
  return (
14
- <MobilePadding>
13
+ <>
15
14
  <Image
16
15
  alt={'banner'}
17
16
  height={602}
@@ -46,7 +45,7 @@ const Inner = memo(() => {
46
45
  >
47
46
  {t('guide.func2.button')}
48
47
  </Button>
49
- </MobilePadding>
48
+ </>
50
49
  );
51
50
  });
52
51