@lobehub/chat 1.6.13 → 1.6.14
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/package.json +1 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/index.tsx +6 -34
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/LocalFiles.tsx +46 -0
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/index.tsx +31 -26
- package/src/const/layoutTokens.ts +1 -1
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/LocalFiles.tsx +0 -10
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 1.6.14](https://github.com/lobehub/lobe-chat/compare/v1.6.13...v1.6.14)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2024-07-26**</sup>
|
|
8
|
+
|
|
9
|
+
#### 💄 Styles
|
|
10
|
+
|
|
11
|
+
- **misc**: Improve input file upload.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### Styles
|
|
19
|
+
|
|
20
|
+
- **misc**: Improve input file upload, closes [#3314](https://github.com/lobehub/lobe-chat/issues/3314) ([de85553](https://github.com/lobehub/lobe-chat/commit/de85553))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
5
30
|
### [Version 1.6.13](https://github.com/lobehub/lobe-chat/compare/v1.6.12...v1.6.13)
|
|
6
31
|
|
|
7
32
|
<sup>Released on **2024-07-25**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.14",
|
|
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",
|
package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/Footer/index.tsx
CHANGED
|
@@ -7,20 +7,17 @@ import { memo, useEffect, useState } from 'react';
|
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
import { Center, Flexbox } from 'react-layout-kit';
|
|
9
9
|
|
|
10
|
-
import DragUpload from '@/components/DragUpload';
|
|
11
10
|
import StopLoadingIcon from '@/components/StopLoading';
|
|
12
11
|
import SaveTopic from '@/features/ChatInput/Topic';
|
|
13
12
|
import { useSendMessage } from '@/features/ChatInput/useSend';
|
|
14
|
-
import { useAgentStore } from '@/store/agent';
|
|
15
|
-
import { agentSelectors } from '@/store/agent/slices/chat';
|
|
16
13
|
import { useChatStore } from '@/store/chat';
|
|
17
14
|
import { chatSelectors, topicSelectors } from '@/store/chat/selectors';
|
|
18
15
|
import { filesSelectors, useFileStore } from '@/store/file';
|
|
19
16
|
import { useUserStore } from '@/store/user';
|
|
20
|
-
import {
|
|
17
|
+
import { preferenceSelectors } from '@/store/user/selectors';
|
|
21
18
|
import { isMacOS } from '@/utils/platform';
|
|
22
19
|
|
|
23
|
-
import
|
|
20
|
+
import LocalFiles from '../LocalFiles';
|
|
24
21
|
import SendMore from './SendMore';
|
|
25
22
|
|
|
26
23
|
const useStyles = createStyles(({ css, prefixCls, token }) => {
|
|
@@ -51,10 +48,11 @@ const useStyles = createStyles(({ css, prefixCls, token }) => {
|
|
|
51
48
|
});
|
|
52
49
|
|
|
53
50
|
interface FooterProps {
|
|
51
|
+
expand: boolean;
|
|
54
52
|
setExpand?: (expand: boolean) => void;
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
const Footer = memo<FooterProps>(({ setExpand }) => {
|
|
55
|
+
const Footer = memo<FooterProps>(({ setExpand, expand }) => {
|
|
58
56
|
const { t } = useTranslation('chat');
|
|
59
57
|
|
|
60
58
|
const { theme, styles } = useStyles();
|
|
@@ -75,28 +73,7 @@ const Footer = memo<FooterProps>(({ setExpand }) => {
|
|
|
75
73
|
|
|
76
74
|
const isImageUploading = useFileStore(filesSelectors.isImageUploading);
|
|
77
75
|
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
const enabledFiles = useUserStore(modelProviderSelectors.isModelEnabledFiles(model));
|
|
81
|
-
|
|
82
|
-
const [useCmdEnterToSend, canUpload] = useUserStore((s) => [
|
|
83
|
-
preferenceSelectors.useCmdEnterToSend(s),
|
|
84
|
-
modelProviderSelectors.isModelEnabledUpload(model)(s),
|
|
85
|
-
]);
|
|
86
|
-
|
|
87
|
-
const uploadFile = useFileStore((s) => s.uploadFile);
|
|
88
|
-
|
|
89
|
-
const uploadImages = async (fileList: FileList | undefined) => {
|
|
90
|
-
if (!fileList || fileList.length === 0) return;
|
|
91
|
-
|
|
92
|
-
const pools = Array.from(fileList).map(async (file) => {
|
|
93
|
-
// skip none-file items
|
|
94
|
-
if (!file.type.startsWith('image') && !enabledFiles) return;
|
|
95
|
-
await uploadFile(file);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
await Promise.all(pools);
|
|
99
|
-
};
|
|
76
|
+
const [useCmdEnterToSend] = useUserStore((s) => [preferenceSelectors.useCmdEnterToSend(s)]);
|
|
100
77
|
|
|
101
78
|
const sendMessage = useSendMessage();
|
|
102
79
|
|
|
@@ -142,12 +119,7 @@ const Footer = memo<FooterProps>(({ setExpand }) => {
|
|
|
142
119
|
padding={'0 24px'}
|
|
143
120
|
>
|
|
144
121
|
<Flexbox align={'center'} gap={8} horizontal style={{ overflow: 'hidden' }}>
|
|
145
|
-
{
|
|
146
|
-
<>
|
|
147
|
-
<DragUpload enabledFiles={enabledFiles} onUploadFiles={uploadImages} />
|
|
148
|
-
<LocalFiles />
|
|
149
|
-
</>
|
|
150
|
-
)}
|
|
122
|
+
{expand && <LocalFiles />}
|
|
151
123
|
</Flexbox>
|
|
152
124
|
<Flexbox align={'center'} flex={'none'} gap={8} horizontal>
|
|
153
125
|
<Flexbox
|
package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/LocalFiles.tsx
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { memo } from 'react';
|
|
2
|
+
|
|
3
|
+
import DragUpload from '@/components/DragUpload';
|
|
4
|
+
import { EditableFileList } from '@/features/FileList';
|
|
5
|
+
import { useAgentStore } from '@/store/agent';
|
|
6
|
+
import { agentSelectors } from '@/store/agent/slices/chat';
|
|
7
|
+
import { useFileStore } from '@/store/file';
|
|
8
|
+
import { useUserStore } from '@/store/user';
|
|
9
|
+
import { modelProviderSelectors } from '@/store/user/selectors';
|
|
10
|
+
|
|
11
|
+
interface LocalFilesProps {
|
|
12
|
+
padding?: number | string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const LocalFiles = memo<LocalFilesProps>(({ padding }) => {
|
|
16
|
+
const model = useAgentStore(agentSelectors.currentAgentModel);
|
|
17
|
+
|
|
18
|
+
const enabledFiles = useUserStore(modelProviderSelectors.isModelEnabledFiles(model));
|
|
19
|
+
const canUpload = useUserStore(modelProviderSelectors.isModelEnabledUpload(model));
|
|
20
|
+
|
|
21
|
+
const inputFilesList = useFileStore((s) => s.inputFilesList);
|
|
22
|
+
const uploadFile = useFileStore((s) => s.uploadFile);
|
|
23
|
+
|
|
24
|
+
const uploadImages = async (fileList: FileList | undefined) => {
|
|
25
|
+
if (!fileList || fileList.length === 0) return;
|
|
26
|
+
|
|
27
|
+
const pools = Array.from(fileList).map(async (file) => {
|
|
28
|
+
// skip none-file items
|
|
29
|
+
if (!file.type.startsWith('image') && !enabledFiles) return;
|
|
30
|
+
await uploadFile(file);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await Promise.all(pools);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
canUpload && (
|
|
38
|
+
<>
|
|
39
|
+
<DragUpload enabledFiles={enabledFiles} onUploadFiles={uploadImages} />
|
|
40
|
+
<EditableFileList items={inputFilesList} padding={padding ?? 0} />
|
|
41
|
+
</>
|
|
42
|
+
)
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export default LocalFiles;
|
|
@@ -14,6 +14,7 @@ import { systemStatusSelectors } from '@/store/global/selectors';
|
|
|
14
14
|
|
|
15
15
|
import Footer from './Footer';
|
|
16
16
|
import Head from './Header';
|
|
17
|
+
import LocalFiles from './LocalFiles';
|
|
17
18
|
import TextArea from './TextArea';
|
|
18
19
|
|
|
19
20
|
const DesktopChatInput = memo(() => {
|
|
@@ -25,33 +26,37 @@ const DesktopChatInput = memo(() => {
|
|
|
25
26
|
]);
|
|
26
27
|
|
|
27
28
|
return (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
height={'100%'}
|
|
47
|
-
padding={'12px 0 16px'}
|
|
48
|
-
style={{ minHeight: CHAT_TEXTAREA_HEIGHT, position: 'relative' }}
|
|
29
|
+
<>
|
|
30
|
+
{!expand && <LocalFiles padding={'8px 16px'} />}
|
|
31
|
+
<DraggablePanel
|
|
32
|
+
fullscreen={expand}
|
|
33
|
+
headerHeight={HEADER_HEIGHT}
|
|
34
|
+
maxHeight={CHAT_TEXTAREA_MAX_HEIGHT}
|
|
35
|
+
minHeight={CHAT_TEXTAREA_HEIGHT}
|
|
36
|
+
onSizeChange={(_, size) => {
|
|
37
|
+
if (!size) return;
|
|
38
|
+
|
|
39
|
+
updatePreference({
|
|
40
|
+
inputHeight:
|
|
41
|
+
typeof size.height === 'string' ? Number.parseInt(size.height) : size.height,
|
|
42
|
+
});
|
|
43
|
+
}}
|
|
44
|
+
placement="bottom"
|
|
45
|
+
size={{ height: inputHeight, width: '100%' }}
|
|
46
|
+
style={{ zIndex: 10 }}
|
|
49
47
|
>
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
<Flexbox
|
|
49
|
+
gap={8}
|
|
50
|
+
height={'100%'}
|
|
51
|
+
padding={'12px 0 16px'}
|
|
52
|
+
style={{ minHeight: CHAT_TEXTAREA_HEIGHT, position: 'relative' }}
|
|
53
|
+
>
|
|
54
|
+
<Head expand={expand} setExpand={setExpand} />
|
|
55
|
+
<TextArea setExpand={setExpand} />
|
|
56
|
+
<Footer expand={expand} setExpand={setExpand} />
|
|
57
|
+
</Flexbox>
|
|
58
|
+
</DraggablePanel>
|
|
59
|
+
</>
|
|
55
60
|
);
|
|
56
61
|
});
|
|
57
62
|
|
|
@@ -4,7 +4,7 @@ export const HEADER_HEIGHT = 64;
|
|
|
4
4
|
export const MOBILE_NABBAR_HEIGHT = 44;
|
|
5
5
|
export const MOBILE_TABBAR_HEIGHT = 48;
|
|
6
6
|
export const CHAT_TEXTAREA_MAX_HEIGHT = 800;
|
|
7
|
-
export const CHAT_TEXTAREA_HEIGHT =
|
|
7
|
+
export const CHAT_TEXTAREA_HEIGHT = 160;
|
|
8
8
|
export const CHAT_TEXTAREA_HEIGHT_MOBILE = 108;
|
|
9
9
|
export const CHAT_SIDEBAR_WIDTH = 280;
|
|
10
10
|
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { memo } from 'react';
|
|
2
|
-
|
|
3
|
-
import { EditableFileList } from '@/features/FileList';
|
|
4
|
-
import { useFileStore } from '@/store/file';
|
|
5
|
-
|
|
6
|
-
export const LocalFiles = memo(() => {
|
|
7
|
-
const inputFilesList = useFileStore((s) => s.inputFilesList);
|
|
8
|
-
|
|
9
|
-
return <EditableFileList items={inputFilesList} padding={0} />;
|
|
10
|
-
});
|