aboutsummaryrefslogtreecommitdiffstats
path: root/src/client/FileUploader.hx
diff options
context:
space:
mode:
authorRblSb <msrblsb@gmail.com>2025-10-23 01:30:22 +0300
committerRblSb <msrblsb@gmail.com>2025-10-23 01:30:22 +0300
commitee3eddc6b80565f6bb458a1fd8f3a83fdd37d554 (patch)
treef8899cd76766e2eb7dd09969c5d91c5d11dd6c69 /src/client/FileUploader.hx
parentd4fb50df4f77cb8d039eaecdc8f6467c5fef4d22 (diff)
Fix large file upload
Diffstat (limited to 'src/client/FileUploader.hx')
-rw-r--r--src/client/FileUploader.hx93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/client/FileUploader.hx b/src/client/FileUploader.hx
new file mode 100644
index 0000000..60cc1d2
--- /dev/null
+++ b/src/client/FileUploader.hx
@@ -0,0 +1,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);
+ });
+ });
+ }
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage