index.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import { __assign, __awaiter, __generator, __spreadArray } from "tslib";
  2. import { useEvent, useRef } from 'functional-mini/component';
  3. import '../_util/assert-component2';
  4. import { mountComponent } from '../_util/component';
  5. import { useComponentEvent } from '../_util/hooks/useComponentEvent';
  6. import { useMixState } from '../_util/hooks/useMixState';
  7. import { triggerRefEvent } from '../_util/hooks/useReportRef';
  8. import { chooseImage } from '../_util/jsapi/choose-image';
  9. import { UploaderFunctionalProps, } from './props';
  10. import { useId } from 'functional-mini/compat';
  11. /**
  12. * 获取一个内部使用的 uid
  13. * 每次获取时自增
  14. */
  15. var useCounter = function () {
  16. var counterRef = useRef(0);
  17. // 使用 Date.now() 与 useId 作为前缀,防止每次前缀都相同
  18. var prefix = useId() + '-' + Date.now();
  19. return {
  20. getCount: function () {
  21. counterRef.current = counterRef.current + 1;
  22. return "".concat(prefix, "-").concat(counterRef.current);
  23. },
  24. };
  25. };
  26. var ImageUpload = function (props) {
  27. var getCount = useCounter().getCount;
  28. var _a = useMixState(props.defaultFileList, {
  29. value: props.fileList,
  30. postState: function (fileList) {
  31. return {
  32. valid: true,
  33. value: (fileList || []).map(function (item) {
  34. var file = __assign({}, item);
  35. if (typeof item.url === 'undefined') {
  36. file.url = '';
  37. }
  38. if (typeof item.uid === 'undefined') {
  39. file.uid = getCount();
  40. }
  41. if (typeof item.status === 'undefined') {
  42. file.status = 'done';
  43. }
  44. return file;
  45. }),
  46. };
  47. },
  48. }), fileList = _a[0], _b = _a[1], isControlled = _b.isControlled, update = _b.update, triggerUpdater = _b.triggerUpdater;
  49. triggerRefEvent();
  50. var triggerEvent = useComponentEvent(props).triggerEvent;
  51. function uploadFile(localFile) {
  52. return __awaiter(this, void 0, void 0, function () {
  53. var onUpload, uid, url, err_1;
  54. return __generator(this, function (_a) {
  55. switch (_a.label) {
  56. case 0:
  57. onUpload = props.onUpload;
  58. uid = getCount();
  59. triggerUpdater(function (oldFiles) {
  60. var tempFileList = __spreadArray(__spreadArray([], oldFiles, true), [
  61. {
  62. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  63. //@ts-expect-error
  64. path: localFile.path,
  65. size: localFile.size,
  66. uid: uid,
  67. status: 'uploading',
  68. },
  69. ], false);
  70. triggerEvent('change', tempFileList);
  71. return tempFileList;
  72. });
  73. _a.label = 1;
  74. case 1:
  75. _a.trys.push([1, 3, , 4]);
  76. return [4 /*yield*/, onUpload(localFile)];
  77. case 2:
  78. url = _a.sent();
  79. if (typeof url !== 'string' || !url) {
  80. updateFile(uid, {
  81. status: 'error',
  82. });
  83. return [2 /*return*/];
  84. }
  85. updateFile(uid, {
  86. status: 'done',
  87. url: url,
  88. });
  89. return [3 /*break*/, 4];
  90. case 3:
  91. err_1 = _a.sent();
  92. updateFile(uid, {
  93. status: 'error',
  94. });
  95. return [3 /*break*/, 4];
  96. case 4: return [2 /*return*/];
  97. }
  98. });
  99. });
  100. }
  101. function updateFile(uid, file) {
  102. return __awaiter(this, void 0, void 0, function () {
  103. return __generator(this, function (_a) {
  104. triggerUpdater(function (old) {
  105. var tempFileList = old.map(function (item) {
  106. if (item.uid === uid) {
  107. return __assign(__assign({}, item), file);
  108. }
  109. return item;
  110. });
  111. triggerEvent('change', tempFileList);
  112. return tempFileList;
  113. });
  114. return [2 /*return*/];
  115. });
  116. });
  117. }
  118. useEvent('chooseImage', function () { return __awaiter(void 0, void 0, void 0, function () {
  119. var onBeforeUpload, onUpload, maxCount, sourceType, localFileList, chooseImageRes, err_2, beforeUploadRes, err_3, tasks;
  120. return __generator(this, function (_a) {
  121. switch (_a.label) {
  122. case 0:
  123. onBeforeUpload = props.onBeforeUpload, onUpload = props.onUpload, maxCount = props.maxCount, sourceType = props.sourceType;
  124. if (!onUpload || typeof onUpload !== 'function') {
  125. throw new Error('need props onUpload');
  126. }
  127. _a.label = 1;
  128. case 1:
  129. _a.trys.push([1, 3, , 4]);
  130. return [4 /*yield*/, chooseImage({
  131. count: typeof maxCount === 'undefined'
  132. ? Infinity
  133. : maxCount - fileList.length,
  134. sourceType: sourceType,
  135. })];
  136. case 2:
  137. chooseImageRes = _a.sent();
  138. localFileList = (chooseImageRes.tempFiles ||
  139. chooseImageRes.tempFilePaths ||
  140. chooseImageRes.apFilePaths ||
  141. chooseImageRes.filePaths ||
  142. [])
  143. .map(function (item) {
  144. if (typeof item === 'string') {
  145. return {
  146. path: item,
  147. };
  148. }
  149. if (item.path) {
  150. return {
  151. path: item.path,
  152. size: item.size,
  153. };
  154. }
  155. })
  156. .filter(function (item) { return !!item; });
  157. return [3 /*break*/, 4];
  158. case 3:
  159. err_2 = _a.sent();
  160. triggerEvent('chooseImageError', err_2);
  161. return [2 /*return*/];
  162. case 4:
  163. if (!(onBeforeUpload && typeof onBeforeUpload === 'function')) return [3 /*break*/, 8];
  164. _a.label = 5;
  165. case 5:
  166. _a.trys.push([5, 7, , 8]);
  167. return [4 /*yield*/, onBeforeUpload(localFileList)];
  168. case 6:
  169. beforeUploadRes = _a.sent();
  170. if (beforeUploadRes === false) {
  171. return [2 /*return*/];
  172. }
  173. if (Array.isArray(beforeUploadRes)) {
  174. localFileList = beforeUploadRes;
  175. }
  176. return [3 /*break*/, 8];
  177. case 7:
  178. err_3 = _a.sent();
  179. return [2 /*return*/];
  180. case 8:
  181. tasks = localFileList.map(function (file) { return uploadFile(file); });
  182. return [4 /*yield*/, Promise.all(tasks)];
  183. case 9:
  184. _a.sent();
  185. return [2 /*return*/];
  186. }
  187. });
  188. }); });
  189. useEvent('onRemove', function (e) { return __awaiter(void 0, void 0, void 0, function () {
  190. var uid, file, result, tempFileList;
  191. return __generator(this, function (_a) {
  192. switch (_a.label) {
  193. case 0:
  194. uid = e.currentTarget.dataset.uid;
  195. file = fileList.find(function (item) { return item.uid === uid; });
  196. if (!(props.onRemove && typeof props.onRemove === 'function')) return [3 /*break*/, 2];
  197. return [4 /*yield*/, props.onRemove(file)];
  198. case 1:
  199. result = _a.sent();
  200. if (result === false) {
  201. return [2 /*return*/];
  202. }
  203. _a.label = 2;
  204. case 2:
  205. tempFileList = fileList.filter(function (item) { return item.uid !== uid; });
  206. if (!isControlled) {
  207. update(tempFileList);
  208. }
  209. triggerEvent('change', tempFileList);
  210. return [2 /*return*/];
  211. }
  212. });
  213. }); });
  214. useEvent('onPreview', function (e) {
  215. var uid = e.currentTarget.dataset.uid;
  216. var file = fileList.find(function (item) { return item.uid === uid; });
  217. triggerEvent('preview', file);
  218. });
  219. useEvent('update', function (e) {
  220. if (isControlled) {
  221. return;
  222. }
  223. update(e);
  224. });
  225. return {
  226. mixin: {
  227. value: fileList,
  228. },
  229. };
  230. };
  231. mountComponent(ImageUpload, UploaderFunctionalProps);