@ant-design/agentic-ui 2.29.27 → 2.29.28
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/dist/Bubble/UserBubble.js +7 -7
- package/dist/Bubble/schema-editor/SchemaEditorBridgeManager.d.ts +4 -0
- package/dist/Bubble/schema-editor/SchemaEditorBridgeManager.js +9 -0
- package/dist/MarkdownEditor/editor/utils/media.js +4 -4
- package/dist/MarkdownInputField/AttachmentButton/AttachmentFileList/AttachmentFileIcon.js +182 -3
- package/dist/MarkdownInputField/AttachmentButton/utils.d.ts +12 -0
- package/dist/MarkdownInputField/AttachmentButton/utils.js +42 -0
- package/dist/MarkdownInputField/FileMapView/index.js +111 -15
- package/dist/MarkdownInputField/FileMapView/style.js +45 -0
- package/dist/ThoughtChainList/CostMillis.d.ts +15 -0
- package/dist/ThoughtChainList/CostMillis.js +1 -1
- package/package.json +1 -2
|
@@ -202,7 +202,12 @@ var getContentStyle = function getContentStyle(standalone, customStyle) {
|
|
|
202
202
|
style: styles === null || styles === void 0 ? void 0 : styles.bubbleListItemExtraStyle,
|
|
203
203
|
className: cx("".concat(prefixClass, "-bubble-before"), "".concat(prefixClass, "-bubble-before-").concat(placement), "".concat(prefixClass, "-bubble-before-user"), hashId),
|
|
204
204
|
"data-testid": "message-before"
|
|
205
|
-
}, contentBeforeDom),
|
|
205
|
+
}, contentBeforeDom), /*#__PURE__*/ React.createElement("div", {
|
|
206
|
+
style: contentStyle,
|
|
207
|
+
className: cx("".concat(prefixClass, "-bubble-content"), "".concat(prefixClass, "-bubble-content-").concat(placement), "".concat(prefixClass, "-bubble-content-user"), _define_property({}, "".concat(prefixClass, "-bubble-content-pure"), props.pure), classNames === null || classNames === void 0 ? void 0 : classNames.bubbleListItemContentClassName, hashId),
|
|
208
|
+
onDoubleClick: props.onDoubleClick,
|
|
209
|
+
"data-testid": "message-content"
|
|
210
|
+
}, childrenDom), hasFileMap && /*#__PURE__*/ React.createElement("div", {
|
|
206
211
|
style: fileViewStyle,
|
|
207
212
|
className: cx("".concat(prefixClass, "-bubble-after"), "".concat(prefixClass, "-bubble-after-").concat(placement), "".concat(prefixClass, "-bubble-after-ai"), hashId),
|
|
208
213
|
"data-testid": "message-after"
|
|
@@ -210,12 +215,7 @@ var getContentStyle = function getContentStyle(standalone, customStyle) {
|
|
|
210
215
|
bubbleListRef: props.bubbleListRef,
|
|
211
216
|
bubble: props,
|
|
212
217
|
placement: placement
|
|
213
|
-
})),
|
|
214
|
-
style: contentStyle,
|
|
215
|
-
className: cx("".concat(prefixClass, "-bubble-content"), "".concat(prefixClass, "-bubble-content-").concat(placement), "".concat(prefixClass, "-bubble-content-user"), _define_property({}, "".concat(prefixClass, "-bubble-content-pure"), props.pure), classNames === null || classNames === void 0 ? void 0 : classNames.bubbleListItemContentClassName, hashId),
|
|
216
|
-
onDoubleClick: props.onDoubleClick,
|
|
217
|
-
"data-testid": "message-content"
|
|
218
|
-
}, childrenDom), contentAfterDom)))));
|
|
218
|
+
})), contentAfterDom)))));
|
|
219
219
|
if ((bubbleRenderConfig === null || bubbleRenderConfig === void 0 ? void 0 : bubbleRenderConfig.render) === false) return null;
|
|
220
220
|
return /*#__PURE__*/ React.createElement(MessagesContext.Provider, {
|
|
221
221
|
value: {
|
|
@@ -134,6 +134,15 @@ import { MarkdownEditor } from "../../MarkdownEditor";
|
|
|
134
134
|
return this.registry.has(id);
|
|
135
135
|
}
|
|
136
136
|
},
|
|
137
|
+
{
|
|
138
|
+
/**
|
|
139
|
+
* 获取指定 id 的当前内容(用于测试或调试)
|
|
140
|
+
*/ key: "getContentById",
|
|
141
|
+
value: function getContentById(id) {
|
|
142
|
+
var handler = this.registry.get(id);
|
|
143
|
+
return handler === null || handler === void 0 ? void 0 : handler.getContent();
|
|
144
|
+
}
|
|
145
|
+
},
|
|
137
146
|
{
|
|
138
147
|
key: "startBridge",
|
|
139
148
|
value: /**
|
|
@@ -164,6 +164,10 @@ export var getRemoteMediaType = function getRemoteMediaType(url) {
|
|
|
164
164
|
2,
|
|
165
165
|
'other'
|
|
166
166
|
];
|
|
167
|
+
if (typeof url !== 'string') return [
|
|
168
|
+
2,
|
|
169
|
+
'other'
|
|
170
|
+
];
|
|
167
171
|
if (url.startsWith('data:')) {
|
|
168
172
|
m = url.match(/data:image\/(\w+);base64,(.*)/);
|
|
169
173
|
if (m) return [
|
|
@@ -175,10 +179,6 @@ export var getRemoteMediaType = function getRemoteMediaType(url) {
|
|
|
175
179
|
'other'
|
|
176
180
|
];
|
|
177
181
|
}
|
|
178
|
-
if (typeof url !== 'string') return [
|
|
179
|
-
2,
|
|
180
|
-
'other'
|
|
181
|
-
];
|
|
182
182
|
_state.label = 1;
|
|
183
183
|
case 1:
|
|
184
184
|
_state.trys.push([
|
|
@@ -1,8 +1,168 @@
|
|
|
1
|
-
|
|
1
|
+
function _array_like_to_array(arr, len) {
|
|
2
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
+
return arr2;
|
|
5
|
+
}
|
|
6
|
+
function _array_with_holes(arr) {
|
|
7
|
+
if (Array.isArray(arr)) return arr;
|
|
8
|
+
}
|
|
9
|
+
function _define_property(obj, key, value) {
|
|
10
|
+
if (key in obj) {
|
|
11
|
+
Object.defineProperty(obj, key, {
|
|
12
|
+
value: value,
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
obj[key] = value;
|
|
19
|
+
}
|
|
20
|
+
return obj;
|
|
21
|
+
}
|
|
22
|
+
function _iterable_to_array_limit(arr, i) {
|
|
23
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
24
|
+
if (_i == null) return;
|
|
25
|
+
var _arr = [];
|
|
26
|
+
var _n = true;
|
|
27
|
+
var _d = false;
|
|
28
|
+
var _s, _e;
|
|
29
|
+
try {
|
|
30
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
31
|
+
_arr.push(_s.value);
|
|
32
|
+
if (i && _arr.length === i) break;
|
|
33
|
+
}
|
|
34
|
+
} catch (err) {
|
|
35
|
+
_d = true;
|
|
36
|
+
_e = err;
|
|
37
|
+
} finally{
|
|
38
|
+
try {
|
|
39
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
40
|
+
} finally{
|
|
41
|
+
if (_d) throw _e;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return _arr;
|
|
45
|
+
}
|
|
46
|
+
function _non_iterable_rest() {
|
|
47
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
48
|
+
}
|
|
49
|
+
function _object_spread(target) {
|
|
50
|
+
for(var i = 1; i < arguments.length; i++){
|
|
51
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
52
|
+
var ownKeys = Object.keys(source);
|
|
53
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
54
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
55
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
ownKeys.forEach(function(key) {
|
|
59
|
+
_define_property(target, key, source[key]);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return target;
|
|
63
|
+
}
|
|
64
|
+
function ownKeys(object, enumerableOnly) {
|
|
65
|
+
var keys = Object.keys(object);
|
|
66
|
+
if (Object.getOwnPropertySymbols) {
|
|
67
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
68
|
+
if (enumerableOnly) {
|
|
69
|
+
symbols = symbols.filter(function(sym) {
|
|
70
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
keys.push.apply(keys, symbols);
|
|
74
|
+
}
|
|
75
|
+
return keys;
|
|
76
|
+
}
|
|
77
|
+
function _object_spread_props(target, source) {
|
|
78
|
+
source = source != null ? source : {};
|
|
79
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
80
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
81
|
+
} else {
|
|
82
|
+
ownKeys(Object(source)).forEach(function(key) {
|
|
83
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return target;
|
|
87
|
+
}
|
|
88
|
+
function _sliced_to_array(arr, i) {
|
|
89
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
90
|
+
}
|
|
91
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
92
|
+
if (!o) return;
|
|
93
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
94
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
95
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
96
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
97
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
98
|
+
}
|
|
99
|
+
import { Eye, FileFailed, FileUploadingSpin, Play } from "@sofa-design/icons";
|
|
2
100
|
import { Image } from "antd";
|
|
3
|
-
import React from "react";
|
|
101
|
+
import React, { useEffect, useState } from "react";
|
|
4
102
|
import { getFileTypeIcon } from "../../../Workspace/File/utils";
|
|
5
|
-
import { isImageFile } from "../utils";
|
|
103
|
+
import { isImageFile, isVideoFile } from "../utils";
|
|
104
|
+
var VideoThumbnail = function VideoThumbnail(param) {
|
|
105
|
+
var src = param.src, className = param.className, style = param.style;
|
|
106
|
+
return /*#__PURE__*/ React.createElement("div", {
|
|
107
|
+
className: className,
|
|
108
|
+
style: _object_spread_props(_object_spread({}, style), {
|
|
109
|
+
position: 'relative',
|
|
110
|
+
overflow: 'hidden',
|
|
111
|
+
borderRadius: 'var(--radius-base)',
|
|
112
|
+
flexShrink: 0
|
|
113
|
+
})
|
|
114
|
+
}, /*#__PURE__*/ React.createElement("video", {
|
|
115
|
+
src: src,
|
|
116
|
+
preload: "metadata",
|
|
117
|
+
muted: true,
|
|
118
|
+
playsInline: true,
|
|
119
|
+
style: {
|
|
120
|
+
width: '100%',
|
|
121
|
+
height: '100%',
|
|
122
|
+
objectFit: 'cover',
|
|
123
|
+
display: 'block'
|
|
124
|
+
}
|
|
125
|
+
}), /*#__PURE__*/ React.createElement("div", {
|
|
126
|
+
style: {
|
|
127
|
+
position: 'absolute',
|
|
128
|
+
inset: 0,
|
|
129
|
+
display: 'flex',
|
|
130
|
+
alignItems: 'center',
|
|
131
|
+
justifyContent: 'center',
|
|
132
|
+
background: 'rgba(0, 0, 0, 0.35)',
|
|
133
|
+
pointerEvents: 'none'
|
|
134
|
+
}
|
|
135
|
+
}, /*#__PURE__*/ React.createElement(Play, {
|
|
136
|
+
style: {
|
|
137
|
+
width: 24,
|
|
138
|
+
height: 24,
|
|
139
|
+
color: '#fff'
|
|
140
|
+
}
|
|
141
|
+
})));
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* 从 File 创建并使用 object URL 的视频缩略图,避免每次渲染都创建新 URL
|
|
145
|
+
*/ var VideoThumbnailFromBlob = function VideoThumbnailFromBlob(param) {
|
|
146
|
+
var file = param.file, className = param.className, style = param.style;
|
|
147
|
+
var _useState = _sliced_to_array(useState(function() {
|
|
148
|
+
return null;
|
|
149
|
+
}), 2), objectUrl = _useState[0], setObjectUrl = _useState[1];
|
|
150
|
+
useEffect(function() {
|
|
151
|
+
var url = URL.createObjectURL(file);
|
|
152
|
+
setObjectUrl(url);
|
|
153
|
+
return function() {
|
|
154
|
+
URL.revokeObjectURL(url);
|
|
155
|
+
};
|
|
156
|
+
}, [
|
|
157
|
+
file
|
|
158
|
+
]);
|
|
159
|
+
if (!objectUrl) return null;
|
|
160
|
+
return /*#__PURE__*/ React.createElement(VideoThumbnail, {
|
|
161
|
+
src: objectUrl,
|
|
162
|
+
className: className,
|
|
163
|
+
style: style
|
|
164
|
+
});
|
|
165
|
+
};
|
|
6
166
|
/**
|
|
7
167
|
* AttachmentFileIcon 组件 - 附件文件图标组件
|
|
8
168
|
*
|
|
@@ -65,6 +225,25 @@ export var AttachmentFileIcon = function AttachmentFileIcon(props) {
|
|
|
65
225
|
alt: file.name
|
|
66
226
|
});
|
|
67
227
|
}
|
|
228
|
+
// 视频文件缩略图预览(与图片类似,带播放按钮)
|
|
229
|
+
if (isVideoFile(file)) {
|
|
230
|
+
var videoUrl = file.previewUrl || file.url;
|
|
231
|
+
if (videoUrl) {
|
|
232
|
+
return /*#__PURE__*/ React.createElement(VideoThumbnail, {
|
|
233
|
+
src: videoUrl,
|
|
234
|
+
className: className,
|
|
235
|
+
style: IMAGE_STYLE
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (file.size) {
|
|
239
|
+
return /*#__PURE__*/ React.createElement(VideoThumbnailFromBlob, {
|
|
240
|
+
key: "".concat(file.name, "-").concat(file.size, "-").concat(file.lastModified || 0),
|
|
241
|
+
file: file,
|
|
242
|
+
className: className,
|
|
243
|
+
style: IMAGE_STYLE
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
68
247
|
// 其他类型文件图标
|
|
69
248
|
var fileType = (_file_type = file.type) === null || _file_type === void 0 ? void 0 : _file_type.split('/').at(-1);
|
|
70
249
|
return getFileTypeIcon(fileType, '', file.name);
|
|
@@ -25,6 +25,18 @@ export declare const kbToSize: (kb: number) => string;
|
|
|
25
25
|
* @returns {boolean} 是否为图片文件
|
|
26
26
|
*/
|
|
27
27
|
export declare const isImageFile: (file: File) => boolean;
|
|
28
|
+
/**
|
|
29
|
+
* 检查文件是否为视频类型
|
|
30
|
+
* 通过 MIME 类型和文件扩展名双重判断
|
|
31
|
+
*
|
|
32
|
+
* @param {File} file - 要检查的文件(含 AttachmentFile)
|
|
33
|
+
* @returns {boolean} 是否为视频文件
|
|
34
|
+
*/
|
|
35
|
+
export declare const isVideoFile: (file: File) => boolean;
|
|
36
|
+
/**
|
|
37
|
+
* 检查文件是否为可展示的媒体类型(图片或视频)
|
|
38
|
+
*/
|
|
39
|
+
export declare const isMediaFile: (file: File) => boolean;
|
|
28
40
|
/**
|
|
29
41
|
* 获取设备品牌
|
|
30
42
|
*
|
|
@@ -64,6 +64,48 @@
|
|
|
64
64
|
return fileName.endsWith(ext);
|
|
65
65
|
});
|
|
66
66
|
};
|
|
67
|
+
var VIDEO_EXTENSIONS = [
|
|
68
|
+
'.mp4',
|
|
69
|
+
'.webm',
|
|
70
|
+
'.ogg',
|
|
71
|
+
'.ogv',
|
|
72
|
+
'.mov',
|
|
73
|
+
'.avi',
|
|
74
|
+
'.wmv',
|
|
75
|
+
'.flv',
|
|
76
|
+
'.m4v',
|
|
77
|
+
'.mkv'
|
|
78
|
+
];
|
|
79
|
+
var hasVideoExtension = function hasVideoExtension(pathOrName) {
|
|
80
|
+
var lower = (pathOrName === null || pathOrName === void 0 ? void 0 : pathOrName.toLowerCase()) || '';
|
|
81
|
+
var beforeQuery = lower.split('?')[0];
|
|
82
|
+
return VIDEO_EXTENSIONS.some(function(ext) {
|
|
83
|
+
return beforeQuery.endsWith(ext);
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* 检查文件是否为视频类型
|
|
88
|
+
* 通过 MIME 类型和文件扩展名双重判断
|
|
89
|
+
*
|
|
90
|
+
* @param {File} file - 要检查的文件(含 AttachmentFile)
|
|
91
|
+
* @returns {boolean} 是否为视频文件
|
|
92
|
+
*/ export var isVideoFile = function isVideoFile(file) {
|
|
93
|
+
var _file_type;
|
|
94
|
+
if ((_file_type = file.type) === null || _file_type === void 0 ? void 0 : _file_type.startsWith('video/')) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
if (hasVideoExtension(file.name)) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
var attachmentFile = file;
|
|
101
|
+
var url = attachmentFile.previewUrl || attachmentFile.url;
|
|
102
|
+
return !!url && hasVideoExtension(url);
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* 检查文件是否为可展示的媒体类型(图片或视频)
|
|
106
|
+
*/ export var isMediaFile = function isMediaFile(file) {
|
|
107
|
+
return isImageFile(file) || isVideoFile(file);
|
|
108
|
+
};
|
|
67
109
|
/**
|
|
68
110
|
* 设备品牌匹配列表
|
|
69
111
|
*/ var UA_MATCH_LIST = [
|
|
@@ -185,12 +185,12 @@ function _ts_generator(thisArg, body) {
|
|
|
185
185
|
};
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
|
-
import { FileSearch } from "@sofa-design/icons";
|
|
189
|
-
import { ConfigProvider, Image } from "antd";
|
|
188
|
+
import { FileSearch, Play } from "@sofa-design/icons";
|
|
189
|
+
import { ConfigProvider, Image, Modal } from "antd";
|
|
190
190
|
import classNames from "clsx";
|
|
191
191
|
import { motion } from "framer-motion";
|
|
192
192
|
import React, { useContext, useMemo, useState } from "react";
|
|
193
|
-
import { isImageFile } from "../AttachmentButton/utils";
|
|
193
|
+
import { isImageFile, isVideoFile } from "../AttachmentButton/utils";
|
|
194
194
|
import { FileMapViewItem } from "./FileMapViewItem";
|
|
195
195
|
import { useStyle } from "./style";
|
|
196
196
|
/**
|
|
@@ -255,26 +255,48 @@ import { useStyle } from "./style";
|
|
|
255
255
|
}, [
|
|
256
256
|
fileList
|
|
257
257
|
]);
|
|
258
|
-
//
|
|
259
|
-
var
|
|
258
|
+
// 视频列表,与图片一样以缩略图形式展示
|
|
259
|
+
var videoList = useMemo(function() {
|
|
260
260
|
return fileList.filter(function(file) {
|
|
261
|
-
return
|
|
261
|
+
return isVideoFile(file);
|
|
262
262
|
});
|
|
263
263
|
}, [
|
|
264
264
|
fileList
|
|
265
265
|
]);
|
|
266
|
-
//
|
|
267
|
-
var
|
|
268
|
-
|
|
266
|
+
// 所有非图片、非视频文件列表
|
|
267
|
+
var allNoMediaFiles = useMemo(function() {
|
|
268
|
+
return fileList.filter(function(file) {
|
|
269
|
+
return !isImageFile(file) && !isVideoFile(file);
|
|
270
|
+
});
|
|
271
|
+
}, [
|
|
272
|
+
fileList
|
|
273
|
+
]);
|
|
274
|
+
// 根据 maxDisplayCount 限制显示的非媒体文件列表
|
|
275
|
+
var noMediaFileList = useMemo(function() {
|
|
269
276
|
if (showAllFiles || props.maxDisplayCount === undefined) {
|
|
270
|
-
return
|
|
277
|
+
return allNoMediaFiles;
|
|
271
278
|
}
|
|
272
|
-
return
|
|
279
|
+
return allNoMediaFiles.slice(0, Math.max(0, props.maxDisplayCount));
|
|
273
280
|
}, [
|
|
274
|
-
|
|
281
|
+
allNoMediaFiles,
|
|
275
282
|
props.maxDisplayCount,
|
|
276
283
|
showAllFiles
|
|
277
284
|
]);
|
|
285
|
+
var _useState1 = _sliced_to_array(useState(false), 2), videoModalOpen = _useState1[0], setVideoModalOpen = _useState1[1];
|
|
286
|
+
var _useState2 = _sliced_to_array(useState(null), 2), previewingVideo = _useState2[0], setPreviewingVideo = _useState2[1];
|
|
287
|
+
var handleVideoClick = function handleVideoClick(file) {
|
|
288
|
+
if (file.status === 'error') return;
|
|
289
|
+
if (props.onPreview) {
|
|
290
|
+
props.onPreview(file);
|
|
291
|
+
} else {
|
|
292
|
+
setPreviewingVideo(file);
|
|
293
|
+
setVideoModalOpen(true);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
var handleVideoModalClose = function handleVideoModalClose() {
|
|
297
|
+
setVideoModalOpen(false);
|
|
298
|
+
setPreviewingVideo(null);
|
|
299
|
+
};
|
|
278
300
|
var handleViewAllClick = function handleViewAllClick() {
|
|
279
301
|
return _async_to_generator(function() {
|
|
280
302
|
var shouldExpand;
|
|
@@ -350,7 +372,81 @@ import { useStyle } from "./style";
|
|
|
350
372
|
src: file.previewUrl || file.url,
|
|
351
373
|
key: file.uuid || file.name || index
|
|
352
374
|
});
|
|
353
|
-
}))), /*#__PURE__*/ React.createElement(motion.div, {
|
|
375
|
+
}))), videoList.length > 0 && /*#__PURE__*/ React.createElement(motion.div, {
|
|
376
|
+
variants: {
|
|
377
|
+
visible: {
|
|
378
|
+
opacity: 1
|
|
379
|
+
},
|
|
380
|
+
hidden: {
|
|
381
|
+
opacity: 0
|
|
382
|
+
}
|
|
383
|
+
},
|
|
384
|
+
whileInView: "visible",
|
|
385
|
+
initial: "hidden",
|
|
386
|
+
animate: "visible",
|
|
387
|
+
className: classNames("".concat(prefix, "-video-row"), "".concat(prefix, "-video-row-").concat(placement), hashId),
|
|
388
|
+
style: props.style
|
|
389
|
+
}, videoList.map(function(file, index) {
|
|
390
|
+
var videoUrl = file.previewUrl || file.url || '';
|
|
391
|
+
var isSingleVideo = videoList.length === 1;
|
|
392
|
+
var thumbSize = isSingleVideo ? {
|
|
393
|
+
width: 330,
|
|
394
|
+
height: 188
|
|
395
|
+
} : {
|
|
396
|
+
width: 124,
|
|
397
|
+
height: 124
|
|
398
|
+
};
|
|
399
|
+
return /*#__PURE__*/ React.createElement("div", {
|
|
400
|
+
role: "button",
|
|
401
|
+
tabIndex: 0,
|
|
402
|
+
className: classNames("".concat(prefix, "-image"), "".concat(prefix, "-video-thumb"), hashId),
|
|
403
|
+
key: file.uuid || file.name || index,
|
|
404
|
+
onClick: function onClick() {
|
|
405
|
+
return handleVideoClick(file);
|
|
406
|
+
},
|
|
407
|
+
onKeyDown: function onKeyDown(e) {
|
|
408
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
409
|
+
e.preventDefault();
|
|
410
|
+
handleVideoClick(file);
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
"aria-label": "播放视频:".concat(file.name),
|
|
414
|
+
style: thumbSize
|
|
415
|
+
}, /*#__PURE__*/ React.createElement("video", {
|
|
416
|
+
src: videoUrl,
|
|
417
|
+
preload: "metadata",
|
|
418
|
+
muted: true,
|
|
419
|
+
playsInline: true,
|
|
420
|
+
style: {
|
|
421
|
+
width: '100%',
|
|
422
|
+
height: '100%',
|
|
423
|
+
objectFit: 'cover'
|
|
424
|
+
}
|
|
425
|
+
}), /*#__PURE__*/ React.createElement("div", {
|
|
426
|
+
className: classNames("".concat(prefix, "-video-play-overlay"), hashId),
|
|
427
|
+
"aria-hidden": true
|
|
428
|
+
}, /*#__PURE__*/ React.createElement(Play, null)));
|
|
429
|
+
})), /*#__PURE__*/ React.createElement(Modal, {
|
|
430
|
+
open: videoModalOpen,
|
|
431
|
+
onCancel: handleVideoModalClose,
|
|
432
|
+
footer: null,
|
|
433
|
+
width: "auto",
|
|
434
|
+
centered: true,
|
|
435
|
+
destroyOnClose: true,
|
|
436
|
+
styles: {
|
|
437
|
+
body: {
|
|
438
|
+
padding: 0
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}, previewingVideo && /*#__PURE__*/ React.createElement("video", {
|
|
442
|
+
src: previewingVideo.previewUrl || previewingVideo.url,
|
|
443
|
+
controls: true,
|
|
444
|
+
autoPlay: true,
|
|
445
|
+
style: {
|
|
446
|
+
maxWidth: '80vw',
|
|
447
|
+
maxHeight: '80vh'
|
|
448
|
+
}
|
|
449
|
+
})), /*#__PURE__*/ React.createElement(motion.div, {
|
|
354
450
|
variants: {
|
|
355
451
|
visible: {
|
|
356
452
|
opacity: 1,
|
|
@@ -371,7 +467,7 @@ import { useStyle } from "./style";
|
|
|
371
467
|
animate: 'visible',
|
|
372
468
|
className: classNames(prefix, hashId, props.className, "".concat(prefix, "-").concat(placement), "".concat(prefix, "-vertical")),
|
|
373
469
|
style: props.style
|
|
374
|
-
},
|
|
470
|
+
}, noMediaFileList.map(function(file, index) {
|
|
375
471
|
var _props_style;
|
|
376
472
|
return /*#__PURE__*/ React.createElement(FileMapViewItem, {
|
|
377
473
|
style: {
|
|
@@ -393,7 +489,7 @@ import { useStyle } from "./style";
|
|
|
393
489
|
className: classNames(hashId, "".concat(prefix, "-item")),
|
|
394
490
|
file: file
|
|
395
491
|
});
|
|
396
|
-
}), props.maxDisplayCount !== undefined &&
|
|
492
|
+
}), props.maxDisplayCount !== undefined && allNoMediaFiles.length > props.maxDisplayCount && !showAllFiles ? /*#__PURE__*/ React.createElement("div", {
|
|
397
493
|
style: {
|
|
398
494
|
width: (_props_style = props.style) === null || _props_style === void 0 ? void 0 : _props_style.width
|
|
399
495
|
},
|
|
@@ -137,6 +137,51 @@ var genStyle = function genStyle(token) {
|
|
|
137
137
|
transition: 'transform 0.3s'
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
|
+
}), _define_property(_obj, '&-video-row', {
|
|
141
|
+
display: 'flex',
|
|
142
|
+
flexWrap: 'wrap',
|
|
143
|
+
gap: 8,
|
|
144
|
+
width: 'fit-content',
|
|
145
|
+
'&-right': {
|
|
146
|
+
alignSelf: 'flex-end'
|
|
147
|
+
}
|
|
148
|
+
}), _define_property(_obj, '&-video-thumb', {
|
|
149
|
+
position: 'relative',
|
|
150
|
+
cursor: 'pointer',
|
|
151
|
+
opacity: 1,
|
|
152
|
+
background: 'var(--color-gray-bg-card-white)',
|
|
153
|
+
boxSizing: 'border-box',
|
|
154
|
+
boxShadow: 'var(--shadow-control-base)',
|
|
155
|
+
borderRadius: 'var(--radius-card-base)',
|
|
156
|
+
border: 'none',
|
|
157
|
+
overflow: 'hidden',
|
|
158
|
+
display: 'flex',
|
|
159
|
+
alignItems: 'center',
|
|
160
|
+
justifyContent: 'center',
|
|
161
|
+
'&:hover': {
|
|
162
|
+
boxShadow: 'var(--shadow-control-lg)',
|
|
163
|
+
'& video': {
|
|
164
|
+
transform: 'scale(1.05)'
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
'& video': {
|
|
168
|
+
transition: 'transform 0.3s'
|
|
169
|
+
}
|
|
170
|
+
}), _define_property(_obj, '&-video-play-overlay', {
|
|
171
|
+
position: 'absolute',
|
|
172
|
+
inset: 0,
|
|
173
|
+
display: 'flex',
|
|
174
|
+
alignItems: 'center',
|
|
175
|
+
justifyContent: 'center',
|
|
176
|
+
background: 'rgba(0, 0, 0, 0.35)',
|
|
177
|
+
borderRadius: 'inherit',
|
|
178
|
+
pointerEvents: 'none',
|
|
179
|
+
opacity: 0.9,
|
|
180
|
+
'& svg': {
|
|
181
|
+
width: 48,
|
|
182
|
+
height: 48,
|
|
183
|
+
color: '#fff'
|
|
184
|
+
}
|
|
140
185
|
}), _define_property(_obj, '&-image-list-view', {
|
|
141
186
|
background: 'var(--color-gray-bg-tip)',
|
|
142
187
|
padding: '4px',
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { LocalKeys } from '../I18n';
|
|
3
|
+
/**
|
|
4
|
+
* 将毫秒转换为可读的时间格式
|
|
5
|
+
*
|
|
6
|
+
* @param {number|undefined} ms - 毫秒数
|
|
7
|
+
* @param {LocalKeys} locale - 本地化配置
|
|
8
|
+
* @returns {string} 格式化后的时间字符串
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* msToTimes(1500, locale) // "1.5s"
|
|
12
|
+
* msToTimes(65000, locale) // "1m 5s"
|
|
13
|
+
* msToTimes(3665000, locale) // "1H 1m 5s"
|
|
14
|
+
*/
|
|
15
|
+
/** 导出供单测覆盖 undefined/null 分支 */
|
|
16
|
+
export declare const msToTimes: (ms: number | undefined | null, locale: LocalKeys) => string;
|
|
2
17
|
/**
|
|
3
18
|
* CostMillis 组件 - 耗时显示组件
|
|
4
19
|
*
|
|
@@ -13,7 +13,7 @@ import { I18nContext } from "../I18n";
|
|
|
13
13
|
* msToTimes(1500, locale) // "1.5s"
|
|
14
14
|
* msToTimes(65000, locale) // "1m 5s"
|
|
15
15
|
* msToTimes(3665000, locale) // "1H 1m 5s"
|
|
16
|
-
*/ var msToTimes = function msToTimes(ms, locale) {
|
|
16
|
+
*/ /** 导出供单测覆盖 undefined/null 分支 */ export var msToTimes = function msToTimes(ms, locale) {
|
|
17
17
|
if (ms === undefined || ms === null) {
|
|
18
18
|
return '';
|
|
19
19
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ant-design/agentic-ui",
|
|
3
|
-
"version": "2.29.
|
|
3
|
+
"version": "2.29.28",
|
|
4
4
|
"description": "面向智能体的 UI 组件库,提供多步推理可视化、工具调用展示、任务执行协同等 Agentic UI 能力",
|
|
5
5
|
"repository": "git@github.com:ant-design/agentic-ui.git",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"lint:css": "stylelint \"{src,test}/**/*.{css,less}\"",
|
|
25
25
|
"lint:es": "eslint \"{src,test}/**/*.{js,jsx,ts,tsx}\"",
|
|
26
26
|
"prepare": "husky install && dumi setup",
|
|
27
|
-
"prepublishOnly": "father doctor && pnpm run test && pnpm run build",
|
|
28
27
|
"prettier": "prettier --write \"{src,docs,test}/**/*.{js,jsx,ts,tsx,css,less,json,md}\"",
|
|
29
28
|
"preview": "pnpm dumi preview",
|
|
30
29
|
"report:demo": "node scripts/generateDemoReport.js",
|