@susonwaiba/react-media-uploader 0.1.3 → 0.1.4
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/.github/workflows/release.yml +25 -0
- package/NEXTJS_INTEGRATION.md +128 -128
- package/README.md +118 -106
- package/bun.lock +37 -0
- package/dist/hooks/use-media-uploader.d.ts +8 -1
- package/dist/hooks/use-media-uploader.js +74 -32
- package/package.json +42 -40
- package/src/hooks/use-media-uploader.ts +315 -261
- package/src/index.ts +3 -3
- package/src/lib/media-helper.ts +153 -153
- package/src/types/media.ts +47 -47
- package/tsconfig.json +19 -19
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { markMediaAsCanceled, generateFileHash, generateUploadUrl, uploadToStorage, markMediaAsTemp, markMediaAsActive, generateMediaType, } from "../lib/media-helper";
|
|
2
|
-
import { MediaStatusEnum } from "../types/media";
|
|
2
|
+
import { MediaStatusEnum, MediaTypeEnum, } from "../types/media";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
export function useMediaUploader({ defaultValues, mediaUploadSuccessStatus = MediaStatusEnum.TEMP, enableManualUpload = false, serverConfig, onUploadSuccess, onUploadFailure, } = {}) {
|
|
5
5
|
const [values, setValues] = useState(defaultValues ?? {});
|
|
@@ -17,14 +17,19 @@ export function useMediaUploader({ defaultValues, mediaUploadSuccessStatus = Med
|
|
|
17
17
|
};
|
|
18
18
|
const onFileChange = async (file, name, multiple = false) => {
|
|
19
19
|
const localId = crypto.randomUUID();
|
|
20
|
+
const mediaType = await generateMediaType(file);
|
|
21
|
+
let tempPreviewUrl = undefined;
|
|
22
|
+
if (mediaType === MediaTypeEnum.IMAGE) {
|
|
23
|
+
tempPreviewUrl = URL.createObjectURL(file);
|
|
24
|
+
}
|
|
20
25
|
const item = {
|
|
21
26
|
localId,
|
|
22
27
|
name,
|
|
23
28
|
multiple,
|
|
24
29
|
file,
|
|
25
|
-
tempPreviewUrl
|
|
30
|
+
tempPreviewUrl,
|
|
26
31
|
media: {
|
|
27
|
-
type:
|
|
32
|
+
type: mediaType,
|
|
28
33
|
name: file.name,
|
|
29
34
|
mimeType: file.type,
|
|
30
35
|
size: file.size,
|
|
@@ -36,18 +41,30 @@ export function useMediaUploader({ defaultValues, mediaUploadSuccessStatus = Med
|
|
|
36
41
|
newState[localId] = item;
|
|
37
42
|
return newState;
|
|
38
43
|
});
|
|
44
|
+
setValues((previous) => {
|
|
45
|
+
const newState = { ...previous };
|
|
46
|
+
newState[name] = tempPreviewUrl;
|
|
47
|
+
return newState;
|
|
48
|
+
});
|
|
39
49
|
if (!enableManualUpload) {
|
|
40
|
-
uploadMediaFile(item);
|
|
50
|
+
await uploadMediaFile(item);
|
|
41
51
|
}
|
|
42
52
|
};
|
|
43
53
|
const uploadMediaFile = async (item) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
let uploadData;
|
|
55
|
+
if (serverConfig?.onGenerateUploadUrl) {
|
|
56
|
+
uploadData = await serverConfig?.onGenerateUploadUrl(item?.media);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const uploadUrlRes = await generateUploadUrl({
|
|
60
|
+
url: serverConfig?.generateUploadUrl,
|
|
61
|
+
additionalHeaders: serverConfig?.additionalHeaders,
|
|
62
|
+
media: item?.media,
|
|
63
|
+
});
|
|
64
|
+
uploadData = uploadUrlRes.data;
|
|
65
|
+
}
|
|
66
|
+
if (uploadData?.item && uploadData?.uploadUrl) {
|
|
67
|
+
item["media"] = uploadData?.item;
|
|
51
68
|
setMediaItems((previous) => {
|
|
52
69
|
const newState = { ...previous };
|
|
53
70
|
newState[item.localId] = item;
|
|
@@ -55,7 +72,7 @@ export function useMediaUploader({ defaultValues, mediaUploadSuccessStatus = Med
|
|
|
55
72
|
});
|
|
56
73
|
const abortController = new AbortController();
|
|
57
74
|
const uploadRes = await uploadToStorage({
|
|
58
|
-
uploadUrl:
|
|
75
|
+
uploadUrl: uploadData?.uploadUrl,
|
|
59
76
|
file: item.file,
|
|
60
77
|
onUploadProgress: (progressEvent) => {
|
|
61
78
|
const currentUploadInfo = {
|
|
@@ -70,11 +87,18 @@ export function useMediaUploader({ defaultValues, mediaUploadSuccessStatus = Med
|
|
|
70
87
|
}
|
|
71
88
|
return newState;
|
|
72
89
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
90
|
+
if (serverConfig?.markMediaAsCanceled) {
|
|
91
|
+
await markMediaAsCanceled({
|
|
92
|
+
url: serverConfig?.markMediaAsCanceled,
|
|
93
|
+
additionalHeaders: serverConfig?.additionalHeaders,
|
|
94
|
+
mediaIds: [uploadData?.item?.id],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
else if (serverConfig?.onMarkMediaAsCanceled) {
|
|
98
|
+
await serverConfig.onMarkMediaAsCanceled([
|
|
99
|
+
uploadData?.item?.id,
|
|
100
|
+
]);
|
|
101
|
+
}
|
|
78
102
|
},
|
|
79
103
|
};
|
|
80
104
|
setUploadInfos((previous) => {
|
|
@@ -89,30 +113,48 @@ export function useMediaUploader({ defaultValues, mediaUploadSuccessStatus = Med
|
|
|
89
113
|
return await onMediaUploadSuccess(item);
|
|
90
114
|
}
|
|
91
115
|
else if (onUploadFailure) {
|
|
92
|
-
onUploadFailure(uploadRes);
|
|
116
|
+
await onUploadFailure(uploadRes);
|
|
93
117
|
}
|
|
94
118
|
}
|
|
95
119
|
return undefined;
|
|
96
120
|
};
|
|
97
121
|
const onMediaUploadSuccess = async (item) => {
|
|
98
122
|
if (item.media.id) {
|
|
99
|
-
let
|
|
123
|
+
let markResItems = [];
|
|
100
124
|
if (mediaUploadSuccessStatus === MediaStatusEnum.TEMP) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
if (serverConfig?.onMarkMediaAsTemp) {
|
|
126
|
+
markResItems = await serverConfig.onMarkMediaAsTemp([item.media.id]);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const res = await markMediaAsTemp({
|
|
130
|
+
url: serverConfig?.markMediaAsTemp,
|
|
131
|
+
additionalHeaders: serverConfig?.additionalHeaders,
|
|
132
|
+
mediaIds: [item.media.id],
|
|
133
|
+
});
|
|
134
|
+
if (res?.data?.items?.length) {
|
|
135
|
+
markResItems = res.data.items;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
106
138
|
}
|
|
107
139
|
else if (mediaUploadSuccessStatus === MediaStatusEnum.ACTIVE) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
140
|
+
if (serverConfig.onMarkMediaAsActive) {
|
|
141
|
+
markResItems = await serverConfig.onMarkMediaAsActive([
|
|
142
|
+
item.media.id,
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const res = await markMediaAsActive({
|
|
147
|
+
url: serverConfig?.markMediaAsActive,
|
|
148
|
+
additionalHeaders: serverConfig?.additionalHeaders,
|
|
149
|
+
mediaIds: [item.media.id],
|
|
150
|
+
});
|
|
151
|
+
if (res?.data?.items?.length) {
|
|
152
|
+
markResItems = res.data.items;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
113
155
|
}
|
|
114
|
-
if (
|
|
115
|
-
const newMedia =
|
|
156
|
+
if (markResItems?.length) {
|
|
157
|
+
const newMedia = markResItems[0];
|
|
116
158
|
item["media"] = newMedia;
|
|
117
159
|
setMediaItems((previous) => {
|
|
118
160
|
const newState = { ...previous };
|
|
@@ -142,7 +184,7 @@ export function useMediaUploader({ defaultValues, mediaUploadSuccessStatus = Med
|
|
|
142
184
|
return newState;
|
|
143
185
|
});
|
|
144
186
|
if (onUploadSuccess) {
|
|
145
|
-
onUploadSuccess(currentValues);
|
|
187
|
+
await onUploadSuccess(currentValues);
|
|
146
188
|
}
|
|
147
189
|
return currentValues;
|
|
148
190
|
}
|
package/package.json
CHANGED
|
@@ -1,40 +1,42 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@susonwaiba/react-media-uploader",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"source": "src/index.ts",
|
|
5
|
-
"module": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"main": "dist/index.js",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
"
|
|
32
|
-
"react
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"@types/react
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@susonwaiba/react-media-uploader",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"source": "src/index.ts",
|
|
5
|
+
"module": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"dev": "rm -rf dist && tsc-watch --noClear --onSuccess tsc-alias",
|
|
10
|
+
"build": "rm -rf dist && tsc && tsc-alias"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/susonwaiba/react-media-uploader.git"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"react",
|
|
18
|
+
"media",
|
|
19
|
+
"uploader",
|
|
20
|
+
"nextjs",
|
|
21
|
+
"media-uploader",
|
|
22
|
+
"react-media-uploader"
|
|
23
|
+
],
|
|
24
|
+
"author": "Suson Waiba <susonwaiba@gmail.com> (https://susonwaiba.github.io)",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/susonwaiba/react-media-uploader/issues"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://github.com/susonwaiba/react-media-uploader#readme",
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"axios": ">=1",
|
|
32
|
+
"react": ">=18",
|
|
33
|
+
"react-dom": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/react": "^18",
|
|
37
|
+
"@types/react-dom": "^18",
|
|
38
|
+
"tsc-alias": "^1",
|
|
39
|
+
"tsc-watch": "^7.2.0",
|
|
40
|
+
"typescript": "^5"
|
|
41
|
+
}
|
|
42
|
+
}
|