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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
package client;
import Types.UploadResponse;
import client.Main.getEl;
import haxe.Json;
import haxe.Timer;
import js.Browser.window;
import js.html.File;
import js.html.InputElement;
import js.html.ProgressEvent;
import js.html.XMLHttpRequest;
class FileUploader {
final main:Main;
public function new(main:Main) {
this.main = main;
}
public function uploadFile(file:File):Void {
var name = ~/[?#%\/\\]/g.replace(file.name, "").trim();
if (name.length == 0) name = "video";
name = (window : Dynamic).encodeURIComponent(name);
// send last chunk separately to allow server file streaming while uploading
uploadLastChunk(file, name, data -> {
if (data.errorId != null) {
main.serverMessage(data.info, true, false);
return;
}
final input:InputElement = getEl("#mediaurl");
input.value = data.url;
uploadFullFile(name, file);
});
}
function uploadFullFile(name:String, file:File):Void {
final request = new XMLHttpRequest();
request.open("POST", "/upload", true);
request.setRequestHeader("content-name", name);
request.upload.onprogress = (event:ProgressEvent) -> {
var ratio = 0.0;
if (event.lengthComputable) {
ratio = (event.loaded / event.total).clamp(0, 1);
}
main.onProgressEvent({
type: Progress,
progress: {
type: Uploading,
ratio: ratio
}
});
}
request.onload = (e:ProgressEvent) -> {
final data:UploadResponse = try {
Json.parse(request.responseText);
} catch (e) {
trace(e);
return;
}
if (data.errorId == null) return;
main.serverMessage(data.info, true, false);
}
request.onloadend = () -> {
Timer.delay(() -> {
main.hideDynamicChin();
}, 500);
}
request.send(file);
}
function uploadLastChunk(file:File, name:String, callback:(data:UploadResponse) -> Void):Void {
final chunkSize = 1024 * 1024 * 5; // 5 MB
final bufferOffset = (file.size - chunkSize).limitMin(0);
final lastChunk = file.slice(bufferOffset);
final chunkReq = window.fetch("/upload-last-chunk", {
method: "POST",
headers: {
"content-name": name,
},
body: lastChunk,
});
chunkReq.then(e -> {
e.json().then((data:UploadResponse) -> {
callback(data);
});
});
}
}
|