@lobehub/chat 0.80.2 → 0.82.1

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 (35) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/docs/Analytics.zh-CN.md +19 -0
  3. package/docs/Environment-Variable.zh-CN.md +77 -1
  4. package/locales/en_US/common.json +12 -0
  5. package/locales/ru_RU/common.json +12 -0
  6. package/locales/zh_CN/common.json +12 -0
  7. package/locales/zh_TW/common.json +12 -0
  8. package/next.config.mjs +4 -0
  9. package/package.json +9 -3
  10. package/public/images/screenshot_background.webp +0 -0
  11. package/public/manifest.json +2 -16
  12. package/src/app/chat/features/Conversation/ChatList/Error/InvalidAccess.tsx +16 -6
  13. package/src/app/chat/features/Header/ShareButton/Inner.tsx +109 -14
  14. package/src/app/chat/features/Header/ShareButton/Preview.tsx +140 -0
  15. package/src/app/chat/features/Header/ShareButton/index.tsx +6 -1
  16. package/src/app/chat/features/Header/ShareButton/style.ts +71 -0
  17. package/src/components/Analytics/Mixpanel.tsx +23 -0
  18. package/src/components/Analytics/Plausible.tsx +18 -0
  19. package/src/components/Analytics/Posthog.tsx +23 -0
  20. package/src/components/Analytics/Vercel.tsx +12 -0
  21. package/src/components/Analytics/index.tsx +19 -2
  22. package/src/components/AppTheme/index.tsx +3 -4
  23. package/src/config/client.ts +46 -0
  24. package/src/config/server.ts +9 -6
  25. package/src/const/url.ts +4 -2
  26. package/src/features/AvatarWithUpload/index.tsx +23 -45
  27. package/src/features/SideBar/index.tsx +1 -1
  28. package/src/locales/create.ts +5 -3
  29. package/src/locales/default/common.ts +12 -0
  30. package/src/services/shareGPT.ts +11 -1
  31. package/src/store/session/slices/chat/actions/share.ts +73 -39
  32. package/src/utils/imageToBase64.ts +37 -0
  33. package/src/utils/parseMarkdown.ts +9 -0
  34. package/public/icons/icon-maskable-192x192.png +0 -0
  35. package/public/icons/icon-maskable-512x512.png +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,81 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 0.82.1](https://github.com/lobehub/lobe-chat/compare/v0.82.0...v0.82.1)
6
+
7
+ <sup>Released on **2023-09-27**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix share screenshot scrollbar.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix share screenshot scrollbar ([244b3b4](https://github.com/lobehub/lobe-chat/commit/244b3b4))
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.82.0](https://github.com/lobehub/lobe-chat/compare/v0.81.0...v0.82.0)
31
+
32
+ <sup>Released on **2023-09-27**</sup>
33
+
34
+ #### ✨ Features
35
+
36
+ - **share**: Add screenshot.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's improved
44
+
45
+ - **share**: Add screenshot, closes [#152](https://github.com/lobehub/lobe-chat/issues/152) ([f5d21f4](https://github.com/lobehub/lobe-chat/commit/f5d21f4))
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
+
55
+ ## [Version 0.81.0](https://github.com/lobehub/lobe-chat/compare/v0.80.2...v0.81.0)
56
+
57
+ <sup>Released on **2023-09-27**</sup>
58
+
59
+ #### ✨ Features
60
+
61
+ - **misc**: Add several analytics sdk.
62
+
63
+ <br/>
64
+
65
+ <details>
66
+ <summary><kbd>Improvements and Fixes</kbd></summary>
67
+
68
+ #### What's improved
69
+
70
+ - **misc**: Add several analytics sdk, closes [#244](https://github.com/lobehub/lobe-chat/issues/244) ([65c6c93](https://github.com/lobehub/lobe-chat/commit/65c6c93))
71
+
72
+ </details>
73
+
74
+ <div align="right">
75
+
76
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
77
+
78
+ </div>
79
+
5
80
  ### [Version 0.80.2](https://github.com/lobehub/lobe-chat/compare/v0.80.1...v0.80.2)
6
81
 
7
82
  <sup>Released on **2023-09-27**</sup>
@@ -0,0 +1,19 @@
1
+ # 数据统计
2
+
3
+ 为更好地帮助分析 LobeChat 的用户使用情况,我们在 LobeChat 中集成了若干免费 / 开源的数据统计服务,用于收集用户的使用情况,你可以按需开启。
4
+
5
+ ## Vercel Analytics
6
+
7
+ [Vercel Analytics](https://vercel.com/analytics) 是 Vercel 推出的一款数据分析服务,它可以帮助你收集网站的访问情况,包括访问量、访问来源、访问设备等等。
8
+
9
+ 由于我们推荐使用 Vercel 一键部署 LobeChat,因此我们在代码中默认集成了 Vercel Analytics,你可以通过自行打开部署项目中 \[Insights] tab,查看你的应用访问情况。
10
+
11
+ Vercel Analytics 提供了 2500 次 / 月的免费 Web Analytics Events (可以理解为 PV),对于个人部署自用的产品来说基本够用。
12
+
13
+ 如果你需要了解 Vercel Analytics 的详细使用教程,请查阅[Vercel Web Analytics 快速开始](https://vercel.com/docs/analytics/quickstart)
14
+
15
+ 如果你不需要 Vercel Analytics,你可以通过设置环境变量 `NEXT_PUBLIC_ANALYTICS_VERCEL=0` 来关闭它。
16
+
17
+ ## 🚧 Posthog
18
+
19
+ ## 🚧 Mixpanel
@@ -17,6 +17,10 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
17
17
  - [`PLUGINS_INDEX_URL`](#plugins_index_url)
18
18
  - [角色服务](#角色服务)
19
19
  - [`AGENTS_INDEX_URL`](#agents_index_url)
20
+ - [数据统计](#数据统计)
21
+ - [Vercel Analytics](#vercel-analytics)
22
+ - [Mixpanel Analytics](#mixpanel-analytics)
23
+ - [Posthog Analytics](#posthog-analytics)
20
24
  - [开发环境](#开发环境)
21
25
  - [`DEV_API_END_PORT_URL`](#dev_api_end_port_url)
22
26
 
@@ -94,7 +98,76 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
94
98
  - 描述:LobeChat 角色市场的索引地址,如果你自行部署了角色市场的服务,可以使用该变量来覆盖默认的插件市场地址
95
99
  - 默认值:`https://chat-agents.lobehub.com`
96
100
 
97
- <br/>
101
+ ## 数据统计
102
+
103
+ ### Vercel Analytics
104
+
105
+ #### `NEXT_PUBLIC_ANALYTICS_VERCEL`
106
+
107
+ - 类型:可选
108
+ - 描述:用于配置 Vercel Analytics 的环境变量,当设为 `0` 则关闭 Vercel Analytics
109
+ - 默认值: -
110
+ - 示例:`0`
111
+
112
+ #### `NEXT_PUBLIC_VERCEL_DEBUG`
113
+
114
+ - 类型:可选
115
+ - 描述:用于开启 Vercel Analytics 的调试模式
116
+ - 默认值: -
117
+ - 示例:`1`
118
+
119
+ ### Mixpanel Analytics
120
+
121
+ #### `NEXT_PUBLIC_ANALYTICS_MIXPANEL`
122
+
123
+ - 类型:可选
124
+ - 描述:用于开启 [Mixpanel Analytics][mixpanel-analytics-url] 的环境变量,设为 `1` 时开启 Mixpanel Analytics
125
+ - 默认值: -
126
+ - 示例:`1`
127
+
128
+ #### `NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN`
129
+
130
+ - 类型:可选
131
+ - 描述:设置 Mixpanel 项目的识别 Token,可以在[这里][mixpanel-project-url]找到
132
+ - 默认值: -
133
+ - 示例:`60db2abae7fdd29961f4e8f91b074b3a`
134
+
135
+ #### `NEXT_PUBLIC_MIXPANEL_DEBUG`
136
+
137
+ - 类型:可选
138
+ - 描述:开启 Mixpanel 的调试模式
139
+ - 默认值: -
140
+ - 示例:`1`
141
+
142
+ ### Posthog Analytics
143
+
144
+ #### `NEXT_PUBLIC_ANALYTICS_POSTHOG`
145
+
146
+ - 类型:可选
147
+ - 描述:用于开启 [PostHog Analytics][posthog-analytics-url] 的环境变量,设为 `1` 时开启 PostHog Analytics
148
+ - 默认值: -
149
+ - 示例:`1`
150
+
151
+ #### `NEXT_PUBLIC_POSTHOG_KEY`
152
+
153
+ - 类型:可选
154
+ - 描述:设置 PostHog 项目 Key
155
+ - 默认值: -
156
+ - 示例:`phc_xxxxxxxx`
157
+
158
+ #### `NEXT_PUBLIC_POSTHOG_HOST`
159
+
160
+ - 类型:可选
161
+ - 描述:设置 PostHog 服务的部署地址,默认为官方的 SAAS 地址
162
+ - 默认值:`https://app.posthog.com`
163
+ - 示例:`https://example.com`
164
+
165
+ #### `NEXT_PUBLIC_POSTHOG_DEBUG`
166
+
167
+ - 类型:可选
168
+ - 描述:开启 PostHog 的调试模式
169
+ - 默认值: -
170
+ - 示例:`1`
98
171
 
99
172
  ## 开发环境
100
173
 
@@ -106,4 +179,7 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
106
179
  - 示例:`https://chat-preview.lobehub.com`
107
180
 
108
181
  [azure-api-verion-url]: https://docs.microsoft.com/zh-cn/azure/developer/javascript/api-reference/es-modules/azure-sdk/ai-translation/translationconfiguration?view=azure-node-latest#api-version
182
+ [mixpanel-analytics-url]: https://mixpanel.com
183
+ [mixpanel-project-url]: https://mixpanel.com/settings/project
109
184
  [openai-api-page]: https://platform.openai.com/account/api-keys
185
+ [posthog-analytics-url]: https://posthog.com
@@ -47,6 +47,7 @@
47
47
  "newAgent": "New Agent",
48
48
  "noDescription": "No Description",
49
49
  "ok": "OK",
50
+ "password": "Password",
50
51
  "pin": "Pin",
51
52
  "pinOff": "Unpin",
52
53
  "regenerate": "Regenerate",
@@ -60,6 +61,17 @@
60
61
  "sessionList": "Agent List",
61
62
  "setting": "Settings",
62
63
  "share": "Share",
64
+ "shareModal": {
65
+ "download": "Download Screenshot",
66
+ "imageType": "Image Type",
67
+ "screenshot": "Screenshot",
68
+ "settings": "Export Settings",
69
+ "withBackground": "Include Background Image",
70
+ "withPluginInfo": "Include Plugin Information",
71
+ "withSystemRole": "Include Agent Role Setting",
72
+ "withFooter": "Including footer",
73
+ "shareToShareGPT": "Generate ShareGPT sharing link"
74
+ },
63
75
  "stop": "Stop",
64
76
  "tab": {
65
77
  "chat": "Chat",
@@ -47,6 +47,7 @@
47
47
  "newAgent": "Новый ассистент",
48
48
  "noDescription": "Нет описания",
49
49
  "ok": "ОК",
50
+ "password": "пароль",
50
51
  "pin": "Закрепить",
51
52
  "pinOff": "Открепить",
52
53
  "regenerate": "Ре-генерация",
@@ -60,6 +61,17 @@
60
61
  "sessionList": "Список помощников",
61
62
  "setting": "Настройки",
62
63
  "share": "Поделиться",
64
+ "shareModal": {
65
+ "download": "Скачать скриншот",
66
+ "imageType": "Тип изображения",
67
+ "screenshot": "Скриншот",
68
+ "settings": "Настройки экспорта",
69
+ "withBackground": "С фоновым изображением",
70
+ "withPluginInfo": "С информацией о плагине",
71
+ "withSystemRole": "С настройками роли помощника",
72
+ "withFooter": "с подвалом",
73
+ "shareToShareGPT": "Создать ссылку для обмена ShareGPT"
74
+ },
63
75
  "stop": "Остановить",
64
76
  "tab": {
65
77
  "chat": "Чат",
@@ -47,6 +47,7 @@
47
47
  "newAgent": "新建助手",
48
48
  "noDescription": "暂无描述",
49
49
  "ok": "确定",
50
+ "password": "密码",
50
51
  "pin": "置顶",
51
52
  "pinOff": "取消置顶",
52
53
  "regenerate": "重新生成",
@@ -60,6 +61,17 @@
60
61
  "sessionList": "助手列表",
61
62
  "setting": "设置",
62
63
  "share": "分享",
64
+ "shareModal": {
65
+ "download": "下载截图",
66
+ "imageType": "图片格式",
67
+ "screenshot": "截图",
68
+ "settings": "导出设置",
69
+ "shareToShareGPT": "生成 ShareGPT 分享链接",
70
+ "withBackground": "包含背景图片",
71
+ "withFooter": "包含页脚",
72
+ "withPluginInfo": "包含插件信息",
73
+ "withSystemRole": "包含助手角色设定"
74
+ },
63
75
  "stop": "停止",
64
76
  "tab": {
65
77
  "chat": "会话",
@@ -47,6 +47,7 @@
47
47
  "newAgent": "新助理",
48
48
  "noDescription": "無描述",
49
49
  "ok": "確定",
50
+ "password": "密碼",
50
51
  "pin": "置頂",
51
52
  "pinOff": "取消置頂",
52
53
  "regenerate": "重新產生",
@@ -60,6 +61,17 @@
60
61
  "sessionList": "助理列表",
61
62
  "setting": "設定",
62
63
  "share": "分享",
64
+ "shareModal": {
65
+ "download": "下載截圖",
66
+ "imageType": "圖片格式",
67
+ "screenshot": "截圖",
68
+ "settings": "匯出設定",
69
+ "withBackground": "包含背景圖片",
70
+ "withPluginInfo": "包含插件資訊",
71
+ "withSystemRole": "包含助手角色設定",
72
+ "withFooter": "包含頁腳",
73
+ "shareToShareGPT": "生成 ShareGPT 分享連結"
74
+ },
63
75
  "stop": "停止",
64
76
  "tab": {
65
77
  "chat": "聊天",
package/next.config.mjs CHANGED
@@ -41,6 +41,10 @@ const nextConfig = {
41
41
  },
42
42
  ];
43
43
  },
44
+ env: {
45
+ AGENTS_INDEX_URL: process.env.AGENTS_INDEX_URL,
46
+ PLUGINS_INDEX_URL: process.env.PLUGINS_INDEX_URL,
47
+ },
44
48
  };
45
49
 
46
50
  export default isProd ? withPWA(nextConfig) : nextConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.80.2",
3
+ "version": "0.82.1",
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",
@@ -78,25 +78,31 @@
78
78
  "antd-style": "^3",
79
79
  "brotli-wasm": "^1",
80
80
  "chroma-js": "^2",
81
+ "dayjs": "^1",
81
82
  "emoji-mart": "^5",
82
83
  "fast-deep-equal": "^3",
83
84
  "gpt-tokenizer": "^2",
85
+ "html-to-image": "^1",
84
86
  "i18next": "^23",
85
87
  "idb-keyval": "^6",
86
88
  "immer": "^10",
87
89
  "lodash-es": "^4",
88
90
  "lucide-react": "latest",
91
+ "mixpanel-browser": "^2",
89
92
  "nanoid": "^5",
90
93
  "next": "^13.5.3",
91
94
  "openai": "^4",
92
95
  "polished": "^4",
96
+ "posthog-js": "^1",
93
97
  "react": "^18",
94
98
  "react-dom": "^18",
95
99
  "react-hotkeys-hook": "^4",
96
100
  "react-i18next": "^13",
97
101
  "react-intersection-observer": "^9",
98
102
  "react-layout-kit": "^1",
99
- "satori": "^0.10",
103
+ "remark": "^14",
104
+ "remark-gfm": "^3",
105
+ "remark-html": "^15",
100
106
  "swr": "^2",
101
107
  "systemjs": "^6",
102
108
  "ts-md5": "^1",
@@ -116,6 +122,7 @@
116
122
  "@testing-library/react": "^14",
117
123
  "@types/chroma-js": "^2",
118
124
  "@types/lodash-es": "^4",
125
+ "@types/mixpanel-browser": "^2",
119
126
  "@types/node": "^20",
120
127
  "@types/react": "^18",
121
128
  "@types/react-dom": "^18",
@@ -135,7 +142,6 @@
135
142
  "next-pwa": "^5",
136
143
  "node-fetch": "^3",
137
144
  "prettier": "^3",
138
- "remark": "^14",
139
145
  "remark-cli": "^11",
140
146
  "semantic-release": "^21",
141
147
  "stylelint": "^15",
@@ -6,26 +6,12 @@
6
6
  {
7
7
  "src": "/icons/icon-192x192.png",
8
8
  "sizes": "192x192",
9
- "type": "image/png",
10
- "purpose": "any"
11
- },
12
- {
13
- "src": "/icons/icon-maskable-192x192.png",
14
- "sizes": "192x192",
15
- "type": "image/png",
16
- "purpose": "maskable"
9
+ "type": "image/png"
17
10
  },
18
11
  {
19
12
  "src": "/icons/icon-512x512.png",
20
13
  "sizes": "512x512",
21
- "type": "image/png",
22
- "purpose": "any"
23
- },
24
- {
25
- "src": "/icons/icon-maskable-512x512.png",
26
- "sizes": "512x512",
27
- "type": "image/png",
28
- "purpose": "maskable"
14
+ "type": "image/png"
29
15
  }
30
16
  ],
31
17
  "id": "/",
@@ -12,9 +12,14 @@ import OtpInput from '../OTPInput';
12
12
  import APIKeyForm from './ApiKeyForm';
13
13
  import { ErrorActionContainer, FormAction } from './style';
14
14
 
15
+ enum Tab {
16
+ Api = 'api',
17
+ Password = 'password',
18
+ }
19
+
15
20
  const InvalidAccess = memo<{ id: string }>(({ id }) => {
16
21
  const { t } = useTranslation('error');
17
- const [mode, setMode] = useState('password');
22
+ const [mode, setMode] = useState<Tab>(Tab.Password);
18
23
  const [password, setSettings] = useGlobalStore((s) => [s.settings.password, s.setSettings]);
19
24
  const [resend, deleteMessage] = useSessionStore((s) => [s.resendMessage, s.deleteMessage]);
20
25
 
@@ -22,16 +27,20 @@ const InvalidAccess = memo<{ id: string }>(({ id }) => {
22
27
  <ErrorActionContainer>
23
28
  <Segmented
24
29
  block
25
- onChange={(value) => setMode(value as string)}
30
+ onChange={(value) => setMode(value as Tab)}
26
31
  options={[
27
- { icon: <Icon icon={KeySquare} />, label: 'OpenAI API Key', value: 'api' },
28
- { icon: <Icon icon={SquareAsterisk} />, label: '密码', value: 'password' },
32
+ { icon: <Icon icon={KeySquare} />, label: 'OpenAI API Key', value: Tab.Api },
33
+ {
34
+ icon: <Icon icon={SquareAsterisk} />,
35
+ label: t('password', { ns: 'common' }),
36
+ value: Tab.Password,
37
+ },
29
38
  ]}
30
39
  style={{ width: '100%' }}
31
40
  value={mode}
32
41
  />
33
42
  <Flexbox gap={24}>
34
- {mode === 'password' ? (
43
+ {mode === Tab.Password && (
35
44
  <>
36
45
  <FormAction
37
46
  avatar={'🗳'}
@@ -56,7 +65,8 @@ const InvalidAccess = memo<{ id: string }>(({ id }) => {
56
65
  {t('unlock.confirm')}
57
66
  </Button>
58
67
  </>
59
- ) : (
68
+ )}
69
+ {mode === Tab.Api && (
60
70
  <APIKeyForm
61
71
  onConfirm={() => {
62
72
  resend(id);
@@ -1,28 +1,123 @@
1
- import { ActionIcon, Icon } from '@lobehub/ui';
2
- import { Loader2, Share2 } from 'lucide-react';
3
- import { memo } from 'react';
1
+ import { Form, ItemGroup } from '@lobehub/ui';
2
+ import { Button, Segmented, SegmentedProps, Switch } from 'antd';
3
+ import { Share2 } from 'lucide-react';
4
+ import { memo, useMemo, useState } from 'react';
4
5
  import { useTranslation } from 'react-i18next';
6
+ import { Flexbox } from 'react-layout-kit';
5
7
 
8
+ import { FORM_STYLE } from '@/const/layoutTokens';
9
+ import { useGlobalStore } from '@/store/global';
6
10
  import { useSessionStore } from '@/store/session';
7
11
 
8
- const ShareButton = memo(() => {
12
+ import Preview, { ImageType, imageTypeOptions } from './Preview';
13
+
14
+ enum Tab {
15
+ Screenshot = 'screenshot',
16
+ ShareGPT = 'sharegpt',
17
+ }
18
+
19
+ const Inner = memo(() => {
20
+ const [withSystemRole, setWithSystemRole] = useState(false);
21
+ const [withPluginInfo, setWithPluginInfo] = useState(false);
22
+ const [withBackground, setWithBackground] = useState(true);
23
+ const [withFooter, setWithFooter] = useState(true);
24
+ const [imageType, setImageType] = useState<ImageType>(ImageType.JPG);
25
+ const [tab, setTab] = useState<Tab>(Tab.Screenshot);
9
26
  const { t } = useTranslation('common');
10
27
 
28
+ const avatar = useGlobalStore((s) => s.settings.avatar);
11
29
  const [shareLoading, shareToShareGPT] = useSessionStore((s) => [
12
30
  s.shareLoading,
13
31
  s.shareToShareGPT,
14
32
  ]);
15
33
 
16
- return shareLoading ? (
17
- <Icon icon={Loader2} size={{ fontSize: 24 }} spin />
18
- ) : (
19
- <ActionIcon
20
- icon={Share2}
21
- onClick={shareToShareGPT}
22
- size={{ fontSize: 24 }}
23
- title={t('share')}
24
- />
34
+ const options: SegmentedProps['options'] = useMemo(
35
+ () => [
36
+ {
37
+ label: t('shareModal.screenshot'),
38
+ value: Tab.Screenshot,
39
+ },
40
+ {
41
+ label: 'ShareGPT',
42
+ value: Tab.ShareGPT,
43
+ },
44
+ ],
45
+ [],
46
+ );
47
+
48
+ const settings: ItemGroup = useMemo(
49
+ () =>
50
+ ({
51
+ children: [
52
+ {
53
+ children: <Switch checked={withSystemRole} onChange={setWithSystemRole} />,
54
+ label: t('shareModal.withSystemRole'),
55
+ minWidth: undefined,
56
+ },
57
+ tab === Tab.Screenshot && {
58
+ children: <Switch checked={withBackground} onChange={setWithBackground} />,
59
+ label: t('shareModal.withBackground'),
60
+ minWidth: undefined,
61
+ },
62
+ tab === Tab.Screenshot && {
63
+ children: <Switch checked={withFooter} onChange={setWithFooter} />,
64
+ label: t('shareModal.withFooter'),
65
+ minWidth: undefined,
66
+ },
67
+ tab === Tab.Screenshot && {
68
+ children: (
69
+ <Segmented
70
+ onChange={(value) => setImageType(value as ImageType)}
71
+ options={imageTypeOptions}
72
+ value={imageType}
73
+ />
74
+ ),
75
+ label: t('shareModal.imageType'),
76
+ minWidth: undefined,
77
+ },
78
+ tab === Tab.ShareGPT && {
79
+ children: <Switch checked={withPluginInfo} onChange={setWithPluginInfo} />,
80
+ label: t('shareModal.withPluginInfo'),
81
+ minWidth: undefined,
82
+ },
83
+ ].filter(Boolean),
84
+ icon: Share2,
85
+ title: t('shareModal.settings'),
86
+ }) as ItemGroup,
87
+ [tab, withSystemRole, withPluginInfo, withBackground, withFooter, imageType],
88
+ );
89
+
90
+ return (
91
+ <Flexbox gap={16}>
92
+ <Segmented
93
+ block
94
+ onChange={(value) => setTab(value as Tab)}
95
+ options={options}
96
+ style={{ width: '100%' }}
97
+ value={tab}
98
+ />
99
+ <Form items={[settings]} {...FORM_STYLE} />
100
+ {tab === Tab.Screenshot && (
101
+ <Preview
102
+ imageType={imageType}
103
+ withBackground={withBackground}
104
+ withFooter={withFooter}
105
+ withSystemRole={withSystemRole}
106
+ />
107
+ )}
108
+ {tab === Tab.ShareGPT && (
109
+ <Button
110
+ block
111
+ loading={shareLoading}
112
+ onClick={() => shareToShareGPT({ avatar, withPluginInfo, withSystemRole })}
113
+ size={'large'}
114
+ type={'primary'}
115
+ >
116
+ {t('shareModal.shareToShareGPT')}
117
+ </Button>
118
+ )}
119
+ </Flexbox>
25
120
  );
26
121
  });
27
122
 
28
- export default ShareButton;
123
+ export default Inner;