@lobehub/chat 1.27.3 → 1.28.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/CHANGELOG.md +25 -0
- package/locales/ar/chat.json +7 -1
- package/locales/ar/models.json +3 -0
- package/locales/bg-BG/chat.json +7 -1
- package/locales/bg-BG/models.json +3 -0
- package/locales/de-DE/chat.json +7 -1
- package/locales/de-DE/models.json +3 -0
- package/locales/en-US/chat.json +7 -1
- package/locales/en-US/models.json +3 -0
- package/locales/es-ES/chat.json +7 -1
- package/locales/es-ES/models.json +3 -0
- package/locales/fa-IR/chat.json +7 -1
- package/locales/fa-IR/models.json +3 -0
- package/locales/fr-FR/chat.json +7 -1
- package/locales/fr-FR/models.json +3 -0
- package/locales/it-IT/chat.json +7 -1
- package/locales/it-IT/models.json +3 -0
- package/locales/ja-JP/chat.json +7 -1
- package/locales/ja-JP/models.json +3 -0
- package/locales/ko-KR/chat.json +7 -1
- package/locales/ko-KR/models.json +3 -0
- package/locales/nl-NL/chat.json +7 -1
- package/locales/nl-NL/models.json +3 -0
- package/locales/pl-PL/chat.json +7 -1
- package/locales/pl-PL/models.json +3 -0
- package/locales/pt-BR/chat.json +7 -1
- package/locales/pt-BR/models.json +3 -0
- package/locales/ru-RU/chat.json +7 -1
- package/locales/ru-RU/models.json +3 -0
- package/locales/tr-TR/chat.json +7 -1
- package/locales/tr-TR/models.json +3 -0
- package/locales/vi-VN/chat.json +7 -1
- package/locales/vi-VN/models.json +3 -0
- package/locales/zh-CN/chat.json +7 -1
- package/locales/zh-CN/models.json +3 -0
- package/locales/zh-TW/chat.json +7 -1
- package/locales/zh-TW/models.json +3 -0
- package/package.json +1 -1
- package/src/app/(main)/chat/(workspace)/features/ShareButton/index.tsx +2 -1
- package/src/{app/(main)/chat/(workspace)/features/ShareButton → features/ShareModal/ShareImage}/Preview.tsx +5 -3
- package/src/features/ShareModal/ShareImage/index.tsx +103 -0
- package/src/{app/(main)/chat/(workspace)/features/ShareButton → features/ShareModal/ShareImage}/style.ts +1 -23
- package/src/features/ShareModal/ShareJSON/Preview.tsx +18 -0
- package/src/features/ShareModal/ShareJSON/generateMessages.test.ts +135 -0
- package/src/features/ShareModal/ShareJSON/generateMessages.ts +35 -0
- package/src/features/ShareModal/ShareJSON/index.tsx +99 -0
- package/src/features/ShareModal/ShareJSON/type.ts +4 -0
- package/src/features/ShareModal/ShareText/Preview.tsx +16 -0
- package/src/features/ShareModal/ShareText/index.tsx +119 -0
- package/src/features/ShareModal/ShareText/template.test.ts +178 -0
- package/src/features/ShareModal/ShareText/template.ts +79 -0
- package/src/features/ShareModal/ShareText/type.ts +6 -0
- package/src/features/ShareModal/index.tsx +69 -0
- package/src/features/ShareModal/style.ts +30 -0
- package/src/locales/default/chat.ts +7 -1
- package/src/services/__tests__/share.test.ts +35 -105
- package/src/services/share.ts +0 -30
- package/src/store/chat/slices/share/action.test.ts +7 -198
- package/src/store/chat/slices/share/action.ts +9 -113
- package/src/utils/client/exportFile.ts +20 -0
- package/src/app/(main)/chat/(workspace)/features/ShareButton/ShareModal.tsx +0 -164
- /package/src/{app/(main)/chat/(workspace)/features/ShareButton → features/ShareModal/ShareImage}/type.ts +0 -0
- /package/src/{app/(main)/chat/(workspace)/features/ShareButton → features/ShareModal/ShareImage}/useScreenshot.ts +0 -0
@@ -6,208 +6,17 @@ import { useChatStore } from '@/store/chat';
|
|
6
6
|
import { messageMapKey } from '@/store/chat/utils/messageMapKey';
|
7
7
|
import { ChatMessage } from '@/types/message';
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
beforeEach(() => {
|
14
|
-
shareServiceSpy = vi.spyOn(shareService, 'createShareGPTUrl').mockResolvedValue('test-url');
|
15
|
-
windowOpenSpy = vi.spyOn(window, 'open');
|
16
|
-
});
|
17
|
-
|
18
|
-
afterEach(() => {
|
19
|
-
vi.restoreAllMocks();
|
20
|
-
});
|
21
|
-
|
22
|
-
describe('shareToShareGPT', () => {
|
23
|
-
it('should share to ShareGPT and open a new window', async () => {
|
24
|
-
const { result } = renderHook(() => useChatStore());
|
25
|
-
const shareServiceSpy = vi.spyOn(shareService, 'createShareGPTUrl');
|
26
|
-
const windowOpenSpy = vi.spyOn(window, 'open');
|
27
|
-
const avatar = 'avatar-url';
|
28
|
-
const withPluginInfo = true;
|
29
|
-
const withSystemRole = true;
|
30
|
-
|
31
|
-
await act(async () => {
|
32
|
-
await result.current.shareToShareGPT({ avatar, withPluginInfo, withSystemRole });
|
33
|
-
});
|
34
|
-
|
35
|
-
expect(shareServiceSpy).toHaveBeenCalled();
|
36
|
-
expect(windowOpenSpy).toHaveBeenCalled();
|
37
|
-
});
|
38
|
-
it('should handle messages from different roles correctly', async () => {
|
39
|
-
// 注意:此处需要你根据实际情况模拟 chatSelectors.currentChats 和 agentSelectors 返回的数据
|
40
|
-
// 此外,你可能需要调整 useChatStore 的引用路径
|
41
|
-
const { result } = renderHook(() => useChatStore());
|
42
|
-
await act(async () => {
|
43
|
-
await result.current.shareToShareGPT({
|
44
|
-
withPluginInfo: true,
|
45
|
-
withSystemRole: true,
|
46
|
-
});
|
47
|
-
});
|
48
|
-
// 根据你的逻辑添加对应的expect断言
|
49
|
-
});
|
50
|
-
|
51
|
-
it('should not include system role information when withSystemRole is false or systemRole is undefined', async () => {
|
52
|
-
// 模拟不同的配置以测试这个行为
|
53
|
-
// 你可能需要调整 useChatStore 的引用路径
|
54
|
-
const { result } = renderHook(() => useChatStore());
|
55
|
-
await act(async () => {
|
56
|
-
await result.current.shareToShareGPT({
|
57
|
-
withSystemRole: false,
|
58
|
-
});
|
59
|
-
});
|
60
|
-
// 根据你的逻辑添加对应的expect断言
|
61
|
-
});
|
62
|
-
|
63
|
-
it('should use default avatar URL when avatar is not provided', async () => {
|
64
|
-
const { result } = renderHook(() => useChatStore());
|
65
|
-
await act(async () => {
|
66
|
-
await result.current.shareToShareGPT({});
|
67
|
-
});
|
68
|
-
|
69
|
-
expect(shareServiceSpy).toHaveBeenCalledWith(
|
70
|
-
expect.objectContaining({
|
71
|
-
avatarUrl: DEFAULT_USER_AVATAR_URL,
|
72
|
-
}),
|
73
|
-
);
|
74
|
-
});
|
75
|
-
|
76
|
-
it('should set shareLoading to true before sharing and to false after sharing', async () => {
|
77
|
-
const { result } = renderHook(() => useChatStore());
|
78
|
-
expect(result.current.shareLoading).toBe(false);
|
79
|
-
await act(async () => {
|
80
|
-
await result.current.shareToShareGPT({});
|
81
|
-
});
|
82
|
-
expect(result.current.shareLoading).toBe(false);
|
83
|
-
// 注意:这里的验证可能需要你根据实际的状态管理逻辑进行调整
|
84
|
-
});
|
85
|
-
|
86
|
-
it('should include plugin information when withPluginInfo is true', async () => {
|
87
|
-
// 模拟带有插件信息的消息
|
88
|
-
const pluginMessage = {
|
89
|
-
role: 'tool',
|
90
|
-
content: 'plugin content',
|
91
|
-
plugin: {
|
92
|
-
type: 'default',
|
93
|
-
arguments: '{}',
|
94
|
-
apiName: 'test-api',
|
95
|
-
identifier: 'test-identifier',
|
96
|
-
},
|
97
|
-
id: 'abc',
|
98
|
-
} as ChatMessage;
|
99
|
-
|
100
|
-
act(() => {
|
101
|
-
useChatStore.setState({
|
102
|
-
messagesMap: {
|
103
|
-
[messageMapKey('abc')]: [pluginMessage],
|
104
|
-
},
|
105
|
-
activeId: 'abc',
|
106
|
-
});
|
107
|
-
});
|
108
|
-
|
109
|
-
const { result } = renderHook(() => useChatStore());
|
110
|
-
await act(async () => {
|
111
|
-
result.current.shareToShareGPT({ withPluginInfo: true });
|
112
|
-
});
|
113
|
-
expect(shareServiceSpy).toHaveBeenCalledWith(
|
114
|
-
expect.objectContaining({
|
115
|
-
items: expect.arrayContaining([
|
116
|
-
expect.objectContaining({
|
117
|
-
from: 'gpt',
|
118
|
-
value: expect.stringContaining('Function Calling Plugin'),
|
119
|
-
}),
|
120
|
-
]),
|
121
|
-
}),
|
122
|
-
);
|
123
|
-
});
|
124
|
-
|
125
|
-
it('should not include plugin information when withPluginInfo is false', async () => {
|
126
|
-
const pluginMessage = {
|
127
|
-
role: 'tool',
|
128
|
-
content: 'plugin content',
|
129
|
-
plugin: {
|
130
|
-
type: 'default',
|
131
|
-
arguments: '{}',
|
132
|
-
apiName: 'test-api',
|
133
|
-
identifier: 'test-identifier',
|
134
|
-
},
|
135
|
-
id: 'abc',
|
136
|
-
} as ChatMessage;
|
137
|
-
|
138
|
-
act(() => {
|
139
|
-
useChatStore.setState({
|
140
|
-
messagesMap: {
|
141
|
-
[messageMapKey('abc')]: [pluginMessage],
|
142
|
-
},
|
143
|
-
activeId: 'abc',
|
144
|
-
});
|
145
|
-
});
|
146
|
-
|
147
|
-
const { result } = renderHook(() => useChatStore());
|
148
|
-
await act(async () => {
|
149
|
-
result.current.shareToShareGPT({ withPluginInfo: false });
|
150
|
-
});
|
151
|
-
expect(shareServiceSpy).toHaveBeenCalledWith(
|
152
|
-
expect.objectContaining({
|
153
|
-
items: expect.not.arrayContaining([
|
154
|
-
expect.objectContaining({
|
155
|
-
from: 'gpt',
|
156
|
-
value: expect.stringContaining('Function Calling Plugin'),
|
157
|
-
}),
|
158
|
-
]),
|
159
|
-
}),
|
160
|
-
);
|
161
|
-
});
|
162
|
-
|
163
|
-
it('should handle messages from different roles correctly', async () => {
|
164
|
-
const messages = [
|
165
|
-
{ role: 'user', content: 'user message', id: '1' },
|
166
|
-
{ role: 'assistant', content: 'assistant message', id: '2' },
|
167
|
-
{
|
168
|
-
role: 'tool',
|
169
|
-
content: 'plugin content',
|
170
|
-
plugin: {
|
171
|
-
type: 'default',
|
172
|
-
arguments: '{}',
|
173
|
-
apiName: 'test-api',
|
174
|
-
identifier: 'test-identifier',
|
175
|
-
},
|
176
|
-
id: '3',
|
177
|
-
},
|
178
|
-
] as ChatMessage[];
|
179
|
-
|
180
|
-
act(() => {
|
181
|
-
useChatStore.setState({
|
182
|
-
messagesMap: {
|
183
|
-
[messageMapKey('abc')]: messages,
|
184
|
-
},
|
185
|
-
activeId: 'abc',
|
186
|
-
});
|
187
|
-
});
|
9
|
+
afterEach(() => {
|
10
|
+
vi.restoreAllMocks();
|
11
|
+
});
|
188
12
|
|
13
|
+
describe('shareSlice actions', () => {
|
14
|
+
describe('genShareUrl', () => {
|
15
|
+
it('TODO', async () => {
|
189
16
|
const { result } = renderHook(() => useChatStore());
|
190
17
|
await act(async () => {
|
191
|
-
await result.current.
|
192
|
-
withPluginInfo: true,
|
193
|
-
withSystemRole: true,
|
194
|
-
});
|
18
|
+
await result.current.genShareUrl();
|
195
19
|
});
|
196
|
-
|
197
|
-
expect(shareServiceSpy).toHaveBeenCalledWith(
|
198
|
-
expect.objectContaining({
|
199
|
-
items: [
|
200
|
-
expect.objectContaining({ from: 'gpt' }), // Agent meta info
|
201
|
-
expect.objectContaining({ from: 'human', value: 'user message' }),
|
202
|
-
expect.objectContaining({ from: 'gpt', value: 'assistant message' }),
|
203
|
-
expect.objectContaining({
|
204
|
-
from: 'gpt',
|
205
|
-
value: expect.stringContaining('Function Calling Plugin'),
|
206
|
-
}),
|
207
|
-
expect.objectContaining({ from: 'gpt', value: expect.stringContaining('Share from') }), // Footer
|
208
|
-
],
|
209
|
-
}),
|
210
|
-
);
|
211
20
|
});
|
212
21
|
});
|
213
22
|
});
|
@@ -1,122 +1,18 @@
|
|
1
|
-
import dayjs from 'dayjs';
|
2
|
-
import { produce } from 'immer';
|
3
1
|
import { StateCreator } from 'zustand/vanilla';
|
4
2
|
|
5
|
-
import { DEFAULT_USER_AVATAR_URL } from '@/const/meta';
|
6
|
-
import { shareService } from '@/services/share';
|
7
|
-
import { useAgentStore } from '@/store/agent';
|
8
|
-
import { agentSelectors } from '@/store/agent/selectors';
|
9
|
-
import { useSessionStore } from '@/store/session';
|
10
|
-
import { sessionMetaSelectors } from '@/store/session/selectors';
|
11
|
-
import { ShareGPTConversation } from '@/types/share';
|
12
|
-
|
13
|
-
import { chatSelectors } from '../../selectors';
|
14
3
|
import { ChatStore } from '../../store';
|
15
4
|
|
16
|
-
interface ShareMessage {
|
17
|
-
from: 'human' | 'gpt';
|
18
|
-
value: string;
|
19
|
-
}
|
20
|
-
|
21
|
-
const Footer: ShareMessage = {
|
22
|
-
from: 'gpt',
|
23
|
-
value: `Share from [**🤯 LobeChat**](https://github.com/lobehub/lobe-chat) - ${dayjs().format(
|
24
|
-
'YYYY-MM-DD',
|
25
|
-
)}`,
|
26
|
-
};
|
27
|
-
|
28
|
-
const PLUGIN_INFO = (plugin: {
|
29
|
-
apiName: string;
|
30
|
-
content: string;
|
31
|
-
identifier: string;
|
32
|
-
}): ShareMessage => ({
|
33
|
-
from: 'gpt',
|
34
|
-
value: [
|
35
|
-
`**🧩 Function Calling Plugin**`,
|
36
|
-
`- Identifier: \`${plugin.identifier}\``,
|
37
|
-
`- API name: \`${plugin.apiName}\``,
|
38
|
-
`- Result:`,
|
39
|
-
``,
|
40
|
-
'```json',
|
41
|
-
plugin.content,
|
42
|
-
'```',
|
43
|
-
].join('\n'),
|
44
|
-
});
|
45
|
-
|
46
|
-
// const t = setNamespace('chat/share');
|
47
5
|
export interface ShareAction {
|
48
|
-
|
49
|
-
avatar?: string;
|
50
|
-
withPluginInfo?: boolean;
|
51
|
-
withSystemRole?: boolean;
|
52
|
-
}) => Promise<void>;
|
6
|
+
genShareUrl: () => Promise<string>;
|
53
7
|
}
|
54
8
|
|
55
|
-
export const chatShare: StateCreator<
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
const defaultMsg: ShareGPTConversation['items'] = [];
|
65
|
-
const showSystemRole = withSystemRole && !!config.systemRole;
|
66
|
-
const shareMsgs = produce(defaultMsg, (draft) => {
|
67
|
-
draft.push({
|
68
|
-
from: 'gpt',
|
69
|
-
value: [
|
70
|
-
`${meta.avatar} **${meta.title}** - ${meta.description}`,
|
71
|
-
showSystemRole && '---',
|
72
|
-
showSystemRole && config.systemRole,
|
73
|
-
]
|
74
|
-
.filter(Boolean)
|
75
|
-
.join('\n\n'),
|
76
|
-
});
|
77
|
-
|
78
|
-
for (const i of messages) {
|
79
|
-
switch (i.role) {
|
80
|
-
case 'assistant': {
|
81
|
-
draft.push({ from: 'gpt', value: i.content });
|
82
|
-
break;
|
83
|
-
}
|
84
|
-
case 'tool': {
|
85
|
-
if (withPluginInfo)
|
86
|
-
draft.push(
|
87
|
-
PLUGIN_INFO({
|
88
|
-
apiName: i.plugin?.apiName || 'undefined',
|
89
|
-
content: i.content,
|
90
|
-
identifier: i.plugin?.identifier || 'undefined',
|
91
|
-
}),
|
92
|
-
);
|
93
|
-
break;
|
94
|
-
}
|
95
|
-
case 'user': {
|
96
|
-
draft.push({ from: 'human', value: i.content });
|
97
|
-
break;
|
98
|
-
}
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
draft.push(Footer);
|
103
|
-
});
|
104
|
-
|
105
|
-
set({ shareLoading: true });
|
106
|
-
|
107
|
-
const res = await shareService.createShareGPTUrl({
|
108
|
-
avatarUrl: avatar || DEFAULT_USER_AVATAR_URL,
|
109
|
-
items: shareMsgs,
|
110
|
-
});
|
111
|
-
set({ shareLoading: false });
|
112
|
-
|
113
|
-
window.open(res, '_blank');
|
9
|
+
export const chatShare: StateCreator<
|
10
|
+
ChatStore,
|
11
|
+
[['zustand/devtools', never]],
|
12
|
+
[],
|
13
|
+
ShareAction
|
14
|
+
> = () => ({
|
15
|
+
genShareUrl: () => {
|
16
|
+
return Promise.resolve('TODO');
|
114
17
|
},
|
115
|
-
// genShareUrl: () => {
|
116
|
-
// const session = sessionSelectors.currentSession(get());
|
117
|
-
// if (!session) return '';
|
118
|
-
//
|
119
|
-
// const agent = session.config;
|
120
|
-
// return genShareMessagesUrl(session.chats, agent.systemRole);
|
121
|
-
// },
|
122
18
|
});
|
@@ -0,0 +1,20 @@
|
|
1
|
+
export const exportFile = (content: string, filename?: string) => {
|
2
|
+
// 创建一个 Blob 对象
|
3
|
+
const blob = new Blob([content], { type: 'plain/text' });
|
4
|
+
|
5
|
+
// 创建一个 URL 对象,用于下载
|
6
|
+
const url = URL.createObjectURL(blob);
|
7
|
+
|
8
|
+
// 创建一个 <a> 元素,设置下载链接和文件名
|
9
|
+
const a = document.createElement('a');
|
10
|
+
a.href = url;
|
11
|
+
a.download = filename || 'file.txt';
|
12
|
+
|
13
|
+
// 触发 <a> 元素的点击事件,开始下载
|
14
|
+
document.body.append(a);
|
15
|
+
a.click();
|
16
|
+
|
17
|
+
// 下载完成后,清除 URL 对象
|
18
|
+
URL.revokeObjectURL(url);
|
19
|
+
a.remove();
|
20
|
+
};
|
@@ -1,164 +0,0 @@
|
|
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 { FORM_STYLE } from '@/const/layoutTokens';
|
8
|
-
import { useChatStore } from '@/store/chat';
|
9
|
-
import { useUserStore } from '@/store/user';
|
10
|
-
import { userProfileSelectors } from '@/store/user/selectors';
|
11
|
-
|
12
|
-
import Preview from './Preview';
|
13
|
-
import { FieldType, ImageType } from './type';
|
14
|
-
import { useScreenshot } from './useScreenshot';
|
15
|
-
|
16
|
-
enum Tab {
|
17
|
-
Screenshot = 'screenshot',
|
18
|
-
ShareGPT = 'sharegpt',
|
19
|
-
}
|
20
|
-
|
21
|
-
export const imageTypeOptions: SegmentedProps['options'] = [
|
22
|
-
{
|
23
|
-
label: 'JPG',
|
24
|
-
value: ImageType.JPG,
|
25
|
-
},
|
26
|
-
{
|
27
|
-
label: 'PNG',
|
28
|
-
value: ImageType.PNG,
|
29
|
-
},
|
30
|
-
{
|
31
|
-
label: 'SVG',
|
32
|
-
value: ImageType.SVG,
|
33
|
-
},
|
34
|
-
{
|
35
|
-
label: 'WEBP',
|
36
|
-
value: ImageType.WEBP,
|
37
|
-
},
|
38
|
-
];
|
39
|
-
|
40
|
-
const DEFAULT_FIELD_VALUE: FieldType = {
|
41
|
-
imageType: ImageType.JPG,
|
42
|
-
withBackground: true,
|
43
|
-
withFooter: false,
|
44
|
-
withPluginInfo: false,
|
45
|
-
withSystemRole: false,
|
46
|
-
};
|
47
|
-
|
48
|
-
const ShareModal = memo<ModalProps>(({ onCancel, open }) => {
|
49
|
-
const [fieldValue, setFieldValue] = useState<FieldType>(DEFAULT_FIELD_VALUE);
|
50
|
-
const [tab, setTab] = useState<Tab>(Tab.Screenshot);
|
51
|
-
const { t } = useTranslation('chat');
|
52
|
-
const avatar = useUserStore(userProfileSelectors.userAvatar);
|
53
|
-
const [shareLoading, shareToShareGPT] = useChatStore((s) => [s.shareLoading, s.shareToShareGPT]);
|
54
|
-
const { loading, onDownload, title } = useScreenshot(fieldValue.imageType);
|
55
|
-
|
56
|
-
const options: SegmentedProps['options'] = useMemo(
|
57
|
-
() => [
|
58
|
-
{
|
59
|
-
label: t('shareModal.screenshot'),
|
60
|
-
value: Tab.Screenshot,
|
61
|
-
},
|
62
|
-
{
|
63
|
-
label: 'ShareGPT',
|
64
|
-
value: Tab.ShareGPT,
|
65
|
-
},
|
66
|
-
],
|
67
|
-
[],
|
68
|
-
);
|
69
|
-
|
70
|
-
const settings: FormItemProps[] = useMemo(
|
71
|
-
() => [
|
72
|
-
{
|
73
|
-
children: <Switch />,
|
74
|
-
label: t('shareModal.withSystemRole'),
|
75
|
-
minWidth: undefined,
|
76
|
-
name: 'withSystemRole',
|
77
|
-
valuePropName: 'checked',
|
78
|
-
},
|
79
|
-
{
|
80
|
-
children: <Switch />,
|
81
|
-
hidden: tab !== Tab.Screenshot,
|
82
|
-
label: t('shareModal.withBackground'),
|
83
|
-
minWidth: undefined,
|
84
|
-
name: 'withBackground',
|
85
|
-
valuePropName: 'checked',
|
86
|
-
},
|
87
|
-
{
|
88
|
-
children: <Switch />,
|
89
|
-
hidden: tab !== Tab.Screenshot,
|
90
|
-
label: t('shareModal.withFooter'),
|
91
|
-
minWidth: undefined,
|
92
|
-
name: 'withFooter',
|
93
|
-
valuePropName: 'checked',
|
94
|
-
},
|
95
|
-
{
|
96
|
-
children: <Segmented options={imageTypeOptions} />,
|
97
|
-
hidden: tab !== Tab.Screenshot,
|
98
|
-
label: t('shareModal.imageType'),
|
99
|
-
minWidth: undefined,
|
100
|
-
name: 'imageType',
|
101
|
-
},
|
102
|
-
{
|
103
|
-
children: <Switch />,
|
104
|
-
hidden: tab !== Tab.ShareGPT,
|
105
|
-
label: t('shareModal.withPluginInfo'),
|
106
|
-
minWidth: undefined,
|
107
|
-
name: 'withPluginInfo',
|
108
|
-
valuePropName: 'checked',
|
109
|
-
},
|
110
|
-
],
|
111
|
-
[tab],
|
112
|
-
);
|
113
|
-
|
114
|
-
return (
|
115
|
-
<Modal
|
116
|
-
allowFullscreen
|
117
|
-
centered={false}
|
118
|
-
footer={
|
119
|
-
<>
|
120
|
-
{tab === Tab.Screenshot && (
|
121
|
-
<Button block loading={loading} onClick={onDownload} size={'large'} type={'primary'}>
|
122
|
-
{t('shareModal.download')}
|
123
|
-
</Button>
|
124
|
-
)}
|
125
|
-
{tab === Tab.ShareGPT && (
|
126
|
-
<Button
|
127
|
-
block
|
128
|
-
loading={shareLoading}
|
129
|
-
onClick={() => shareToShareGPT({ avatar, ...fieldValue })}
|
130
|
-
size={'large'}
|
131
|
-
type={'primary'}
|
132
|
-
>
|
133
|
-
{t('shareModal.shareToShareGPT')}
|
134
|
-
</Button>
|
135
|
-
)}
|
136
|
-
</>
|
137
|
-
}
|
138
|
-
maxHeight={false}
|
139
|
-
onCancel={onCancel}
|
140
|
-
open={open}
|
141
|
-
title={t('share', { ns: 'common' })}
|
142
|
-
>
|
143
|
-
<Flexbox gap={16}>
|
144
|
-
<Segmented
|
145
|
-
block
|
146
|
-
onChange={(value) => setTab(value as Tab)}
|
147
|
-
options={options}
|
148
|
-
style={{ width: '100%' }}
|
149
|
-
value={tab}
|
150
|
-
/>
|
151
|
-
{tab === Tab.Screenshot && <Preview title={title} {...fieldValue} />}
|
152
|
-
<Form
|
153
|
-
initialValues={DEFAULT_FIELD_VALUE}
|
154
|
-
items={settings}
|
155
|
-
itemsType={'flat'}
|
156
|
-
onValuesChange={(_, v) => setFieldValue(v)}
|
157
|
-
{...FORM_STYLE}
|
158
|
-
/>
|
159
|
-
</Flexbox>
|
160
|
-
</Modal>
|
161
|
-
);
|
162
|
-
});
|
163
|
-
|
164
|
-
export default ShareModal;
|
File without changes
|
File without changes
|