@lobehub/lobehub 2.0.0-next.217 → 2.0.0-next.219
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 +58 -0
- package/changelog/v1.json +21 -0
- package/package.json +2 -2
- package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +18 -31
- package/packages/builtin-tool-cloud-sandbox/src/types.ts +3 -3
- package/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/List/Item/Actions.tsx +1 -1
- package/src/app/[variants]/(main)/chat/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/Actions.tsx +1 -1
- package/src/app/[variants]/(main)/chat/profile/features/EditorCanvas/TypoBar.tsx +1 -11
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/List/Item/Actions.tsx +1 -1
- package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/TopicListContent/ThreadList/ThreadItem/Actions.tsx +1 -1
- package/src/app/[variants]/(main)/group/profile/features/EditorCanvas/TypoBar.tsx +1 -11
- package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/Item/Actions.tsx +1 -1
- package/src/app/[variants]/(main)/home/_layout/Body/Project/List/Actions.tsx +1 -1
- package/src/app/[variants]/(main)/home/_layout/Footer/index.tsx +3 -9
- package/src/app/[variants]/(main)/home/_layout/Header/components/AddButton.tsx +1 -1
- package/src/app/[variants]/(main)/memory/features/EditableModal/index.tsx +8 -101
- package/src/app/[variants]/(main)/page/_layout/Body/List/Item/Actions.tsx +1 -1
- package/src/app/[variants]/(main)/resource/(home)/_layout/Body/LibraryList/List/Item/Actions.tsx +1 -1
- package/src/features/ChatInput/InputEditor/index.tsx +1 -0
- package/src/features/ChatInput/TypoBar/index.tsx +0 -11
- package/src/features/Conversation/ChatItem/components/MessageContent/index.tsx +11 -12
- package/src/features/EditorModal/EditorCanvas.tsx +81 -0
- package/src/features/EditorModal/TextareCanvas.tsx +28 -0
- package/src/{app/[variants]/(main)/memory/features/EditableModal → features/EditorModal}/Typobar.tsx +0 -11
- package/src/features/EditorModal/index.tsx +51 -0
- package/src/features/PageEditor/Copilot/TopicSelector/Actions.tsx +1 -1
- package/src/features/PageEditor/EditorCanvas/InlineToolbar.tsx +1 -17
- package/src/features/ResourceManager/components/Explorer/ItemDropdown/DropdownMenu.tsx +1 -1
- package/src/features/User/UserPanel/ThemeButton.tsx +1 -1
- package/src/server/routers/tools/market.ts +118 -102
- package/src/server/services/discover/index.ts +10 -5
- package/src/services/codeInterpreter.ts +12 -20
- package/src/store/chat/slices/plugin/actions/pluginTypes.ts +13 -86
- package/src/features/Conversation/ChatItem/components/MessageContent/EditableModal.tsx +0 -119
- package/src/features/Conversation/ChatItem/components/MessageContent/Typobar.tsx +0 -150
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,64 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.219](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.218...v2.0.0-next.219)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-05**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Resolve BaseUI dropdown compatibility issue.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Resolve BaseUI dropdown compatibility issue, closes [#11248](https://github.com/lobehub/lobe-chat/issues/11248) ([065bfec](https://github.com/lobehub/lobe-chat/commit/065bfec))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.218](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.217...v2.0.0-next.218)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2026-01-05**</sup>
|
|
33
|
+
|
|
34
|
+
#### ✨ Features
|
|
35
|
+
|
|
36
|
+
- **misc**: Update the sandbox export files & save files way.
|
|
37
|
+
|
|
38
|
+
#### 🐛 Bug Fixes
|
|
39
|
+
|
|
40
|
+
- **misc**: Fix editor modal when Markdown rendering off.
|
|
41
|
+
|
|
42
|
+
<br/>
|
|
43
|
+
|
|
44
|
+
<details>
|
|
45
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
46
|
+
|
|
47
|
+
#### What's improved
|
|
48
|
+
|
|
49
|
+
- **misc**: Update the sandbox export files & save files way, closes [#11249](https://github.com/lobehub/lobe-chat/issues/11249) ([039b0a1](https://github.com/lobehub/lobe-chat/commit/039b0a1))
|
|
50
|
+
|
|
51
|
+
#### What's fixed
|
|
52
|
+
|
|
53
|
+
- **misc**: Fix editor modal when Markdown rendering off, closes [#11251](https://github.com/lobehub/lobe-chat/issues/11251) ([eb86d3b](https://github.com/lobehub/lobe-chat/commit/eb86d3b))
|
|
54
|
+
|
|
55
|
+
</details>
|
|
56
|
+
|
|
57
|
+
<div align="right">
|
|
58
|
+
|
|
59
|
+
[](#readme-top)
|
|
60
|
+
|
|
61
|
+
</div>
|
|
62
|
+
|
|
5
63
|
## [Version 2.0.0-next.217](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.216...v2.0.0-next.217)
|
|
6
64
|
|
|
7
65
|
<sup>Released on **2026-01-05**</sup>
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,25 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"children": {
|
|
4
|
+
"fixes": [
|
|
5
|
+
"Resolve BaseUI dropdown compatibility issue."
|
|
6
|
+
]
|
|
7
|
+
},
|
|
8
|
+
"date": "2026-01-05",
|
|
9
|
+
"version": "2.0.0-next.219"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"children": {
|
|
13
|
+
"features": [
|
|
14
|
+
"Update the sandbox export files & save files way."
|
|
15
|
+
],
|
|
16
|
+
"fixes": [
|
|
17
|
+
"Fix editor modal when Markdown rendering off."
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
"date": "2026-01-05",
|
|
21
|
+
"version": "2.0.0-next.218"
|
|
22
|
+
},
|
|
2
23
|
{
|
|
3
24
|
"children": {},
|
|
4
25
|
"date": "2026-01-05",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.219",
|
|
4
4
|
"description": "LobeHub - an open-source,comprehensive AI Agent 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",
|
|
@@ -205,7 +205,7 @@
|
|
|
205
205
|
"@lobehub/icons": "^4.0.2",
|
|
206
206
|
"@lobehub/market-sdk": "^0.25.1",
|
|
207
207
|
"@lobehub/tts": "^4.0.2",
|
|
208
|
-
"@lobehub/ui": "^4.9.
|
|
208
|
+
"@lobehub/ui": "^4.9.3",
|
|
209
209
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
210
210
|
"@neondatabase/serverless": "^1.0.2",
|
|
211
211
|
"@next/third-parties": "^16.1.1",
|
|
@@ -425,51 +425,38 @@ export class CloudSandboxExecutionRuntime {
|
|
|
425
425
|
|
|
426
426
|
/**
|
|
427
427
|
* Export a file from the sandbox to cloud storage
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
428
|
+
* Uses a single tRPC call that handles:
|
|
429
|
+
* 1. Generate pre-signed upload URL
|
|
430
|
+
* 2. Call sandbox to upload file
|
|
431
|
+
* 3. Create persistent file record
|
|
432
|
+
* 4. Return permanent /f/:id URL
|
|
431
433
|
*/
|
|
432
434
|
async exportFile(args: ExportFileParams): Promise<BuiltinServerRuntimeOutput> {
|
|
433
435
|
try {
|
|
434
436
|
// Extract filename from path
|
|
435
437
|
const filename = args.path.split('/').pop() || 'exported_file';
|
|
436
438
|
|
|
437
|
-
//
|
|
438
|
-
const
|
|
439
|
+
// Single call that handles everything: upload URL generation, sandbox upload, and file record creation
|
|
440
|
+
const result = await codeInterpreterService.exportAndUploadFile(
|
|
441
|
+
args.path,
|
|
439
442
|
filename,
|
|
440
443
|
this.context.topicId,
|
|
441
444
|
);
|
|
442
445
|
|
|
443
|
-
if (!uploadUrlResult.success) {
|
|
444
|
-
throw new Error(uploadUrlResult.error?.message || 'Failed to get upload URL');
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// Step 2: Call the sandbox's exportFile tool with the upload URL
|
|
448
|
-
// The sandbox will read the file and upload it to the pre-signed URL
|
|
449
|
-
const result = await this.callTool('exportFile', {
|
|
450
|
-
path: args.path,
|
|
451
|
-
uploadUrl: uploadUrlResult.uploadUrl,
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
// Check if the sandbox upload was successful
|
|
455
|
-
const uploadSuccess = result.success && result.result?.success !== false;
|
|
456
|
-
const fileSize = result.result?.size;
|
|
457
|
-
const mimeType = result.result?.mimeType;
|
|
458
|
-
const fileContent = result.result?.content;
|
|
459
|
-
|
|
460
446
|
const state: ExportFileState = {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
filename,
|
|
464
|
-
mimeType,
|
|
447
|
+
downloadUrl: result.success && result.url ? result.url : '',
|
|
448
|
+
fileId: result.fileId,
|
|
449
|
+
filename: result.filename,
|
|
450
|
+
mimeType: result.mimeType,
|
|
465
451
|
path: args.path,
|
|
466
|
-
size:
|
|
467
|
-
success:
|
|
452
|
+
size: result.size,
|
|
453
|
+
success: result.success,
|
|
468
454
|
};
|
|
469
|
-
|
|
455
|
+
|
|
456
|
+
if (!result.success) {
|
|
470
457
|
return {
|
|
471
458
|
content: JSON.stringify({
|
|
472
|
-
error: result.
|
|
459
|
+
error: result.error?.message || 'Failed to export file from sandbox',
|
|
473
460
|
filename,
|
|
474
461
|
success: false,
|
|
475
462
|
}),
|
|
@@ -479,7 +466,7 @@ export class CloudSandboxExecutionRuntime {
|
|
|
479
466
|
}
|
|
480
467
|
|
|
481
468
|
return {
|
|
482
|
-
content: `File exported successfully.\n\nFilename: ${filename}\nDownload URL: ${
|
|
469
|
+
content: `File exported successfully.\n\nFilename: ${filename}\nDownload URL: ${result.url}`,
|
|
483
470
|
state,
|
|
484
471
|
success: true,
|
|
485
472
|
};
|
|
@@ -90,10 +90,10 @@ export interface GlobFilesState {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
export interface ExportFileState {
|
|
93
|
-
/**
|
|
94
|
-
content?: string;
|
|
95
|
-
/** The download URL for the exported file */
|
|
93
|
+
/** The download URL for the exported file (permanent /f/:id URL) */
|
|
96
94
|
downloadUrl: string;
|
|
95
|
+
/** The file ID in database (returned from server) */
|
|
96
|
+
fileId?: string;
|
|
97
97
|
/** The exported file name */
|
|
98
98
|
filename: string;
|
|
99
99
|
/** The MIME type of the file */
|
|
@@ -8,7 +8,7 @@ interface ActionProps {
|
|
|
8
8
|
|
|
9
9
|
const Actions = memo<ActionProps>(({ dropdownMenu }) => {
|
|
10
10
|
return (
|
|
11
|
-
<DropdownMenu items={dropdownMenu}>
|
|
11
|
+
<DropdownMenu items={dropdownMenu} nativeButton={false}>
|
|
12
12
|
<ActionIcon icon={MoreHorizontalIcon} size={'small'} />
|
|
13
13
|
</DropdownMenu>
|
|
14
14
|
);
|
|
@@ -8,7 +8,7 @@ interface ActionProps {
|
|
|
8
8
|
|
|
9
9
|
const Actions = memo<ActionProps>(({ dropdownMenu }) => {
|
|
10
10
|
return (
|
|
11
|
-
<DropdownMenu items={dropdownMenu}>
|
|
11
|
+
<DropdownMenu items={dropdownMenu} nativeButton={false}>
|
|
12
12
|
<ActionIcon icon={MoreHorizontalIcon} size={'small'} />
|
|
13
13
|
</DropdownMenu>
|
|
14
14
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HotkeyEnum, getHotkeyById } from '@lobehub/editor';
|
|
2
2
|
import { FloatActions } from '@lobehub/editor/react';
|
|
3
|
-
import { type ChatInputActionsProps
|
|
3
|
+
import { type ChatInputActionsProps } from '@lobehub/editor/react';
|
|
4
4
|
import {
|
|
5
5
|
BoldIcon,
|
|
6
6
|
CodeXmlIcon,
|
|
@@ -116,16 +116,6 @@ const TypoBar = memo(() => {
|
|
|
116
116
|
label: t('typobar.codeblock'),
|
|
117
117
|
onClick: editorState.codeblock,
|
|
118
118
|
},
|
|
119
|
-
editorState.isCodeblock && {
|
|
120
|
-
children: (
|
|
121
|
-
<CodeLanguageSelect
|
|
122
|
-
onSelect={(value) => editorState.updateCodeblockLang(value)}
|
|
123
|
-
value={editorState.codeblockLang}
|
|
124
|
-
/>
|
|
125
|
-
),
|
|
126
|
-
disabled: !editorState.isCodeblock,
|
|
127
|
-
key: 'codeblockLang',
|
|
128
|
-
},
|
|
129
119
|
].filter(Boolean) as ChatInputActionsProps['items'];
|
|
130
120
|
}, [editorState, t]);
|
|
131
121
|
|
|
@@ -8,7 +8,7 @@ interface ActionProps {
|
|
|
8
8
|
|
|
9
9
|
const Actions = memo<ActionProps>(({ dropdownMenu }) => {
|
|
10
10
|
return (
|
|
11
|
-
<DropdownMenu items={dropdownMenu}>
|
|
11
|
+
<DropdownMenu items={dropdownMenu} nativeButton={false}>
|
|
12
12
|
<ActionIcon icon={MoreHorizontalIcon} size={'small'} />
|
|
13
13
|
</DropdownMenu>
|
|
14
14
|
);
|
|
@@ -8,7 +8,7 @@ interface ActionProps {
|
|
|
8
8
|
|
|
9
9
|
const Actions = memo<ActionProps>(({ dropdownMenu }) => {
|
|
10
10
|
return (
|
|
11
|
-
<DropdownMenu items={dropdownMenu}>
|
|
11
|
+
<DropdownMenu items={dropdownMenu} nativeButton={false}>
|
|
12
12
|
<ActionIcon icon={MoreHorizontalIcon} size={'small'} />
|
|
13
13
|
</DropdownMenu>
|
|
14
14
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HotkeyEnum, getHotkeyById } from '@lobehub/editor';
|
|
2
2
|
import { FloatActions } from '@lobehub/editor/react';
|
|
3
|
-
import { type ChatInputActionsProps
|
|
3
|
+
import { type ChatInputActionsProps } from '@lobehub/editor/react';
|
|
4
4
|
import {
|
|
5
5
|
BoldIcon,
|
|
6
6
|
CodeXmlIcon,
|
|
@@ -116,16 +116,6 @@ const TypoBar = memo(() => {
|
|
|
116
116
|
label: t('typobar.codeblock'),
|
|
117
117
|
onClick: editorState.codeblock,
|
|
118
118
|
},
|
|
119
|
-
editorState.isCodeblock && {
|
|
120
|
-
children: (
|
|
121
|
-
<CodeLanguageSelect
|
|
122
|
-
onSelect={(value) => editorState.updateCodeblockLang(value)}
|
|
123
|
-
value={editorState.codeblockLang}
|
|
124
|
-
/>
|
|
125
|
-
),
|
|
126
|
-
disabled: !editorState.isCodeblock,
|
|
127
|
-
key: 'codeblockLang',
|
|
128
|
-
},
|
|
129
119
|
].filter(Boolean) as ChatInputActionsProps['items'];
|
|
130
120
|
}, [editorState, t]);
|
|
131
121
|
|
|
@@ -8,7 +8,7 @@ interface ActionProps {
|
|
|
8
8
|
|
|
9
9
|
const Actions = memo<ActionProps>(({ dropdownMenu }) => {
|
|
10
10
|
return (
|
|
11
|
-
<DropdownMenu items={dropdownMenu}>
|
|
11
|
+
<DropdownMenu items={dropdownMenu} nativeButton={false}>
|
|
12
12
|
<ActionIcon icon={MoreHorizontalIcon} size={'small'} />
|
|
13
13
|
</DropdownMenu>
|
|
14
14
|
);
|
|
@@ -8,7 +8,7 @@ interface ActionsProps {
|
|
|
8
8
|
|
|
9
9
|
const Actions = memo<ActionsProps>(({ dropdownMenu }) => {
|
|
10
10
|
return (
|
|
11
|
-
<DropdownMenu items={dropdownMenu}>
|
|
11
|
+
<DropdownMenu items={dropdownMenu} nativeButton={false}>
|
|
12
12
|
<ActionIcon icon={MoreHorizontalIcon} size={'small'} />
|
|
13
13
|
</DropdownMenu>
|
|
14
14
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { BRANDING_EMAIL, SOCIAL_URL } from '@lobechat/business-const';
|
|
4
|
-
import { ActionIcon,
|
|
4
|
+
import { ActionIcon, DropdownMenu, Icon, type MenuProps } from '@lobehub/ui';
|
|
5
5
|
import { Flexbox } from '@lobehub/ui';
|
|
6
6
|
import { DiscordIcon } from '@lobehub/ui/icons';
|
|
7
7
|
import { Book, CircleHelp, Feather, FileClockIcon, FlaskConical, Github, Mail } from 'lucide-react';
|
|
@@ -103,15 +103,9 @@ const Footer = memo(() => {
|
|
|
103
103
|
<>
|
|
104
104
|
<Flexbox align={'center'} gap={2} horizontal justify={'space-between'} padding={8}>
|
|
105
105
|
<Flexbox align={'center'} flex={1} gap={2} horizontal>
|
|
106
|
-
<
|
|
107
|
-
menu={{
|
|
108
|
-
items: helpMenuItems,
|
|
109
|
-
}}
|
|
110
|
-
placement="topLeft"
|
|
111
|
-
trigger={['click']}
|
|
112
|
-
>
|
|
106
|
+
<DropdownMenu items={helpMenuItems} nativeButton={false} placement="topLeft">
|
|
113
107
|
<ActionIcon aria-label={t('userPanel.help')} icon={CircleHelp} size={16} />
|
|
114
|
-
</
|
|
108
|
+
</DropdownMenu>
|
|
115
109
|
{!hideGitHub && (
|
|
116
110
|
<a aria-label={'GitHub'} href={GITHUB} rel="noopener noreferrer" target={'_blank'}>
|
|
117
111
|
<ActionIcon icon={Github} size={16} title={'GitHub'} />
|
|
@@ -44,7 +44,7 @@ const AddButton = memo(() => {
|
|
|
44
44
|
size={DESKTOP_HEADER_ICON_SIZE}
|
|
45
45
|
title={tChat('newAgent')}
|
|
46
46
|
/>
|
|
47
|
-
<DropdownMenu items={dropdownItems}>
|
|
47
|
+
<DropdownMenu items={dropdownItems} nativeButton={false}>
|
|
48
48
|
<ActionIcon
|
|
49
49
|
color={cssVar.colorTextQuaternary}
|
|
50
50
|
icon={ChevronDownIcon}
|
|
@@ -1,66 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ReactCodePlugin,
|
|
3
|
-
ReactCodemirrorPlugin,
|
|
4
|
-
ReactHRPlugin,
|
|
5
|
-
ReactLinkHighlightPlugin,
|
|
6
|
-
ReactListPlugin,
|
|
7
|
-
ReactMathPlugin,
|
|
8
|
-
ReactTablePlugin,
|
|
9
|
-
} from '@lobehub/editor';
|
|
10
|
-
import { Editor, useEditor } from '@lobehub/editor/react';
|
|
11
|
-
import { Flexbox, Modal } from '@lobehub/ui';
|
|
12
|
-
import { memo, useMemo, useState } from 'react';
|
|
13
|
-
import { useTranslation } from 'react-i18next';
|
|
1
|
+
import { memo } from 'react';
|
|
14
2
|
|
|
15
|
-
import {
|
|
16
|
-
import { labPreferSelectors } from '@/store/user/slices/preference/selectors';
|
|
3
|
+
import { EditorModal } from '@/features/EditorModal';
|
|
17
4
|
import { useUserMemoryStore } from '@/store/userMemory';
|
|
18
5
|
import { LayersEnum } from '@/types/userMemory';
|
|
19
6
|
|
|
20
|
-
import TypoBar from './Typobar';
|
|
21
|
-
|
|
22
7
|
const EditableModal = memo(() => {
|
|
23
|
-
const { t } = useTranslation('common');
|
|
24
|
-
const editor = useEditor();
|
|
25
|
-
const [confirmLoading, setConfirmLoading] = useState(false);
|
|
26
8
|
const editingMemoryId = useUserMemoryStore((s) => s.editingMemoryId);
|
|
27
9
|
const editingMemoryContent = useUserMemoryStore((s) => s.editingMemoryContent);
|
|
28
10
|
const editingMemoryLayer = useUserMemoryStore((s) => s.editingMemoryLayer);
|
|
29
11
|
const clearEditingMemory = useUserMemoryStore((s) => s.clearEditingMemory);
|
|
30
12
|
const updateMemory = useUserMemoryStore((s) => s.updateMemory);
|
|
31
13
|
|
|
32
|
-
const enableRichRender = useUserStore(labPreferSelectors.enableInputMarkdown);
|
|
33
|
-
|
|
34
|
-
const richRenderProps = useMemo(
|
|
35
|
-
() =>
|
|
36
|
-
!enableRichRender
|
|
37
|
-
? {
|
|
38
|
-
enablePasteMarkdown: false,
|
|
39
|
-
markdownOption: {
|
|
40
|
-
bold: false,
|
|
41
|
-
code: false,
|
|
42
|
-
header: false,
|
|
43
|
-
italic: false,
|
|
44
|
-
quote: false,
|
|
45
|
-
strikethrough: false,
|
|
46
|
-
underline: false,
|
|
47
|
-
underlineStrikethrough: false,
|
|
48
|
-
},
|
|
49
|
-
}
|
|
50
|
-
: {
|
|
51
|
-
plugins: [
|
|
52
|
-
ReactListPlugin,
|
|
53
|
-
ReactCodePlugin,
|
|
54
|
-
ReactCodemirrorPlugin,
|
|
55
|
-
ReactHRPlugin,
|
|
56
|
-
ReactLinkHighlightPlugin,
|
|
57
|
-
ReactTablePlugin,
|
|
58
|
-
ReactMathPlugin,
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
[enableRichRender],
|
|
62
|
-
);
|
|
63
|
-
|
|
64
14
|
const layerMap = {
|
|
65
15
|
context: LayersEnum.Context,
|
|
66
16
|
experience: LayersEnum.Experience,
|
|
@@ -69,58 +19,15 @@ const EditableModal = memo(() => {
|
|
|
69
19
|
};
|
|
70
20
|
|
|
71
21
|
return (
|
|
72
|
-
<
|
|
73
|
-
cancelText={t('cancel')}
|
|
74
|
-
closable={false}
|
|
75
|
-
confirmLoading={confirmLoading}
|
|
76
|
-
destroyOnHidden
|
|
77
|
-
okText={t('ok')}
|
|
22
|
+
<EditorModal
|
|
78
23
|
onCancel={clearEditingMemory}
|
|
79
|
-
|
|
80
|
-
if (!
|
|
81
|
-
|
|
82
|
-
const newValue = editor.getDocument('markdown') as unknown as string;
|
|
83
|
-
await updateMemory(editingMemoryId, newValue, layerMap[editingMemoryLayer]);
|
|
84
|
-
setConfirmLoading(false);
|
|
24
|
+
onConfirm={async (value) => {
|
|
25
|
+
if (!editingMemoryId || !editingMemoryLayer) return;
|
|
26
|
+
await updateMemory(editingMemoryId, value, layerMap[editingMemoryLayer]);
|
|
85
27
|
}}
|
|
86
28
|
open={!!editingMemoryId}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
overflow: 'hidden',
|
|
90
|
-
padding: 0,
|
|
91
|
-
},
|
|
92
|
-
}}
|
|
93
|
-
title={null}
|
|
94
|
-
width={'min(90vw, 960px)'}
|
|
95
|
-
>
|
|
96
|
-
<TypoBar editor={editor} />
|
|
97
|
-
<Flexbox
|
|
98
|
-
onClick={() => {
|
|
99
|
-
editor.focus();
|
|
100
|
-
}}
|
|
101
|
-
paddingBlock={16}
|
|
102
|
-
paddingInline={48}
|
|
103
|
-
style={{ cursor: 'text', maxHeight: '80vh', minHeight: '50vh', overflowY: 'auto' }}
|
|
104
|
-
>
|
|
105
|
-
<Editor
|
|
106
|
-
autoFocus
|
|
107
|
-
content={''}
|
|
108
|
-
editor={editor}
|
|
109
|
-
onInit={(editor) => {
|
|
110
|
-
if (!editor) return;
|
|
111
|
-
try {
|
|
112
|
-
editor?.setDocument('markdown', editingMemoryContent);
|
|
113
|
-
} catch {}
|
|
114
|
-
}}
|
|
115
|
-
style={{
|
|
116
|
-
paddingBottom: 120,
|
|
117
|
-
}}
|
|
118
|
-
type={'text'}
|
|
119
|
-
variant={'chat'}
|
|
120
|
-
{...richRenderProps}
|
|
121
|
-
/>
|
|
122
|
-
</Flexbox>
|
|
123
|
-
</Modal>
|
|
29
|
+
value={editingMemoryContent}
|
|
30
|
+
/>
|
|
124
31
|
);
|
|
125
32
|
});
|
|
126
33
|
|
|
@@ -8,7 +8,7 @@ interface ActionProps {
|
|
|
8
8
|
|
|
9
9
|
const Actions = memo<ActionProps>(({ dropdownMenu }) => {
|
|
10
10
|
return (
|
|
11
|
-
<DropdownMenu items={dropdownMenu}>
|
|
11
|
+
<DropdownMenu items={dropdownMenu} nativeButton={false}>
|
|
12
12
|
<ActionIcon icon={MoreHorizontalIcon} size={'small'} />
|
|
13
13
|
</DropdownMenu>
|
|
14
14
|
);
|
package/src/app/[variants]/(main)/resource/(home)/_layout/Body/LibraryList/List/Item/Actions.tsx
CHANGED
|
@@ -8,7 +8,7 @@ interface ActionProps {
|
|
|
8
8
|
|
|
9
9
|
const Actions = memo<ActionProps>(({ dropdownMenu }) => {
|
|
10
10
|
return (
|
|
11
|
-
<DropdownMenu items={dropdownMenu}>
|
|
11
|
+
<DropdownMenu items={dropdownMenu} nativeButton={false}>
|
|
12
12
|
<ActionIcon icon={MoreHorizontalIcon} size={'small'} />
|
|
13
13
|
</DropdownMenu>
|
|
14
14
|
);
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
ChatInputActionBar,
|
|
5
5
|
ChatInputActions,
|
|
6
6
|
type ChatInputActionsProps,
|
|
7
|
-
CodeLanguageSelect,
|
|
8
7
|
} from '@lobehub/editor/react';
|
|
9
8
|
import { cssVar } from 'antd-style';
|
|
10
9
|
import {
|
|
@@ -122,16 +121,6 @@ const TypoBar = memo(() => {
|
|
|
122
121
|
label: t('typobar.codeblock'),
|
|
123
122
|
onClick: editorState.codeblock,
|
|
124
123
|
},
|
|
125
|
-
editorState.isCodeblock && {
|
|
126
|
-
children: (
|
|
127
|
-
<CodeLanguageSelect
|
|
128
|
-
onSelect={(value) => editorState.updateCodeblockLang(value)}
|
|
129
|
-
value={editorState.codeblockLang}
|
|
130
|
-
/>
|
|
131
|
-
),
|
|
132
|
-
disabled: !editorState.isCodeblock,
|
|
133
|
-
key: 'codeblockLang',
|
|
134
|
-
},
|
|
135
124
|
].filter(Boolean) as ChatInputActionsProps['items'],
|
|
136
125
|
[editorState],
|
|
137
126
|
);
|
|
@@ -7,7 +7,10 @@ import { useConversationStore } from '@/features/Conversation/store';
|
|
|
7
7
|
|
|
8
8
|
import { type ChatItemProps } from '../../type';
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const EditorModal = dynamic(
|
|
11
|
+
() => import('@/features/EditorModal').then((mode) => mode.EditorModal),
|
|
12
|
+
{ ssr: false },
|
|
13
|
+
);
|
|
11
14
|
|
|
12
15
|
export const MSG_CONTENT_CLASSNAME = 'msg_content_flag';
|
|
13
16
|
|
|
@@ -60,13 +63,6 @@ const MessageContent = memo<MessageContentProps>(
|
|
|
60
63
|
s.updateMessageContent,
|
|
61
64
|
]);
|
|
62
65
|
|
|
63
|
-
const onChange = useCallback(
|
|
64
|
-
(value: string) => {
|
|
65
|
-
updateMessageContent(id, value);
|
|
66
|
-
},
|
|
67
|
-
[id, updateMessageContent],
|
|
68
|
-
);
|
|
69
|
-
|
|
70
66
|
const onEditingChange = useCallback(
|
|
71
67
|
(edit: boolean) => toggleMessageEditing(id, edit),
|
|
72
68
|
[id, toggleMessageEditing],
|
|
@@ -90,10 +86,13 @@ const MessageContent = memo<MessageContentProps>(
|
|
|
90
86
|
</Flexbox>
|
|
91
87
|
<Suspense fallback={null}>
|
|
92
88
|
{editing && (
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
<EditorModal
|
|
90
|
+
onCancel={() => onEditingChange(false)}
|
|
91
|
+
onConfirm={async (value) => {
|
|
92
|
+
await updateMessageContent(id, value);
|
|
93
|
+
onEditingChange(false);
|
|
94
|
+
}}
|
|
95
|
+
open={editing}
|
|
97
96
|
value={message ? String(message) : ''}
|
|
98
97
|
/>
|
|
99
98
|
)}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ReactCodePlugin,
|
|
3
|
+
ReactCodemirrorPlugin,
|
|
4
|
+
ReactHRPlugin,
|
|
5
|
+
ReactLinkPlugin,
|
|
6
|
+
ReactListPlugin,
|
|
7
|
+
ReactMathPlugin,
|
|
8
|
+
ReactTablePlugin,
|
|
9
|
+
} from '@lobehub/editor';
|
|
10
|
+
import { Editor, useEditor } from '@lobehub/editor/react';
|
|
11
|
+
import { Flexbox } from '@lobehub/ui';
|
|
12
|
+
import { FC } from 'react';
|
|
13
|
+
|
|
14
|
+
import TypoBar from './Typobar';
|
|
15
|
+
|
|
16
|
+
interface EditorCanvasProps {
|
|
17
|
+
onChange?: (value: string) => void;
|
|
18
|
+
value?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const EditorCanvas: FC<EditorCanvasProps> = ({ value, onChange }) => {
|
|
22
|
+
const editor = useEditor();
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<TypoBar editor={editor} />
|
|
26
|
+
<Flexbox
|
|
27
|
+
onClick={() => {
|
|
28
|
+
editor?.focus();
|
|
29
|
+
}}
|
|
30
|
+
padding={16}
|
|
31
|
+
style={{ cursor: 'text', maxHeight: '80vh', minHeight: '50vh', overflowY: 'auto' }}
|
|
32
|
+
>
|
|
33
|
+
<div
|
|
34
|
+
onClick={(e) => {
|
|
35
|
+
e.stopPropagation();
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
}}
|
|
38
|
+
>
|
|
39
|
+
<Editor
|
|
40
|
+
autoFocus
|
|
41
|
+
content={''}
|
|
42
|
+
editor={editor}
|
|
43
|
+
onInit={(editor) => {
|
|
44
|
+
if (!editor || !value) return;
|
|
45
|
+
try {
|
|
46
|
+
editor?.setDocument('markdown', value);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
console.error('setDocument error:', e);
|
|
49
|
+
}
|
|
50
|
+
}}
|
|
51
|
+
onTextChange={(editor) => {
|
|
52
|
+
try {
|
|
53
|
+
const newValue = editor.getDocument('markdown') as unknown as string;
|
|
54
|
+
onChange?.(newValue);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
console.error('getDocument error:', e);
|
|
57
|
+
onChange?.('');
|
|
58
|
+
}
|
|
59
|
+
}}
|
|
60
|
+
plugins={[
|
|
61
|
+
ReactListPlugin,
|
|
62
|
+
ReactCodePlugin,
|
|
63
|
+
ReactCodemirrorPlugin,
|
|
64
|
+
ReactHRPlugin,
|
|
65
|
+
ReactLinkPlugin,
|
|
66
|
+
ReactTablePlugin,
|
|
67
|
+
ReactMathPlugin,
|
|
68
|
+
]}
|
|
69
|
+
style={{
|
|
70
|
+
paddingBottom: 120,
|
|
71
|
+
}}
|
|
72
|
+
type={'text'}
|
|
73
|
+
variant={'chat'}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
</Flexbox>
|
|
77
|
+
</>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export default EditorCanvas;
|