dn-react-router-toolkit 0.1.4 → 0.1.5
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/file-kit/client/drop_file_input.d.mts +7 -4
- package/dist/file-kit/client/drop_file_input.d.ts +7 -4
- package/dist/file-kit/client/drop_file_input.js +241 -179
- package/dist/file-kit/client/drop_file_input.mjs +240 -177
- package/dist/file-kit/client/file_uploader.d.mts +1 -0
- package/dist/file-kit/client/file_uploader.d.ts +1 -0
- package/dist/file-kit/client/file_uploader.js +40 -33
- package/dist/file-kit/client/file_uploader.mjs +38 -33
- package/dist/file-kit/client/metadata.d.mts +3 -0
- package/dist/file-kit/client/metadata.d.ts +3 -0
- package/dist/file-kit/client/metadata.js +59 -0
- package/dist/file-kit/client/metadata.mjs +34 -0
- package/package.json +1 -1
|
@@ -11,18 +11,21 @@ type FileInputProps = Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTM
|
|
|
11
11
|
};
|
|
12
12
|
type FileItem<T> = {
|
|
13
13
|
key: string;
|
|
14
|
+
width?: number;
|
|
15
|
+
height?: number;
|
|
14
16
|
item?: T;
|
|
15
17
|
};
|
|
16
18
|
type Props<T> = {
|
|
17
19
|
defaultValue?: T | T[];
|
|
18
20
|
options?: FileUploaderOptions;
|
|
19
|
-
uploadFile?: (file: File, options?: FileUploaderOptions) => Promise<T>;
|
|
20
21
|
onFileInput?: (files: File[]) => void;
|
|
21
22
|
onFileUploaded?: (file: T) => Promise<void>;
|
|
22
|
-
onChange?: (files:
|
|
23
|
+
onChange?: (files: T[]) => void;
|
|
23
24
|
limit?: number;
|
|
24
25
|
};
|
|
25
|
-
declare function
|
|
26
|
+
declare function createUseDropFileInput<T>({ uploadFile, }: {
|
|
27
|
+
uploadFile: (file: File, options?: FileUploaderOptions) => Promise<T>;
|
|
28
|
+
}): ({ defaultValue, options, onChange, onFileInput, onFileUploaded, limit, }?: Props<T>) => {
|
|
26
29
|
fileIds: string[];
|
|
27
30
|
files: FileItem<T>[];
|
|
28
31
|
setFiles: React.Dispatch<React.SetStateAction<FileItem<T>[]>>;
|
|
@@ -30,4 +33,4 @@ declare function useDropFileInput<T>({ defaultValue, options, uploadFile, onFile
|
|
|
30
33
|
};
|
|
31
34
|
declare function DropFileMessageBox(): React.JSX.Element;
|
|
32
35
|
|
|
33
|
-
export { DropFileMessageBox, type FileInputProps, type FileItem,
|
|
36
|
+
export { DropFileMessageBox, type FileInputProps, type FileItem, createUseDropFileInput as default };
|
|
@@ -11,18 +11,21 @@ type FileInputProps = Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTM
|
|
|
11
11
|
};
|
|
12
12
|
type FileItem<T> = {
|
|
13
13
|
key: string;
|
|
14
|
+
width?: number;
|
|
15
|
+
height?: number;
|
|
14
16
|
item?: T;
|
|
15
17
|
};
|
|
16
18
|
type Props<T> = {
|
|
17
19
|
defaultValue?: T | T[];
|
|
18
20
|
options?: FileUploaderOptions;
|
|
19
|
-
uploadFile?: (file: File, options?: FileUploaderOptions) => Promise<T>;
|
|
20
21
|
onFileInput?: (files: File[]) => void;
|
|
21
22
|
onFileUploaded?: (file: T) => Promise<void>;
|
|
22
|
-
onChange?: (files:
|
|
23
|
+
onChange?: (files: T[]) => void;
|
|
23
24
|
limit?: number;
|
|
24
25
|
};
|
|
25
|
-
declare function
|
|
26
|
+
declare function createUseDropFileInput<T>({ uploadFile, }: {
|
|
27
|
+
uploadFile: (file: File, options?: FileUploaderOptions) => Promise<T>;
|
|
28
|
+
}): ({ defaultValue, options, onChange, onFileInput, onFileUploaded, limit, }?: Props<T>) => {
|
|
26
29
|
fileIds: string[];
|
|
27
30
|
files: FileItem<T>[];
|
|
28
31
|
setFiles: React.Dispatch<React.SetStateAction<FileItem<T>[]>>;
|
|
@@ -30,4 +33,4 @@ declare function useDropFileInput<T>({ defaultValue, options, uploadFile, onFile
|
|
|
30
33
|
};
|
|
31
34
|
declare function DropFileMessageBox(): React.JSX.Element;
|
|
32
35
|
|
|
33
|
-
export { DropFileMessageBox, type FileInputProps, type FileItem,
|
|
36
|
+
export { DropFileMessageBox, type FileInputProps, type FileItem, createUseDropFileInput as default };
|
|
@@ -31,8 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var drop_file_input_exports = {};
|
|
32
32
|
__export(drop_file_input_exports, {
|
|
33
33
|
DropFileMessageBox: () => DropFileMessageBox,
|
|
34
|
-
default: () =>
|
|
35
|
-
useDropFileInput: () => useDropFileInput
|
|
34
|
+
default: () => createUseDropFileInput
|
|
36
35
|
});
|
|
37
36
|
module.exports = __toCommonJS(drop_file_input_exports);
|
|
38
37
|
var import_react = __toESM(require("react"));
|
|
@@ -43,193 +42,256 @@ function cn(...classes) {
|
|
|
43
42
|
return classes.filter(Boolean).join(" ").trim();
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
// src/file-kit/client/
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return {
|
|
58
|
-
key: (0, import_uuid.v4)(),
|
|
59
|
-
item: v
|
|
45
|
+
// src/file-kit/client/metadata.ts
|
|
46
|
+
function generateMetadata(blob) {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
if (blob.type.startsWith("image/")) {
|
|
49
|
+
const img = new Image();
|
|
50
|
+
img.src = URL.createObjectURL(blob);
|
|
51
|
+
img.onload = () => {
|
|
52
|
+
resolve({
|
|
53
|
+
width: img.width,
|
|
54
|
+
height: img.height
|
|
55
|
+
});
|
|
60
56
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (f.key === fileItem.key) {
|
|
124
|
-
return {
|
|
125
|
-
...f,
|
|
126
|
-
item
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
return f;
|
|
130
|
-
})
|
|
131
|
-
);
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
[props.accept]
|
|
136
|
-
);
|
|
137
|
-
const handleDrop = (0, import_react.useCallback)(
|
|
138
|
-
(e) => {
|
|
57
|
+
img.onerror = reject;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (blob.type.startsWith("video/")) {
|
|
61
|
+
const video = document.createElement("video");
|
|
62
|
+
video.src = URL.createObjectURL(blob);
|
|
63
|
+
video.onloadedmetadata = () => {
|
|
64
|
+
resolve({
|
|
65
|
+
width: video.videoWidth,
|
|
66
|
+
height: video.videoHeight,
|
|
67
|
+
duration: video.duration
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
video.onerror = reject;
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
resolve({});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/file-kit/client/drop_file_input.tsx
|
|
78
|
+
function createUseDropFileInput({
|
|
79
|
+
uploadFile
|
|
80
|
+
}) {
|
|
81
|
+
return function useDropFileInput({
|
|
82
|
+
defaultValue,
|
|
83
|
+
options,
|
|
84
|
+
onChange,
|
|
85
|
+
onFileInput,
|
|
86
|
+
onFileUploaded,
|
|
87
|
+
limit
|
|
88
|
+
} = {}) {
|
|
89
|
+
const [files, setFiles] = (0, import_react.useState)(
|
|
90
|
+
defaultValue ? (Array.isArray(defaultValue) ? defaultValue : [defaultValue]).map((v) => {
|
|
91
|
+
return {
|
|
92
|
+
key: (0, import_uuid.v4)(),
|
|
93
|
+
item: v
|
|
94
|
+
};
|
|
95
|
+
}).slice(0, limit ? limit : Infinity) : []
|
|
96
|
+
);
|
|
97
|
+
const fileRef = (0, import_react.useRef)([]);
|
|
98
|
+
(0, import_react.useEffect)(() => {
|
|
99
|
+
fileRef.current = files;
|
|
100
|
+
onChange?.(files.map((f) => f.item).filter(Boolean));
|
|
101
|
+
}, [files]);
|
|
102
|
+
const Component = (0, import_react.useCallback)(
|
|
103
|
+
function Component2({
|
|
104
|
+
className,
|
|
105
|
+
container = "border border-dashed border-neutral-300 rounded flex items-center justify-center",
|
|
106
|
+
draggingClassName,
|
|
107
|
+
name,
|
|
108
|
+
hideMessage = false,
|
|
109
|
+
children,
|
|
110
|
+
...props
|
|
111
|
+
}) {
|
|
112
|
+
const [isDragging, setIsDragging] = (0, import_react.useState)(false);
|
|
113
|
+
const handleDragEnter = (0, import_react.useCallback)((e) => {
|
|
114
|
+
e.preventDefault();
|
|
115
|
+
e.stopPropagation();
|
|
116
|
+
setIsDragging(true);
|
|
117
|
+
}, []);
|
|
118
|
+
const handleDragLeave = (0, import_react.useCallback)((e) => {
|
|
139
119
|
e.preventDefault();
|
|
140
120
|
e.stopPropagation();
|
|
141
121
|
setIsDragging(false);
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
handleClick();
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
[handleClick]
|
|
160
|
-
);
|
|
161
|
-
const handleChange = (0, import_react.useCallback)(
|
|
162
|
-
(e) => {
|
|
163
|
-
if (e.target.files && e.target.files.length > 0) {
|
|
164
|
-
handleFiles(Array.from(e.target.files));
|
|
165
|
-
e.target.value = "";
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
|
-
[handleFiles]
|
|
169
|
-
);
|
|
170
|
-
return /* @__PURE__ */ import_react.default.createElement(
|
|
171
|
-
"div",
|
|
172
|
-
{
|
|
173
|
-
className: cn(
|
|
174
|
-
className,
|
|
175
|
-
container,
|
|
176
|
-
draggingClassName?.(isDragging) || (isDragging ? "bg-neutral-300/25" : "hover:bg-neutral-300/25"),
|
|
177
|
-
"transition-colors cursor-pointer"
|
|
178
|
-
),
|
|
179
|
-
onDragEnter: handleDragEnter,
|
|
180
|
-
onDragLeave: handleDragLeave,
|
|
181
|
-
onDragOver: handleDragOver,
|
|
182
|
-
onDrop: handleDrop,
|
|
183
|
-
onClick: handleClick,
|
|
184
|
-
onChange: handleChange,
|
|
185
|
-
onKeyDown: handleKeyDown,
|
|
186
|
-
tabIndex: 0,
|
|
187
|
-
role: "button"
|
|
188
|
-
},
|
|
189
|
-
/* @__PURE__ */ import_react.default.createElement("input", { ...props, defaultValue: "", type: "file", hidden: true, ref: inputRef }),
|
|
190
|
-
/* @__PURE__ */ import_react.default.createElement(
|
|
191
|
-
"input",
|
|
192
|
-
{
|
|
193
|
-
name,
|
|
194
|
-
hidden: true,
|
|
195
|
-
readOnly: true,
|
|
196
|
-
value: files.map((file) => {
|
|
197
|
-
if (file.item && typeof file.item === "object" && "id" in file.item) {
|
|
198
|
-
return file.item.id;
|
|
122
|
+
}, []);
|
|
123
|
+
const handleDragOver = (0, import_react.useCallback)((e) => {
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
e.stopPropagation();
|
|
126
|
+
}, []);
|
|
127
|
+
const handleFiles = (0, import_react.useCallback)(
|
|
128
|
+
async (files2) => {
|
|
129
|
+
if (limit && fileRef.current.length >= limit) {
|
|
130
|
+
alert(`\uD30C\uC77C\uC740 \uCD5C\uB300 ${limit}\uAC1C \uC5C5\uB85C\uB4DC\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const filteredFiles = files2.filter((file) => {
|
|
134
|
+
if (!props.accept) {
|
|
135
|
+
return true;
|
|
199
136
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
137
|
+
const accepts = props.accept.split(",");
|
|
138
|
+
for (const accept of accepts) {
|
|
139
|
+
const trimmedAccept = accept.trim();
|
|
140
|
+
if (file.type === trimmedAccept || file.type.endsWith(trimmedAccept) || file.name.endsWith(trimmedAccept)) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
if (trimmedAccept.endsWith("/*")) {
|
|
144
|
+
const baseType = trimmedAccept.replace("/*", "");
|
|
145
|
+
if (file.type.startsWith(baseType + "/")) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return false;
|
|
151
|
+
});
|
|
152
|
+
if (files2.length !== filteredFiles.length) {
|
|
153
|
+
alert(`${props.accept} \uD615\uC2DD\uC758 \uD30C\uC77C\uB9CC \uC5C5\uB85C\uB4DC\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`);
|
|
154
|
+
}
|
|
155
|
+
const limitedFiles = filteredFiles.slice(
|
|
156
|
+
0,
|
|
157
|
+
limit ? limit - fileRef.current.length : Infinity
|
|
158
|
+
);
|
|
159
|
+
if (limitedFiles.length === 0) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (onFileInput) {
|
|
163
|
+
onFileInput(limitedFiles);
|
|
164
|
+
}
|
|
165
|
+
for (const file of limitedFiles) {
|
|
166
|
+
const { width, height } = await generateMetadata(file);
|
|
167
|
+
const fileItem = {
|
|
168
|
+
key: (0, import_uuid.v4)(),
|
|
169
|
+
width: Number(width) || void 0,
|
|
170
|
+
height: Number(height) || void 0
|
|
171
|
+
};
|
|
172
|
+
setFiles((prevFiles) => [...prevFiles, fileItem]);
|
|
173
|
+
uploadFile?.(file, options).then(async (item) => {
|
|
174
|
+
await onFileUploaded?.(item);
|
|
175
|
+
setFiles(
|
|
176
|
+
(prevFiles) => prevFiles.map((f) => {
|
|
177
|
+
if (f.key === fileItem.key) {
|
|
178
|
+
return {
|
|
179
|
+
...f,
|
|
180
|
+
item
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
return f;
|
|
184
|
+
})
|
|
185
|
+
);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
[props.accept]
|
|
190
|
+
);
|
|
191
|
+
const handleDrop = (0, import_react.useCallback)(
|
|
192
|
+
(e) => {
|
|
193
|
+
e.preventDefault();
|
|
194
|
+
e.stopPropagation();
|
|
195
|
+
setIsDragging(false);
|
|
196
|
+
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
197
|
+
handleFiles(Array.from(e.dataTransfer.files));
|
|
198
|
+
e.dataTransfer.clearData();
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
[handleFiles]
|
|
202
|
+
);
|
|
203
|
+
const inputRef = (0, import_react.useRef)(null);
|
|
204
|
+
const handleClick = (0, import_react.useCallback)(() => {
|
|
205
|
+
inputRef.current?.click();
|
|
206
|
+
}, []);
|
|
207
|
+
const handleKeyDown = (0, import_react.useCallback)(
|
|
208
|
+
(e) => {
|
|
209
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
210
|
+
handleClick();
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
[handleClick]
|
|
214
|
+
);
|
|
215
|
+
const handleChange = (0, import_react.useCallback)(
|
|
216
|
+
(e) => {
|
|
217
|
+
if (e.target.files && e.target.files.length > 0) {
|
|
218
|
+
handleFiles(Array.from(e.target.files));
|
|
219
|
+
e.target.value = "";
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
[handleFiles]
|
|
223
|
+
);
|
|
224
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
225
|
+
"div",
|
|
226
|
+
{
|
|
227
|
+
className: cn(
|
|
228
|
+
className,
|
|
229
|
+
container,
|
|
230
|
+
draggingClassName?.(isDragging) || (isDragging ? "bg-neutral-300/25" : "hover:bg-neutral-300/25"),
|
|
231
|
+
"transition-colors cursor-pointer"
|
|
232
|
+
),
|
|
233
|
+
onDragEnter: handleDragEnter,
|
|
234
|
+
onDragLeave: handleDragLeave,
|
|
235
|
+
onDragOver: handleDragOver,
|
|
236
|
+
onDrop: handleDrop,
|
|
237
|
+
onClick: handleClick,
|
|
238
|
+
onChange: handleChange,
|
|
239
|
+
onKeyDown: handleKeyDown,
|
|
240
|
+
tabIndex: 0,
|
|
241
|
+
role: "button"
|
|
242
|
+
},
|
|
243
|
+
/* @__PURE__ */ import_react.default.createElement(
|
|
244
|
+
"input",
|
|
245
|
+
{
|
|
246
|
+
...props,
|
|
247
|
+
defaultValue: "",
|
|
248
|
+
type: "file",
|
|
249
|
+
hidden: true,
|
|
250
|
+
ref: inputRef
|
|
251
|
+
}
|
|
252
|
+
),
|
|
253
|
+
/* @__PURE__ */ import_react.default.createElement(
|
|
254
|
+
"input",
|
|
255
|
+
{
|
|
256
|
+
name,
|
|
257
|
+
hidden: true,
|
|
258
|
+
readOnly: true,
|
|
259
|
+
value: files.map((file) => {
|
|
260
|
+
if (file.item && typeof file.item === "object" && "id" in file.item) {
|
|
261
|
+
return file.item.id;
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}).filter(Boolean).join(",")
|
|
265
|
+
}
|
|
266
|
+
),
|
|
267
|
+
children || !(hideMessage && !isDragging) && /* @__PURE__ */ import_react.default.createElement(DropFileMessageBox, null)
|
|
268
|
+
);
|
|
269
|
+
},
|
|
270
|
+
[limit, fileRef, files, options, uploadFile, onFileInput, onFileUploaded]
|
|
271
|
+
);
|
|
272
|
+
const loadedFileIds = files.map((file) => {
|
|
273
|
+
if (file.item && typeof file.item === "object" && "id" in file.item) {
|
|
274
|
+
return file.item.id;
|
|
275
|
+
}
|
|
276
|
+
return null;
|
|
277
|
+
}).filter(Boolean);
|
|
278
|
+
const loadedFileIdsString = loadedFileIds.join(",");
|
|
279
|
+
const fileIds = (0, import_react.useMemo)(
|
|
280
|
+
() => loadedFileIdsString.split(",").filter(Boolean),
|
|
281
|
+
[loadedFileIdsString]
|
|
282
|
+
);
|
|
283
|
+
return {
|
|
284
|
+
fileIds,
|
|
285
|
+
files,
|
|
286
|
+
setFiles,
|
|
287
|
+
Component
|
|
288
|
+
};
|
|
225
289
|
};
|
|
226
290
|
}
|
|
227
291
|
function DropFileMessageBox() {
|
|
228
292
|
return /* @__PURE__ */ import_react.default.createElement("div", { className: "text-sm pointer-events-none flex justify-center items-center" }, /* @__PURE__ */ import_react.default.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ import_react.default.createElement("span", null, "\uD30C\uC77C\uC744 \uC5EC\uAE30\uB85C \uB04C\uC5B4\uB2E4 \uB193\uAC70\uB098 \uD074\uB9AD\uD574\uC11C \uC120\uD0DD\uD574 \uC8FC\uC138\uC694")));
|
|
229
293
|
}
|
|
230
|
-
var drop_file_input_default = useDropFileInput;
|
|
231
294
|
// Annotate the CommonJS export names for ESM import in node:
|
|
232
295
|
0 && (module.exports = {
|
|
233
|
-
DropFileMessageBox
|
|
234
|
-
useDropFileInput
|
|
296
|
+
DropFileMessageBox
|
|
235
297
|
});
|
|
@@ -13,193 +13,256 @@ function cn(...classes) {
|
|
|
13
13
|
return classes.filter(Boolean).join(" ").trim();
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
// src/file-kit/client/
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
key: v4(),
|
|
29
|
-
item: v
|
|
16
|
+
// src/file-kit/client/metadata.ts
|
|
17
|
+
function generateMetadata(blob) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
if (blob.type.startsWith("image/")) {
|
|
20
|
+
const img = new Image();
|
|
21
|
+
img.src = URL.createObjectURL(blob);
|
|
22
|
+
img.onload = () => {
|
|
23
|
+
resolve({
|
|
24
|
+
width: img.width,
|
|
25
|
+
height: img.height
|
|
26
|
+
});
|
|
30
27
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (f.key === fileItem.key) {
|
|
94
|
-
return {
|
|
95
|
-
...f,
|
|
96
|
-
item
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
return f;
|
|
100
|
-
})
|
|
101
|
-
);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
[props.accept]
|
|
106
|
-
);
|
|
107
|
-
const handleDrop = useCallback(
|
|
108
|
-
(e) => {
|
|
28
|
+
img.onerror = reject;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (blob.type.startsWith("video/")) {
|
|
32
|
+
const video = document.createElement("video");
|
|
33
|
+
video.src = URL.createObjectURL(blob);
|
|
34
|
+
video.onloadedmetadata = () => {
|
|
35
|
+
resolve({
|
|
36
|
+
width: video.videoWidth,
|
|
37
|
+
height: video.videoHeight,
|
|
38
|
+
duration: video.duration
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
video.onerror = reject;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
resolve({});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/file-kit/client/drop_file_input.tsx
|
|
49
|
+
function createUseDropFileInput({
|
|
50
|
+
uploadFile
|
|
51
|
+
}) {
|
|
52
|
+
return function useDropFileInput({
|
|
53
|
+
defaultValue,
|
|
54
|
+
options,
|
|
55
|
+
onChange,
|
|
56
|
+
onFileInput,
|
|
57
|
+
onFileUploaded,
|
|
58
|
+
limit
|
|
59
|
+
} = {}) {
|
|
60
|
+
const [files, setFiles] = useState(
|
|
61
|
+
defaultValue ? (Array.isArray(defaultValue) ? defaultValue : [defaultValue]).map((v) => {
|
|
62
|
+
return {
|
|
63
|
+
key: v4(),
|
|
64
|
+
item: v
|
|
65
|
+
};
|
|
66
|
+
}).slice(0, limit ? limit : Infinity) : []
|
|
67
|
+
);
|
|
68
|
+
const fileRef = useRef([]);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
fileRef.current = files;
|
|
71
|
+
onChange?.(files.map((f) => f.item).filter(Boolean));
|
|
72
|
+
}, [files]);
|
|
73
|
+
const Component = useCallback(
|
|
74
|
+
function Component2({
|
|
75
|
+
className,
|
|
76
|
+
container = "border border-dashed border-neutral-300 rounded flex items-center justify-center",
|
|
77
|
+
draggingClassName,
|
|
78
|
+
name,
|
|
79
|
+
hideMessage = false,
|
|
80
|
+
children,
|
|
81
|
+
...props
|
|
82
|
+
}) {
|
|
83
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
84
|
+
const handleDragEnter = useCallback((e) => {
|
|
85
|
+
e.preventDefault();
|
|
86
|
+
e.stopPropagation();
|
|
87
|
+
setIsDragging(true);
|
|
88
|
+
}, []);
|
|
89
|
+
const handleDragLeave = useCallback((e) => {
|
|
109
90
|
e.preventDefault();
|
|
110
91
|
e.stopPropagation();
|
|
111
92
|
setIsDragging(false);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
handleClick();
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
[handleClick]
|
|
130
|
-
);
|
|
131
|
-
const handleChange = useCallback(
|
|
132
|
-
(e) => {
|
|
133
|
-
if (e.target.files && e.target.files.length > 0) {
|
|
134
|
-
handleFiles(Array.from(e.target.files));
|
|
135
|
-
e.target.value = "";
|
|
136
|
-
}
|
|
137
|
-
},
|
|
138
|
-
[handleFiles]
|
|
139
|
-
);
|
|
140
|
-
return /* @__PURE__ */ React.createElement(
|
|
141
|
-
"div",
|
|
142
|
-
{
|
|
143
|
-
className: cn(
|
|
144
|
-
className,
|
|
145
|
-
container,
|
|
146
|
-
draggingClassName?.(isDragging) || (isDragging ? "bg-neutral-300/25" : "hover:bg-neutral-300/25"),
|
|
147
|
-
"transition-colors cursor-pointer"
|
|
148
|
-
),
|
|
149
|
-
onDragEnter: handleDragEnter,
|
|
150
|
-
onDragLeave: handleDragLeave,
|
|
151
|
-
onDragOver: handleDragOver,
|
|
152
|
-
onDrop: handleDrop,
|
|
153
|
-
onClick: handleClick,
|
|
154
|
-
onChange: handleChange,
|
|
155
|
-
onKeyDown: handleKeyDown,
|
|
156
|
-
tabIndex: 0,
|
|
157
|
-
role: "button"
|
|
158
|
-
},
|
|
159
|
-
/* @__PURE__ */ React.createElement("input", { ...props, defaultValue: "", type: "file", hidden: true, ref: inputRef }),
|
|
160
|
-
/* @__PURE__ */ React.createElement(
|
|
161
|
-
"input",
|
|
162
|
-
{
|
|
163
|
-
name,
|
|
164
|
-
hidden: true,
|
|
165
|
-
readOnly: true,
|
|
166
|
-
value: files.map((file) => {
|
|
167
|
-
if (file.item && typeof file.item === "object" && "id" in file.item) {
|
|
168
|
-
return file.item.id;
|
|
93
|
+
}, []);
|
|
94
|
+
const handleDragOver = useCallback((e) => {
|
|
95
|
+
e.preventDefault();
|
|
96
|
+
e.stopPropagation();
|
|
97
|
+
}, []);
|
|
98
|
+
const handleFiles = useCallback(
|
|
99
|
+
async (files2) => {
|
|
100
|
+
if (limit && fileRef.current.length >= limit) {
|
|
101
|
+
alert(`\uD30C\uC77C\uC740 \uCD5C\uB300 ${limit}\uAC1C \uC5C5\uB85C\uB4DC\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const filteredFiles = files2.filter((file) => {
|
|
105
|
+
if (!props.accept) {
|
|
106
|
+
return true;
|
|
169
107
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
108
|
+
const accepts = props.accept.split(",");
|
|
109
|
+
for (const accept of accepts) {
|
|
110
|
+
const trimmedAccept = accept.trim();
|
|
111
|
+
if (file.type === trimmedAccept || file.type.endsWith(trimmedAccept) || file.name.endsWith(trimmedAccept)) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
if (trimmedAccept.endsWith("/*")) {
|
|
115
|
+
const baseType = trimmedAccept.replace("/*", "");
|
|
116
|
+
if (file.type.startsWith(baseType + "/")) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return false;
|
|
122
|
+
});
|
|
123
|
+
if (files2.length !== filteredFiles.length) {
|
|
124
|
+
alert(`${props.accept} \uD615\uC2DD\uC758 \uD30C\uC77C\uB9CC \uC5C5\uB85C\uB4DC\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`);
|
|
125
|
+
}
|
|
126
|
+
const limitedFiles = filteredFiles.slice(
|
|
127
|
+
0,
|
|
128
|
+
limit ? limit - fileRef.current.length : Infinity
|
|
129
|
+
);
|
|
130
|
+
if (limitedFiles.length === 0) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (onFileInput) {
|
|
134
|
+
onFileInput(limitedFiles);
|
|
135
|
+
}
|
|
136
|
+
for (const file of limitedFiles) {
|
|
137
|
+
const { width, height } = await generateMetadata(file);
|
|
138
|
+
const fileItem = {
|
|
139
|
+
key: v4(),
|
|
140
|
+
width: Number(width) || void 0,
|
|
141
|
+
height: Number(height) || void 0
|
|
142
|
+
};
|
|
143
|
+
setFiles((prevFiles) => [...prevFiles, fileItem]);
|
|
144
|
+
uploadFile?.(file, options).then(async (item) => {
|
|
145
|
+
await onFileUploaded?.(item);
|
|
146
|
+
setFiles(
|
|
147
|
+
(prevFiles) => prevFiles.map((f) => {
|
|
148
|
+
if (f.key === fileItem.key) {
|
|
149
|
+
return {
|
|
150
|
+
...f,
|
|
151
|
+
item
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return f;
|
|
155
|
+
})
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
[props.accept]
|
|
161
|
+
);
|
|
162
|
+
const handleDrop = useCallback(
|
|
163
|
+
(e) => {
|
|
164
|
+
e.preventDefault();
|
|
165
|
+
e.stopPropagation();
|
|
166
|
+
setIsDragging(false);
|
|
167
|
+
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
|
|
168
|
+
handleFiles(Array.from(e.dataTransfer.files));
|
|
169
|
+
e.dataTransfer.clearData();
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
[handleFiles]
|
|
173
|
+
);
|
|
174
|
+
const inputRef = useRef(null);
|
|
175
|
+
const handleClick = useCallback(() => {
|
|
176
|
+
inputRef.current?.click();
|
|
177
|
+
}, []);
|
|
178
|
+
const handleKeyDown = useCallback(
|
|
179
|
+
(e) => {
|
|
180
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
181
|
+
handleClick();
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
[handleClick]
|
|
185
|
+
);
|
|
186
|
+
const handleChange = useCallback(
|
|
187
|
+
(e) => {
|
|
188
|
+
if (e.target.files && e.target.files.length > 0) {
|
|
189
|
+
handleFiles(Array.from(e.target.files));
|
|
190
|
+
e.target.value = "";
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
[handleFiles]
|
|
194
|
+
);
|
|
195
|
+
return /* @__PURE__ */ React.createElement(
|
|
196
|
+
"div",
|
|
197
|
+
{
|
|
198
|
+
className: cn(
|
|
199
|
+
className,
|
|
200
|
+
container,
|
|
201
|
+
draggingClassName?.(isDragging) || (isDragging ? "bg-neutral-300/25" : "hover:bg-neutral-300/25"),
|
|
202
|
+
"transition-colors cursor-pointer"
|
|
203
|
+
),
|
|
204
|
+
onDragEnter: handleDragEnter,
|
|
205
|
+
onDragLeave: handleDragLeave,
|
|
206
|
+
onDragOver: handleDragOver,
|
|
207
|
+
onDrop: handleDrop,
|
|
208
|
+
onClick: handleClick,
|
|
209
|
+
onChange: handleChange,
|
|
210
|
+
onKeyDown: handleKeyDown,
|
|
211
|
+
tabIndex: 0,
|
|
212
|
+
role: "button"
|
|
213
|
+
},
|
|
214
|
+
/* @__PURE__ */ React.createElement(
|
|
215
|
+
"input",
|
|
216
|
+
{
|
|
217
|
+
...props,
|
|
218
|
+
defaultValue: "",
|
|
219
|
+
type: "file",
|
|
220
|
+
hidden: true,
|
|
221
|
+
ref: inputRef
|
|
222
|
+
}
|
|
223
|
+
),
|
|
224
|
+
/* @__PURE__ */ React.createElement(
|
|
225
|
+
"input",
|
|
226
|
+
{
|
|
227
|
+
name,
|
|
228
|
+
hidden: true,
|
|
229
|
+
readOnly: true,
|
|
230
|
+
value: files.map((file) => {
|
|
231
|
+
if (file.item && typeof file.item === "object" && "id" in file.item) {
|
|
232
|
+
return file.item.id;
|
|
233
|
+
}
|
|
234
|
+
return null;
|
|
235
|
+
}).filter(Boolean).join(",")
|
|
236
|
+
}
|
|
237
|
+
),
|
|
238
|
+
children || !(hideMessage && !isDragging) && /* @__PURE__ */ React.createElement(DropFileMessageBox, null)
|
|
239
|
+
);
|
|
240
|
+
},
|
|
241
|
+
[limit, fileRef, files, options, uploadFile, onFileInput, onFileUploaded]
|
|
242
|
+
);
|
|
243
|
+
const loadedFileIds = files.map((file) => {
|
|
244
|
+
if (file.item && typeof file.item === "object" && "id" in file.item) {
|
|
245
|
+
return file.item.id;
|
|
246
|
+
}
|
|
247
|
+
return null;
|
|
248
|
+
}).filter(Boolean);
|
|
249
|
+
const loadedFileIdsString = loadedFileIds.join(",");
|
|
250
|
+
const fileIds = useMemo(
|
|
251
|
+
() => loadedFileIdsString.split(",").filter(Boolean),
|
|
252
|
+
[loadedFileIdsString]
|
|
253
|
+
);
|
|
254
|
+
return {
|
|
255
|
+
fileIds,
|
|
256
|
+
files,
|
|
257
|
+
setFiles,
|
|
258
|
+
Component
|
|
259
|
+
};
|
|
195
260
|
};
|
|
196
261
|
}
|
|
197
262
|
function DropFileMessageBox() {
|
|
198
263
|
return /* @__PURE__ */ React.createElement("div", { className: "text-sm pointer-events-none flex justify-center items-center" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-col items-center" }, /* @__PURE__ */ React.createElement("span", null, "\uD30C\uC77C\uC744 \uC5EC\uAE30\uB85C \uB04C\uC5B4\uB2E4 \uB193\uAC70\uB098 \uD074\uB9AD\uD574\uC11C \uC120\uD0DD\uD574 \uC8FC\uC138\uC694")));
|
|
199
264
|
}
|
|
200
|
-
var drop_file_input_default = useDropFileInput;
|
|
201
265
|
export {
|
|
202
266
|
DropFileMessageBox,
|
|
203
|
-
|
|
204
|
-
useDropFileInput
|
|
267
|
+
createUseDropFileInput as default
|
|
205
268
|
};
|
|
@@ -23,6 +23,40 @@ __export(file_uploader_exports, {
|
|
|
23
23
|
FileUploader: () => FileUploader
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(file_uploader_exports);
|
|
26
|
+
|
|
27
|
+
// src/file-kit/client/metadata.ts
|
|
28
|
+
function generateMetadata(blob) {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
if (blob.type.startsWith("image/")) {
|
|
31
|
+
const img = new Image();
|
|
32
|
+
img.src = URL.createObjectURL(blob);
|
|
33
|
+
img.onload = () => {
|
|
34
|
+
resolve({
|
|
35
|
+
width: img.width,
|
|
36
|
+
height: img.height
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
img.onerror = reject;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (blob.type.startsWith("video/")) {
|
|
43
|
+
const video = document.createElement("video");
|
|
44
|
+
video.src = URL.createObjectURL(blob);
|
|
45
|
+
video.onloadedmetadata = () => {
|
|
46
|
+
resolve({
|
|
47
|
+
width: video.videoWidth,
|
|
48
|
+
height: video.videoHeight,
|
|
49
|
+
duration: video.duration
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
video.onerror = reject;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
resolve({});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/file-kit/client/file_uploader.ts
|
|
26
60
|
var FileUploader = class {
|
|
27
61
|
endpoint;
|
|
28
62
|
constructor(endpoint = "/api/files") {
|
|
@@ -42,45 +76,18 @@ var FileUploader = class {
|
|
|
42
76
|
}
|
|
43
77
|
async uploadBlob(blob, name = "blob", options = {}) {
|
|
44
78
|
const { type, size } = blob;
|
|
45
|
-
const metadataForMedia = await
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
img.onload = () => {
|
|
51
|
-
resolve({
|
|
52
|
-
...options.metadata,
|
|
53
|
-
width: img.width,
|
|
54
|
-
height: img.height
|
|
55
|
-
});
|
|
56
|
-
};
|
|
57
|
-
img.onerror = reject;
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
if (blob.type.startsWith("video/")) {
|
|
61
|
-
const video = document.createElement("video");
|
|
62
|
-
video.src = URL.createObjectURL(blob);
|
|
63
|
-
video.onloadedmetadata = () => {
|
|
64
|
-
resolve({
|
|
65
|
-
...options.metadata,
|
|
66
|
-
width: video.videoWidth,
|
|
67
|
-
height: video.videoHeight,
|
|
68
|
-
duration: video.duration
|
|
69
|
-
});
|
|
70
|
-
};
|
|
71
|
-
video.onerror = reject;
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
resolve(options.metadata || {});
|
|
75
|
-
}
|
|
76
|
-
);
|
|
79
|
+
const metadataForMedia = await generateMetadata(blob);
|
|
80
|
+
const metadata = {
|
|
81
|
+
...metadataForMedia,
|
|
82
|
+
...options.metadata
|
|
83
|
+
};
|
|
77
84
|
const res1 = await fetch(this.endpoint, {
|
|
78
85
|
method: "POST",
|
|
79
86
|
body: JSON.stringify({
|
|
80
87
|
name: name.replace(/ /g, "_"),
|
|
81
88
|
type,
|
|
82
89
|
size,
|
|
83
|
-
metadata
|
|
90
|
+
metadata
|
|
84
91
|
})
|
|
85
92
|
});
|
|
86
93
|
if (!res1.ok) {
|
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
// src/file-kit/client/metadata.ts
|
|
2
|
+
function generateMetadata(blob) {
|
|
3
|
+
return new Promise((resolve, reject) => {
|
|
4
|
+
if (blob.type.startsWith("image/")) {
|
|
5
|
+
const img = new Image();
|
|
6
|
+
img.src = URL.createObjectURL(blob);
|
|
7
|
+
img.onload = () => {
|
|
8
|
+
resolve({
|
|
9
|
+
width: img.width,
|
|
10
|
+
height: img.height
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
img.onerror = reject;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (blob.type.startsWith("video/")) {
|
|
17
|
+
const video = document.createElement("video");
|
|
18
|
+
video.src = URL.createObjectURL(blob);
|
|
19
|
+
video.onloadedmetadata = () => {
|
|
20
|
+
resolve({
|
|
21
|
+
width: video.videoWidth,
|
|
22
|
+
height: video.videoHeight,
|
|
23
|
+
duration: video.duration
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
video.onerror = reject;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
resolve({});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
1
33
|
// src/file-kit/client/file_uploader.ts
|
|
2
34
|
var FileUploader = class {
|
|
3
35
|
endpoint;
|
|
@@ -18,45 +50,18 @@ var FileUploader = class {
|
|
|
18
50
|
}
|
|
19
51
|
async uploadBlob(blob, name = "blob", options = {}) {
|
|
20
52
|
const { type, size } = blob;
|
|
21
|
-
const metadataForMedia = await
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
img.onload = () => {
|
|
27
|
-
resolve({
|
|
28
|
-
...options.metadata,
|
|
29
|
-
width: img.width,
|
|
30
|
-
height: img.height
|
|
31
|
-
});
|
|
32
|
-
};
|
|
33
|
-
img.onerror = reject;
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if (blob.type.startsWith("video/")) {
|
|
37
|
-
const video = document.createElement("video");
|
|
38
|
-
video.src = URL.createObjectURL(blob);
|
|
39
|
-
video.onloadedmetadata = () => {
|
|
40
|
-
resolve({
|
|
41
|
-
...options.metadata,
|
|
42
|
-
width: video.videoWidth,
|
|
43
|
-
height: video.videoHeight,
|
|
44
|
-
duration: video.duration
|
|
45
|
-
});
|
|
46
|
-
};
|
|
47
|
-
video.onerror = reject;
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
resolve(options.metadata || {});
|
|
51
|
-
}
|
|
52
|
-
);
|
|
53
|
+
const metadataForMedia = await generateMetadata(blob);
|
|
54
|
+
const metadata = {
|
|
55
|
+
...metadataForMedia,
|
|
56
|
+
...options.metadata
|
|
57
|
+
};
|
|
53
58
|
const res1 = await fetch(this.endpoint, {
|
|
54
59
|
method: "POST",
|
|
55
60
|
body: JSON.stringify({
|
|
56
61
|
name: name.replace(/ /g, "_"),
|
|
57
62
|
type,
|
|
58
63
|
size,
|
|
59
|
-
metadata
|
|
64
|
+
metadata
|
|
60
65
|
})
|
|
61
66
|
});
|
|
62
67
|
if (!res1.ok) {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/file-kit/client/metadata.ts
|
|
21
|
+
var metadata_exports = {};
|
|
22
|
+
__export(metadata_exports, {
|
|
23
|
+
generateMetadata: () => generateMetadata
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(metadata_exports);
|
|
26
|
+
function generateMetadata(blob) {
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
if (blob.type.startsWith("image/")) {
|
|
29
|
+
const img = new Image();
|
|
30
|
+
img.src = URL.createObjectURL(blob);
|
|
31
|
+
img.onload = () => {
|
|
32
|
+
resolve({
|
|
33
|
+
width: img.width,
|
|
34
|
+
height: img.height
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
img.onerror = reject;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (blob.type.startsWith("video/")) {
|
|
41
|
+
const video = document.createElement("video");
|
|
42
|
+
video.src = URL.createObjectURL(blob);
|
|
43
|
+
video.onloadedmetadata = () => {
|
|
44
|
+
resolve({
|
|
45
|
+
width: video.videoWidth,
|
|
46
|
+
height: video.videoHeight,
|
|
47
|
+
duration: video.duration
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
video.onerror = reject;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
resolve({});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
57
|
+
0 && (module.exports = {
|
|
58
|
+
generateMetadata
|
|
59
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/file-kit/client/metadata.ts
|
|
2
|
+
function generateMetadata(blob) {
|
|
3
|
+
return new Promise((resolve, reject) => {
|
|
4
|
+
if (blob.type.startsWith("image/")) {
|
|
5
|
+
const img = new Image();
|
|
6
|
+
img.src = URL.createObjectURL(blob);
|
|
7
|
+
img.onload = () => {
|
|
8
|
+
resolve({
|
|
9
|
+
width: img.width,
|
|
10
|
+
height: img.height
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
img.onerror = reject;
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (blob.type.startsWith("video/")) {
|
|
17
|
+
const video = document.createElement("video");
|
|
18
|
+
video.src = URL.createObjectURL(blob);
|
|
19
|
+
video.onloadedmetadata = () => {
|
|
20
|
+
resolve({
|
|
21
|
+
width: video.videoWidth,
|
|
22
|
+
height: video.videoHeight,
|
|
23
|
+
duration: video.duration
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
video.onerror = reject;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
resolve({});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
generateMetadata
|
|
34
|
+
};
|