@fe-free/ai 4.1.5 → 4.1.7
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 +18 -0
- package/package.json +6 -4
- package/src/files/files.stories.tsx +22 -0
- package/src/files/index.tsx +41 -0
- package/src/files/style.scss +7 -0
- package/src/index.ts +2 -0
- package/src/sender/files.tsx +5 -11
- package/src/stream/index.ts +41 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @fe-free/ai
|
|
2
2
|
|
|
3
|
+
## 4.1.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- feat: ai
|
|
8
|
+
- @fe-free/core@4.1.7
|
|
9
|
+
- @fe-free/icons@4.1.7
|
|
10
|
+
- @fe-free/tool@4.1.7
|
|
11
|
+
|
|
12
|
+
## 4.1.6
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- feat: ai
|
|
17
|
+
- @fe-free/core@4.1.6
|
|
18
|
+
- @fe-free/icons@4.1.6
|
|
19
|
+
- @fe-free/tool@4.1.6
|
|
20
|
+
|
|
3
21
|
## 4.1.5
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fe-free/ai",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"author": "",
|
|
@@ -12,9 +12,11 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"ahooks": "^3.7.8",
|
|
14
14
|
"classnames": "^2.5.1",
|
|
15
|
-
"
|
|
15
|
+
"lodash-es": "^4.17.21",
|
|
16
|
+
"@fe-free/core": "4.1.7"
|
|
16
17
|
},
|
|
17
18
|
"peerDependencies": {
|
|
19
|
+
"@ant-design/x-sdk": "^2.1.3",
|
|
18
20
|
"antd": "^5.27.1",
|
|
19
21
|
"dayjs": "~1.11.10",
|
|
20
22
|
"i18next": "^25.7.2",
|
|
@@ -22,8 +24,8 @@
|
|
|
22
24
|
"i18next-icu": "^2.4.1",
|
|
23
25
|
"react": "^19.2.0",
|
|
24
26
|
"react-i18next": "^16.4.0",
|
|
25
|
-
"@fe-free/
|
|
26
|
-
"@fe-free/
|
|
27
|
+
"@fe-free/tool": "4.1.7",
|
|
28
|
+
"@fe-free/icons": "4.1.7"
|
|
27
29
|
},
|
|
28
30
|
"scripts": {
|
|
29
31
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { FileViewList } from '@fe-free/ai';
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
3
|
+
|
|
4
|
+
const meta: Meta<typeof FileViewList> = {
|
|
5
|
+
title: '@fe-free/ai/FileViewList',
|
|
6
|
+
component: FileViewList,
|
|
7
|
+
tags: ['autodocs'],
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type Story = StoryObj<typeof FileViewList>;
|
|
11
|
+
|
|
12
|
+
export const Default: Story = {
|
|
13
|
+
args: {
|
|
14
|
+
urls: [
|
|
15
|
+
'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
|
|
16
|
+
'https://minio-api-dev.pre-ai.pivotecho.cn/ai-agent/YWIW_%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20260108121456_230_1.png',
|
|
17
|
+
'https://minio-api-dev.pre-ai.pivotecho.cn/ai-agent/3Uck_%E5%8D%8E%E4%BD%8FAI%E9%A2%84%E8%AE%A2%E7%AC%AC%E4%BA%8C%E8%BD%AEPOC%E8%A6%81%E6%B1%82%282%29.pdf',
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default meta;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { FileCard } from '@fe-free/core';
|
|
2
|
+
import { Image } from 'antd';
|
|
3
|
+
import './style.scss';
|
|
4
|
+
|
|
5
|
+
function isUrl(url: string) {
|
|
6
|
+
return url.startsWith('http') || url.startsWith('https');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function FileView({ url, isImage: propsIsImage }: { url: string; isImage?: boolean }) {
|
|
10
|
+
const isImage = propsIsImage ?? FileCard.isImage(url);
|
|
11
|
+
|
|
12
|
+
// 判断是 url 才 decodeURIComponent
|
|
13
|
+
const decodedUrl = isUrl(url) ? decodeURIComponent(url) : url;
|
|
14
|
+
const name = decodedUrl.split('/').pop() || decodedUrl;
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className="fea-file-view">
|
|
18
|
+
{isImage ? (
|
|
19
|
+
<Image width={60} height={60} src={url} />
|
|
20
|
+
) : (
|
|
21
|
+
<div className="flex h-[60px] w-[250px] items-center rounded bg-01 px-1">
|
|
22
|
+
<div className="min-w-0">
|
|
23
|
+
<FileCard name={name} />
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
)}
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function FileViewList({ urls }: { urls: string[] }) {
|
|
32
|
+
return (
|
|
33
|
+
<div className="flex flex-wrap gap-2">
|
|
34
|
+
{urls.map((url) => (
|
|
35
|
+
<FileView key={url} url={url} />
|
|
36
|
+
))}
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { FileView, FileViewList };
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
export { FileView, FileViewList } from './files';
|
|
1
2
|
export { MSender } from './m_sender';
|
|
2
3
|
export type { MSenderProps, MSenderRef } from './m_sender';
|
|
3
4
|
export { Sender } from './sender';
|
|
4
5
|
export type { SenderProps, SenderRef } from './sender';
|
|
6
|
+
export { fetchStream } from './stream';
|
|
5
7
|
export { Tip } from './tip';
|
|
6
8
|
import './style.scss';
|
package/src/sender/files.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import { App, Button, Dropdown, Input, Modal, Upload } from 'antd';
|
|
|
5
5
|
import type { RefObject } from 'react';
|
|
6
6
|
import { useState } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
|
+
import { FileView } from '../files';
|
|
8
9
|
import FilesIcon from '../svgs/files.svg?react';
|
|
9
10
|
import type { SenderProps } from './types';
|
|
10
11
|
|
|
@@ -136,16 +137,9 @@ function UploadFileItem({ file, onDelete }: { file: UploadFile; onDelete: () =>
|
|
|
136
137
|
return (
|
|
137
138
|
<div className="group relative">
|
|
138
139
|
{isImage ? (
|
|
139
|
-
<
|
|
140
|
-
src={file.originFileObj && URL.createObjectURL(file.originFileObj)}
|
|
141
|
-
className="h-[53px] w-[53px] rounded-lg border border-01 bg-01 object-cover"
|
|
142
|
-
/>
|
|
140
|
+
<FileView url={URL.createObjectURL(file.originFileObj!)} isImage={isImage} />
|
|
143
141
|
) : (
|
|
144
|
-
<
|
|
145
|
-
<div className="min-w-0">
|
|
146
|
-
<FileCard name={file.name} size={file.size} />
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
142
|
+
<FileView url={file.name} />
|
|
149
143
|
)}
|
|
150
144
|
{!isDone && (
|
|
151
145
|
<div className="absolute inset-0 flex items-center justify-center bg-01/80">
|
|
@@ -163,7 +157,7 @@ function UploadFileItem({ file, onDelete }: { file: UploadFile; onDelete: () =>
|
|
|
163
157
|
function UrlFileItem({ url, onDelete }: { url: string; onDelete: () => void }) {
|
|
164
158
|
return (
|
|
165
159
|
<div className="group relative">
|
|
166
|
-
<div className="flex h-[
|
|
160
|
+
<div className="flex h-[60px] w-[250px] items-center rounded bg-01 px-2">
|
|
167
161
|
<div className="line-clamp-2">{url}</div>
|
|
168
162
|
</div>
|
|
169
163
|
<CloseOutlined
|
|
@@ -186,7 +180,7 @@ function Files(
|
|
|
186
180
|
|
|
187
181
|
return (
|
|
188
182
|
<>
|
|
189
|
-
{fileList && fileList.length > 0 && (
|
|
183
|
+
{((fileList && fileList.length > 0) || (fileUrls && fileUrls.length > 0)) && (
|
|
190
184
|
<div className="scrollbar-hide mb-2 flex gap-2 overflow-x-auto">
|
|
191
185
|
{fileList.map((file) => (
|
|
192
186
|
<UploadFileItem
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { XRequest } from '@ant-design/x-sdk';
|
|
2
|
+
|
|
3
|
+
async function fetchStream(
|
|
4
|
+
url: string,
|
|
5
|
+
{
|
|
6
|
+
params,
|
|
7
|
+
headers,
|
|
8
|
+
callbacks,
|
|
9
|
+
...rest
|
|
10
|
+
}: {
|
|
11
|
+
params?: Record<string, any>;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
callbacks?: {
|
|
14
|
+
onUpdate?: ({ event, data }: { event: string; data: string }, headers: Headers) => void;
|
|
15
|
+
onError?: (error: Error, errorInfo?: any) => void;
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
) {
|
|
19
|
+
await XRequest<any, { event: string; data: string }>(url, {
|
|
20
|
+
...rest,
|
|
21
|
+
params: params,
|
|
22
|
+
headers: headers,
|
|
23
|
+
callbacks: {
|
|
24
|
+
onUpdate: (message, headers) => {
|
|
25
|
+
// 会存在 message 为 undefined 的情况
|
|
26
|
+
if (message) {
|
|
27
|
+
callbacks?.onUpdate?.(message, headers);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
onSuccess: () => {
|
|
31
|
+
// nothing
|
|
32
|
+
},
|
|
33
|
+
onError: (error, errorInfo) => {
|
|
34
|
+
console.log('XRequest onError', error);
|
|
35
|
+
callbacks?.onError?.(error, errorInfo);
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { fetchStream };
|