@4399ywkf/design 1.3.8 → 1.3.10
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.
|
@@ -18,7 +18,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
|
|
|
18
18
|
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
19
19
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
20
20
|
import { useDebounceFn } from 'ahooks';
|
|
21
|
-
import { cloneDeep } from 'lodash-es';
|
|
21
|
+
import { cloneDeep, debounce } from 'lodash-es';
|
|
22
22
|
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
23
23
|
import "./styles/index.less";
|
|
24
24
|
import "./styles/test.less";
|
|
@@ -202,25 +202,40 @@ var WaterfallVirtual = function WaterfallVirtual(props) {
|
|
|
202
202
|
});
|
|
203
203
|
}, [cardList, scrollPos, isInitialized, overscan]);
|
|
204
204
|
|
|
205
|
+
// 在组件顶部添加
|
|
206
|
+
var queueDataRef = useRef(queueData);
|
|
207
|
+
|
|
208
|
+
// 在 queueData 更新时同步 ref
|
|
209
|
+
useEffect(function () {
|
|
210
|
+
queueDataRef.current = queueData;
|
|
211
|
+
}, [queueData]);
|
|
212
|
+
|
|
205
213
|
// 变更queueData中list的具体高度
|
|
206
|
-
var changeQueueDataHeight = useCallback(function (columnIndex, index, height) {
|
|
214
|
+
var changeQueueDataHeight = useCallback(debounce(function (columnIndex, index, height) {
|
|
207
215
|
setQueueData(function (prev) {
|
|
208
|
-
|
|
209
|
-
var
|
|
216
|
+
// 使用最新的状态进行计算
|
|
217
|
+
var currentData = queueDataRef.current;
|
|
218
|
+
|
|
219
|
+
// 添加边界检查,防止索引越界
|
|
220
|
+
if (!currentData[columnIndex] || !currentData[columnIndex].list[index]) {
|
|
221
|
+
return prev; // 如果索引无效,返回原数据
|
|
222
|
+
}
|
|
223
|
+
var item = currentData[columnIndex].list[index];
|
|
210
224
|
item.style.height = "".concat(height, "px");
|
|
211
225
|
item.h = height;
|
|
212
226
|
var currentHeight = item.y + item.h + gap;
|
|
213
227
|
// index 之后的item 的 y 需要重新计算
|
|
214
|
-
for (var i = index + 1; i <
|
|
215
|
-
var _item =
|
|
228
|
+
for (var i = index + 1; i < currentData[columnIndex].list.length; i++) {
|
|
229
|
+
var _item = currentData[columnIndex].list[i];
|
|
216
230
|
_item.y = currentHeight;
|
|
217
231
|
currentHeight += _item.h + gap;
|
|
218
232
|
_item.style.transform = "translate3d(".concat(_item.x, "px, ").concat(_item.y, "px, 0)");
|
|
219
233
|
}
|
|
220
|
-
|
|
221
|
-
return cloneDeep(
|
|
234
|
+
currentData[columnIndex].height = currentData[columnIndex].list[currentData[columnIndex].list.length - 1].y + currentData[columnIndex].list[currentData[columnIndex].list.length - 1].h + gap;
|
|
235
|
+
return cloneDeep(currentData);
|
|
222
236
|
});
|
|
223
|
-
}, [queueData
|
|
237
|
+
}, 16), [gap] // 只依赖 gap,移除 queueData 依赖
|
|
238
|
+
);
|
|
224
239
|
|
|
225
240
|
// 初始化滚动状态
|
|
226
241
|
var initScrollState = useCallback(function () {
|
package/dist/hooks/index.d.ts
CHANGED
package/dist/hooks/index.js
CHANGED
|
@@ -35,7 +35,7 @@ export var useDownloadImage = function useDownloadImage() {
|
|
|
35
35
|
// 单张图片下载
|
|
36
36
|
var downloadImage = useCallback( /*#__PURE__*/function () {
|
|
37
37
|
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(url, options) {
|
|
38
|
-
var _abortControllerRef$c, _response$headers$get, _response$headers$get2, _options$onSuccess, response, _options$onError, filename, blob, finalBlob, objectUrl, link, _options$onError2, err;
|
|
38
|
+
var _abortControllerRef$c, _response$headers$get, _response$headers$get2, _options$onSuccess, response, _options$onError, errMsg, filename, blob, finalBlob, objectUrl, link, _options$onError2, err;
|
|
39
39
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
40
40
|
while (1) switch (_context.prev = _context.next) {
|
|
41
41
|
case 0:
|
|
@@ -44,37 +44,55 @@ export var useDownloadImage = function useDownloadImage() {
|
|
|
44
44
|
setError(null);
|
|
45
45
|
setProgress(0);
|
|
46
46
|
abortControllerRef.current = new AbortController();
|
|
47
|
-
|
|
47
|
+
console.log('🟩 [downloadImage] 发起请求...', url, options);
|
|
48
|
+
_context.next = 8;
|
|
48
49
|
return fetch(url, _objectSpread(_objectSpread({}, options === null || options === void 0 ? void 0 : options.fetchOptions), {}, {
|
|
49
50
|
signal: (_abortControllerRef$c = abortControllerRef.current) === null || _abortControllerRef$c === void 0 ? void 0 : _abortControllerRef$c.signal
|
|
50
51
|
}));
|
|
51
|
-
case
|
|
52
|
+
case 8:
|
|
52
53
|
response = _context.sent;
|
|
54
|
+
console.log('🟩 [downloadImage] 响应状态:', response.status, response.statusText);
|
|
55
|
+
console.log('🟩 [downloadImage] 响应类型:', response.type);
|
|
56
|
+
console.log('🟩 [downloadImage] Content-Type:', response.headers.get('content-type'));
|
|
57
|
+
console.log('🟩 [downloadImage] Content-Disposition:', response.headers.get('content-disposition'));
|
|
53
58
|
if (response.ok) {
|
|
54
|
-
_context.next =
|
|
59
|
+
_context.next = 18;
|
|
55
60
|
break;
|
|
56
61
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
errMsg = "\u4E0B\u8F7D\u5931\u8D25: ".concat(response.status, " ").concat(response.statusText);
|
|
63
|
+
console.error('❌ [downloadImage] 响应非 200:', errMsg);
|
|
64
|
+
options === null || options === void 0 || (_options$onError = options.onError) === null || _options$onError === void 0 || _options$onError.call(options, new Error(errMsg));
|
|
65
|
+
throw new Error(errMsg);
|
|
66
|
+
case 18:
|
|
60
67
|
// // 检查内容类型
|
|
61
68
|
filename = (_response$headers$get = (_response$headers$get2 = response.headers.get('Content-Disposition')) === null || _response$headers$get2 === void 0 || (_response$headers$get2 = _response$headers$get2.split('filename=')) === null || _response$headers$get2 === void 0 ? void 0 : _response$headers$get2[1]) !== null && _response$headers$get !== void 0 ? _response$headers$get : 'image.png';
|
|
62
|
-
|
|
69
|
+
console.log('🟩 [downloadImage] 解析文件名:', filename);
|
|
70
|
+
_context.next = 22;
|
|
63
71
|
return response.blob();
|
|
64
|
-
case
|
|
72
|
+
case 22:
|
|
65
73
|
blob = _context.sent;
|
|
74
|
+
console.log('🟩 [downloadImage] Blob 大小:', blob.size, '字节');
|
|
75
|
+
|
|
76
|
+
// 检查 blob 是否为空
|
|
77
|
+
if (blob.size === 0) {
|
|
78
|
+
console.warn('⚠️ [downloadImage] Blob 内容为空,可能是资源无效或被拦截。');
|
|
79
|
+
}
|
|
80
|
+
|
|
66
81
|
// 处理图片压缩(如果需要)
|
|
67
82
|
finalBlob = blob;
|
|
68
83
|
if (!(options !== null && options !== void 0 && options.compress && options.quality)) {
|
|
69
|
-
_context.next =
|
|
84
|
+
_context.next = 32;
|
|
70
85
|
break;
|
|
71
86
|
}
|
|
72
|
-
|
|
87
|
+
console.log('🟨 [downloadImage] 启用压缩, 质量:', options.quality);
|
|
88
|
+
_context.next = 30;
|
|
73
89
|
return compressImage(blob, options.quality);
|
|
74
|
-
case
|
|
90
|
+
case 30:
|
|
75
91
|
finalBlob = _context.sent;
|
|
76
|
-
|
|
92
|
+
console.log('🟨 [downloadImage] 压缩后大小:', finalBlob.size);
|
|
93
|
+
case 32:
|
|
77
94
|
objectUrl = URL.createObjectURL(finalBlob);
|
|
95
|
+
console.log('🟩 [downloadImage] 生成 Object URL:', objectUrl);
|
|
78
96
|
link = document.createElement('a');
|
|
79
97
|
link.href = objectUrl;
|
|
80
98
|
// 如果没有提供文件名,则使用默认名称
|
|
@@ -87,29 +105,31 @@ export var useDownloadImage = function useDownloadImage() {
|
|
|
87
105
|
URL.revokeObjectURL(objectUrl);
|
|
88
106
|
setProgress(100);
|
|
89
107
|
options === null || options === void 0 || (_options$onSuccess = options.onSuccess) === null || _options$onSuccess === void 0 || _options$onSuccess.call(options);
|
|
108
|
+
console.log('✅ [downloadImage] 下载完成:', filename);
|
|
90
109
|
return _context.abrupt("return", {
|
|
91
110
|
success: true
|
|
92
111
|
});
|
|
93
|
-
case
|
|
94
|
-
_context.prev =
|
|
112
|
+
case 47:
|
|
113
|
+
_context.prev = 47;
|
|
95
114
|
_context.t0 = _context["catch"](0);
|
|
96
115
|
err = _context.t0 instanceof Error ? _context.t0 : new Error('未知错误');
|
|
97
|
-
console.error('下载图片失败:', err);
|
|
116
|
+
console.error('❌ [downloadImage] 下载图片失败:', err);
|
|
98
117
|
setError(err);
|
|
99
118
|
options === null || options === void 0 || (_options$onError2 = options.onError) === null || _options$onError2 === void 0 || _options$onError2.call(options, err);
|
|
100
119
|
return _context.abrupt("return", {
|
|
101
120
|
success: false,
|
|
102
121
|
error: err
|
|
103
122
|
});
|
|
104
|
-
case
|
|
105
|
-
_context.prev =
|
|
123
|
+
case 54:
|
|
124
|
+
_context.prev = 54;
|
|
106
125
|
setLoading(false);
|
|
107
|
-
|
|
108
|
-
|
|
126
|
+
console.log('🧹 [downloadImage] 状态重置完成。');
|
|
127
|
+
return _context.finish(54);
|
|
128
|
+
case 58:
|
|
109
129
|
case "end":
|
|
110
130
|
return _context.stop();
|
|
111
131
|
}
|
|
112
|
-
}, _callee, null, [[0,
|
|
132
|
+
}, _callee, null, [[0, 47, 54, 58]]);
|
|
113
133
|
}));
|
|
114
134
|
return function (_x, _x2) {
|
|
115
135
|
return _ref.apply(this, arguments);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
4
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
+
import { useEffect, useRef, useState } from 'react';
|
|
8
|
+
export function useScrolling(ref) {
|
|
9
|
+
var checkInterval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 60;
|
|
10
|
+
var _useState = useState(false),
|
|
11
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
12
|
+
isScrolling = _useState2[0],
|
|
13
|
+
setIsScrolling = _useState2[1];
|
|
14
|
+
var lastScrollTop = useRef(0);
|
|
15
|
+
var frame = useRef(null);
|
|
16
|
+
var stillCount = useRef(0);
|
|
17
|
+
useEffect(function () {
|
|
18
|
+
var el = ref.current;
|
|
19
|
+
if (!el) return;
|
|
20
|
+
var checkScrolling = function checkScrolling() {
|
|
21
|
+
var current = el.scrollTop;
|
|
22
|
+
if (current !== lastScrollTop.current) {
|
|
23
|
+
if (!isScrolling) setIsScrolling(true);
|
|
24
|
+
lastScrollTop.current = current;
|
|
25
|
+
stillCount.current = 0;
|
|
26
|
+
} else {
|
|
27
|
+
stillCount.current++;
|
|
28
|
+
// 连续几帧没变化,认为停止滚动
|
|
29
|
+
if (isScrolling && stillCount.current >= checkInterval) {
|
|
30
|
+
setIsScrolling(false);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
frame.current = requestAnimationFrame(checkScrolling);
|
|
34
|
+
};
|
|
35
|
+
frame.current = requestAnimationFrame(checkScrolling);
|
|
36
|
+
return function () {
|
|
37
|
+
if (frame.current !== null) {
|
|
38
|
+
cancelAnimationFrame(frame.current);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}, [ref, isScrolling, checkInterval]);
|
|
42
|
+
return isScrolling;
|
|
43
|
+
}
|