@hzab/form-render-mobile 0.0.15 → 0.0.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/form-render-mobile",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "formily-form-render-mobile",
5
5
  "main": "lib",
6
6
  "scripts": {
@@ -0,0 +1,39 @@
1
+ import { checkImageUrl, checkVideoUrl, checkAudioUrl } from "./utils";
2
+
3
+ export const TYPE_VIDEO = "video";
4
+ export const TYPE_IMG = "img";
5
+ export const TYPE_AUDIO = "audio";
6
+
7
+ export function checkFileType(file) {
8
+ const { type, url = file?.ossUrl } = file || {};
9
+ let fileType = "";
10
+ // 判断文件类型,获取对应展示的数据
11
+ if (url) {
12
+ // 图片
13
+ if (url.startsWith("data:image/") || checkImageUrl(url)) {
14
+ fileType = TYPE_IMG;
15
+ } else if (checkVideoUrl(url)) {
16
+ // 视频
17
+ fileType = TYPE_VIDEO;
18
+ } else if (checkAudioUrl(url)) {
19
+ // 音频
20
+ fileType = TYPE_AUDIO;
21
+ }
22
+ } else if (type) {
23
+ // 图片
24
+ if (type?.startsWith("image/")) {
25
+ fileType = TYPE_IMG;
26
+ }
27
+
28
+ // 视频
29
+ if (type?.startsWith("video/")) {
30
+ fileType = TYPE_VIDEO;
31
+ }
32
+
33
+ // 音频
34
+ if (type?.startsWith("audio/")) {
35
+ fileType = TYPE_AUDIO;
36
+ }
37
+ }
38
+ return fileType;
39
+ }
@@ -22,15 +22,13 @@
22
22
  max-width: 100vw;
23
23
  max-height: 100vh;
24
24
  background-color: #000 !important;
25
+ overflow: auto;
25
26
  .image-previewer-mask-img {
26
- max-width: 100vw;
27
- max-height: 100vh;
28
- width: 100vw;
29
27
  }
30
28
  .image-previewer-mask-close-btn {
31
- position: absolute;
32
- right: 2vw;
33
- top: 1vh;
29
+ position: fixed;
30
+ right: 4vw;
31
+ top: 2vh;
34
32
  width: 5vw;
35
33
  height: 5vw;
36
34
  line-height: 5vw;
@@ -0,0 +1,22 @@
1
+ import { CloseCircleFill } from "antd-mobile-icons";
2
+
3
+ export const ItemRender = (props) => {
4
+ const { index, disabled, readOnly, onItemDel } = props;
5
+ return (
6
+ <div className="file-item">
7
+ {props.children}
8
+ {disabled || readOnly ? null : (
9
+ <div
10
+ className="file-item-del"
11
+ onClick={() => {
12
+ onItemDel(index);
13
+ }}
14
+ >
15
+ <CloseCircleFill fontSize={14} />
16
+ </div>
17
+ )}
18
+ </div>
19
+ );
20
+ };
21
+
22
+ export default ItemRender;
@@ -0,0 +1,49 @@
1
+ import { getFileURL } from "../../common/utils";
2
+
3
+ import { TYPE_VIDEO, TYPE_IMG, TYPE_AUDIO, checkFileType } from "../../common/checkFileType";
4
+
5
+ import Video from "../video";
6
+ import Image from "../Image";
7
+ import ItemRender from "./ItemRender";
8
+
9
+ export const ItemList = (props) => {
10
+ const { fileList, baseUrl, disabled, readOnly, onItemDel } = props || {};
11
+
12
+ return (
13
+ <>
14
+ {fileList.map((it, idx) => {
15
+ if (!it) {
16
+ return null;
17
+ }
18
+ const { name, url = it?.ossUrl } = it || {};
19
+
20
+ let src = url || getFileURL(it);
21
+
22
+ if (baseUrl) {
23
+ src = baseUrl + src;
24
+ }
25
+
26
+ let content = it?.name;
27
+
28
+ const fileType = checkFileType(it);
29
+ if (fileType === TYPE_IMG) {
30
+ content = <Image className="file-item-view" src={src} alt={name} />;
31
+ }
32
+ if (fileType === TYPE_VIDEO) {
33
+ content = <Video src={src} href={src} />;
34
+ }
35
+ if (fileType === TYPE_AUDIO) {
36
+ content = <audio src={src} controls></audio>;
37
+ }
38
+
39
+ return (
40
+ <ItemRender index={idx} key={name + "_" + idx} disabled={disabled} readOnly={readOnly} onItemDel={onItemDel}>
41
+ {content}
42
+ </ItemRender>
43
+ );
44
+ })}
45
+ </>
46
+ );
47
+ };
48
+
49
+ export default ItemList;
@@ -23,8 +23,8 @@
23
23
  }
24
24
  .video-mask-close-btn {
25
25
  position: absolute;
26
- right: 2vw;
27
- top: 1vh;
26
+ right: 4vw;
27
+ top: 2vh;
28
28
  width: 5vw;
29
29
  height: 5vw;
30
30
  line-height: 5vw;
@@ -1,28 +1,17 @@
1
1
  import { useState, useRef, useEffect, useMemo } from "react";
2
2
  import { Button, Dialog, ActionSheet, Toast } from "antd-mobile";
3
- import { CloseCircleFill } from "antd-mobile-icons";
4
3
  import { nanoid } from "nanoid";
5
4
 
6
- import Video from "./video";
7
- import Image from "./Image";
5
+ import Video from "./components/video";
6
+ import Image from "./components/Image";
7
+ import ItemList from "./components/ItemList";
8
8
 
9
9
  import { getImage, getVideo, getAudio } from "./common/cordova-camera";
10
- import {
11
- getFileURL,
12
- checkImageUrl,
13
- checkVideoUrl,
14
- checkAudioUrl,
15
- handleMaxCount,
16
- handleInputFileList,
17
- } from "./common/utils";
10
+ import { handleMaxCount, handleInputFileList } from "./common/utils";
18
11
  import { handleOssUpload } from "./common/ossUpload";
19
12
 
20
13
  import "./uploader.less";
21
14
 
22
- const TYPE_VIDEO = "video";
23
- const TYPE_IMG = "img";
24
- const TYPE_AUDIO = "audio";
25
-
26
15
  const _ = require("lodash");
27
16
 
28
17
  function Uploader(props) {
@@ -50,6 +39,7 @@ function Uploader(props) {
50
39
  ossOpt,
51
40
  onCountExceed,
52
41
  } = props;
42
+ const [loading, setLoading] = useState(false);
53
43
  const [fileList, setFileList] = useState(handleInputFileList(value, maxCount));
54
44
  const [actionSheetVisible, setActionSheetVisible] = useState(false);
55
45
  useEffect(() => {
@@ -84,7 +74,9 @@ function Uploader(props) {
84
74
  });
85
75
  // 处理 oss 逻辑
86
76
  if (isOssUpload) {
77
+ setLoading(true);
87
78
  files = await handleOssUpload(files, { ...ossOpt, ossUrl });
79
+ setLoading(false);
88
80
  }
89
81
 
90
82
  e.target.value = ""; // HACK: fix the same file doesn't trigger onChange
@@ -182,11 +174,6 @@ function Uploader(props) {
182
174
  Dialog.confirm({
183
175
  content: "确认删除?",
184
176
  onConfirm: () => {
185
- // setFileList((files) => {
186
- // files.splice(idx, 1);
187
- // handleChange(files, "del");
188
- // return files;
189
- // });
190
177
  const middleValue = _.cloneDeep(fileList);
191
178
  middleValue.splice(idx, 1);
192
179
  handleChange(middleValue, "del");
@@ -195,25 +182,6 @@ function Uploader(props) {
195
182
  });
196
183
  }
197
184
 
198
- function ItemRender(props) {
199
- const { index } = props;
200
- return (
201
- <div className="file-item">
202
- {props.children}
203
- {disabled || readOnly ? null : (
204
- <div
205
- className="file-item-del"
206
- onClick={() => {
207
- onItemDel(index);
208
- }}
209
- >
210
- <CloseCircleFill fontSize={14} />
211
- </div>
212
- )}
213
- </div>
214
- );
215
- }
216
-
217
185
  const inputProps = {
218
186
  className: "aria-hidden",
219
187
  style: { display: "none" },
@@ -230,83 +198,13 @@ function Uploader(props) {
230
198
  <div className="uploader">
231
199
  <input {...inputProps} ref={uploaderRef}></input>
232
200
  <input {...inputProps} ref={audioUploaderRef} id={name + "-audio"} accept="audio/*"></input>
233
- {fileList.map((it, idx) => {
234
- if (!it) {
235
- return null;
236
- }
237
- const { type, name, url = it?.ossUrl } = it || {};
238
- let src = "";
239
- let fileType = "";
240
- let downLoadUrl = undefined;
241
-
242
- // 判断文件类型,获取对应展示的数据
243
- if (url) {
244
- src = url;
245
- // 图片
246
- const isImg = checkImageUrl(src);
247
- if (src.startsWith("data:image/") || isImg) {
248
- fileType = TYPE_IMG;
249
- } else if (checkVideoUrl(src)) {
250
- // 视频
251
- fileType = TYPE_VIDEO;
252
- } else if (checkAudioUrl(src)) {
253
- // 音频
254
- fileType = TYPE_AUDIO;
255
- }
256
- } else {
257
- // 图片
258
- if (type?.startsWith("image/")) {
259
- src = getFileURL(it);
260
- fileType = TYPE_IMG;
261
- }
262
-
263
- // 视频
264
- if (type?.startsWith("video/")) {
265
- src = getFileURL(it);
266
- fileType = TYPE_VIDEO;
267
- // TODO: 确认下载逻辑
268
- downLoadUrl = src;
269
- }
270
- if (type?.startsWith("audio/")) {
271
- src = getFileURL(it);
272
- fileType = TYPE_AUDIO;
273
- // TODO: 确认下载逻辑
274
- downLoadUrl = src;
275
- }
276
- }
277
-
278
- if (baseUrl) {
279
- src = baseUrl + src;
280
- }
281
-
282
- if (fileType === TYPE_IMG) {
283
- return (
284
- <ItemRender index={idx} key={name + "_" + idx}>
285
- <Image className="file-item-view" src={src} alt={name} />
286
- </ItemRender>
287
- );
288
- }
289
- if (fileType === TYPE_VIDEO) {
290
- return (
291
- <ItemRender index={idx} key={name + "_" + idx}>
292
- <Video src={src} href={downLoadUrl} />
293
- </ItemRender>
294
- );
295
- }
296
- if (fileType === TYPE_AUDIO) {
297
- return (
298
- <ItemRender index={idx} key={name + "_" + idx}>
299
- <audio src={src} controls></audio>
300
- </ItemRender>
301
- );
302
- }
303
-
304
- return (
305
- <ItemRender index={idx} key={name + "_" + idx}>
306
- {it?.name}
307
- </ItemRender>
308
- );
309
- })}
201
+ <ItemList
202
+ fileList={fileList}
203
+ baseUrl={isOssUpload ? baseUrl : ""}
204
+ disabled={disabled}
205
+ readOnly={readOnly}
206
+ onItemDel={onItemDel}
207
+ />
310
208
  {disabled || readOnly || (maxCount > 0 && fileList.length >= maxCount) ? null : (
311
209
  <>
312
210
  <Button
@@ -314,6 +212,7 @@ function Uploader(props) {
314
212
  onClick={() => {
315
213
  setActionSheetVisible(true);
316
214
  }}
215
+ loading={loading}
317
216
  >
318
217
  +
319
218
  </Button>