-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathuse-file-upload.tsx
More file actions
69 lines (61 loc) · 1.97 KB
/
use-file-upload.tsx
File metadata and controls
69 lines (61 loc) · 1.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
import { useState } from "react";
import { toast } from "sonner";
const useFileUpload = () => {
const [progress, setProgress] = useState<number>(0);
const uploadFile = (file: File, folder: string) => {
const formData = new FormData();
formData.append("folder", folder);
formData.append("file", file);
const xhr = new XMLHttpRequest();
xhr.open("POST", "https://storage.sarafu.network/v1/upload");
xhr.timeout = 30_000;
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percentage = Math.round((event.loaded * 100) / event.total);
setProgress(percentage);
}
};
return new Promise<string>((resolve, reject) => {
xhr.ontimeout = () => {
toast.error("File upload timed out. Please try again.");
reject(new Error("File upload timed out"));
};
xhr.onerror = () => {
console.error("File upload network error", {
status: xhr.status,
statusText: xhr.statusText,
});
toast.error("File upload failed. Please check your connection.");
reject(new Error(`File upload failed: network error`));
};
xhr.onload = () => {
if (xhr.status === 200) {
const data = xhr.responseText;
const response = JSON.parse(data) as {
ok: boolean;
payload: {
s3: string;
};
};
if (response.ok) {
resolve(response.payload.s3);
} else {
toast.error("File upload failed");
reject(new Error("File upload failed: server returned ok=false"));
}
} else {
const errorMsg = `File upload failed (HTTP ${xhr.status})`;
console.error(errorMsg, xhr.responseText?.slice(0, 200));
toast.error(errorMsg);
reject(new Error(errorMsg));
}
};
xhr.send(formData);
});
};
return {
progress,
uploadFile,
};
};
export default useFileUpload;