1
|
|
|
import React, {useRef, useState} from "react"; |
2
|
|
|
import MediaShowcase from "../components/MediaShowcase"; |
3
|
|
|
import {Button} from "react-bootstrap"; |
4
|
|
|
import "bootstrap/dist/css/bootstrap.min.css"; |
5
|
|
|
import {Link} from "react-router-dom"; |
6
|
|
|
|
7
|
|
|
const cloudName = "replayer-store"; |
8
|
|
|
const cloudinaryEndpoint = `https://api.cloudinary.com/v1_1/${cloudName}/auto/upload`; |
9
|
|
|
const acceptedFormats = ".jpg, .png, .gif, .bmp, .mp4, .mkv, .webp"; |
10
|
|
|
const uploadPreset = "replayer_preset"; |
11
|
|
|
const apiPutEndpoint = "/api/put"; |
12
|
|
|
|
13
|
|
|
function UploadPage(): JSX.Element { |
14
|
|
|
const [file, setFile] = useState<File | null>(null); |
15
|
|
|
const [fileUrl, setFileUrl] = useState<string | null>(null); |
16
|
|
|
const [isUploading, setIsUploading] = useState<boolean>(false); |
17
|
|
|
const fileSelector = useRef<HTMLInputElement>(null); |
18
|
|
|
|
19
|
|
|
const getFile = () => { |
20
|
|
|
if (fileSelector.current) { |
21
|
|
|
fileSelector.current.click(); |
22
|
|
|
} |
23
|
|
|
}; |
24
|
|
|
|
25
|
|
|
const retrieveFile = () => { |
26
|
|
|
if (fileSelector.current?.files && fileSelector.current.files.length > 0) { |
27
|
|
|
setFile(fileSelector.current.files[0]); |
28
|
|
|
} |
29
|
|
|
}; |
30
|
|
|
|
31
|
|
|
const sendFile = async () => { |
32
|
|
|
if (file) { |
33
|
|
|
const start = (new Date()).getTime(); |
34
|
|
|
setIsUploading(true); |
35
|
|
|
const formData = new FormData(); |
36
|
|
|
formData.append("file", file); |
37
|
|
|
formData.append("upload_preset", uploadPreset); |
38
|
|
|
|
39
|
|
|
const request = await fetch(cloudinaryEndpoint, { |
40
|
|
|
method: "POST", |
41
|
|
|
body: formData |
42
|
|
|
}); |
43
|
|
|
|
44
|
|
|
if (request.ok) { |
45
|
|
|
|
46
|
|
|
|
47
|
|
|
const response = await request.json(); |
48
|
|
|
|
49
|
|
|
if (response.asset_id) { |
50
|
|
|
const req = await fetch(apiPutEndpoint, { |
51
|
|
|
method: "POST", |
52
|
|
|
body: JSON.stringify({ |
53
|
|
|
privateUrl: response.secure_url, |
54
|
|
|
name: file.name, |
55
|
|
|
type: file.type, |
56
|
|
|
size: file.size |
57
|
|
|
}) |
58
|
|
|
}); |
59
|
|
|
|
60
|
|
|
const res = await req.json(); |
61
|
|
|
|
62
|
|
|
setFileUrl("/watch/" + res.resourceId); |
63
|
|
|
setFile(null); |
64
|
|
|
const end = (new Date()).getTime(); |
65
|
|
|
console.log("Uploaded in " + (end - start) + "ms"); |
66
|
|
|
} |
67
|
|
|
} else { |
68
|
|
|
alert(`Upload error\n${request.status} ${request.statusText}`); |
69
|
|
|
} |
70
|
|
|
setIsUploading(false); |
71
|
|
|
} |
72
|
|
|
}; |
73
|
|
|
|
74
|
|
|
return ( |
75
|
|
|
<React.Fragment> |
76
|
|
|
{fileUrl && |
77
|
|
|
<div> |
78
|
|
|
<p>You can access your media here:</p> |
79
|
|
|
<Link to={fileUrl}>{" " + window.location.origin + fileUrl}</Link> |
80
|
|
|
</div> |
81
|
|
|
} |
82
|
|
|
<div className="selector-container" onClick={getFile}> |
83
|
|
|
<input type="file" className="file-selector" accept={acceptedFormats} ref={fileSelector} |
84
|
|
|
onChange={retrieveFile} /> |
85
|
|
|
{!file && <h1>+</h1>} |
86
|
|
|
{file && <MediaShowcase file={file} />} |
87
|
|
|
{isUploading && |
88
|
|
|
<div className="loading-screen"> |
89
|
|
|
<h1> |
90
|
|
|
Uploading... |
91
|
|
|
</h1> |
92
|
|
|
</div> |
93
|
|
|
} |
94
|
|
|
</div> |
95
|
|
|
|
96
|
|
|
{file && |
97
|
|
|
<Button className="btn-primary" onClick={sendFile}> |
98
|
|
|
Send file |
99
|
|
|
</Button> |
100
|
|
|
} |
101
|
|
|
</React.Fragment> |
102
|
|
|
); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
export default UploadPage; |
106
|
|
|
|