aboutsummaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
authorRblSb <msrblsb@gmail.com>2025-02-06 06:41:49 +0300
committerRblSb <msrblsb@gmail.com>2025-02-07 01:12:14 +0300
commitd86f0c30e1726a56e670955c3b995945c1daf834 (patch)
tree2cff6b1c76191df76291f93c5a46810f09181727 /src/client
parent382f9b2ebedca905028341825350a0fa69d88673 (diff)
Fixes pack
- Fix timer seek on server pause with double timer.pause() calls - Implement multi-caching - Better uploading progress with XMLHttpRequest - Better upload/cache error reporting
Diffstat (limited to 'src/client')
-rw-r--r--src/client/Buttons.hx86
-rw-r--r--src/client/Main.hx42
-rw-r--r--src/client/Player.hx11
3 files changed, 81 insertions, 58 deletions
diff --git a/src/client/Buttons.hx b/src/client/Buttons.hx
index 99e12cb..513133a 100644
--- a/src/client/Buttons.hx
+++ b/src/client/Buttons.hx
@@ -1,18 +1,20 @@
package client;
import Types.UploadResponse;
-import Types.WsEvent;
import client.Main.getEl;
+import haxe.Json;
import haxe.Timer;
-import haxe.io.Path;
import js.Browser.document;
import js.Browser.window;
+import js.html.Blob;
import js.html.Element;
import js.html.ImageElement;
import js.html.InputElement;
import js.html.KeyboardEvent;
+import js.html.ProgressEvent;
import js.html.TransitionEvent;
import js.html.VisualViewport;
+import js.html.XMLHttpRequest;
class Buttons {
static var split:Split;
@@ -250,51 +252,63 @@ class Buttons {
// send last chunk separately to allow server file streaming while uploading
final chunkSize = 1024 * 1024 * 5; // 5 MB
- if (buffer.byteLength > chunkSize) {
- final lastChunk = buffer.slice(buffer.byteLength - chunkSize);
- window.fetch("/upload-last-chunk", {
- method: "POST",
- headers: {
- "content-name": Path.withoutExtension(name),
- "client-name": main.getName(),
- },
- body: lastChunk,
- });
- }
-
- // send full file
- final request = window.fetch("/upload", {
+ final bufferOffset = (buffer.byteLength - chunkSize).limitMin(0);
+ final lastChunk = buffer.slice(bufferOffset);
+ final chunkReq = window.fetch("/upload-last-chunk", {
method: "POST",
headers: {
- "content-name": Path.withoutExtension(name),
+ "content-name": name,
"client-name": main.getName(),
},
- body: buffer,
+ body: lastChunk,
});
- request.then(e -> {
+ chunkReq.then(e -> {
e.json().then((data:UploadResponse) -> {
- trace(data.info);
- if (data.errorId == null) return;
- main.serverMessage(data.info, true, false);
+ if (data.errorId != null) {
+ main.serverMessage(data.info, true, false);
+ return;
+ }
+ final input:InputElement = getEl("#mediaurl");
+ input.value = data.url;
+ });
+ });
+
+ final request = new XMLHttpRequest();
+ request.open("POST", "/upload", true);
+ request.setRequestHeader("content-name", name);
+ request.setRequestHeader("client-name", main.getName());
+
+ 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
+ }
});
- }).catchError(err -> {
- trace(err);
+ }
+
+ 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);
- });
-
- // set file url to input after upload starts
- function onStartUpload(event:WsEvent):Void {
- if (event.type != Progress) return;
- final data = event.progress;
- if (data.type != Uploading) return;
- if (data.data == null) return;
- final input:InputElement = getEl("#mediaurl");
- input.value = data.data;
- JsApi.off(Progress, onStartUpload);
}
- JsApi.on(Progress, onStartUpload);
+
+ request.send(new Blob([buffer]));
});
}
diff --git a/src/client/Main.hx b/src/client/Main.hx
index 84f6838..5c4b28d 100644
--- a/src/client/Main.hx
+++ b/src/client/Main.hx
@@ -120,7 +120,7 @@ class Main {
if (!player.isVideoLoaded()) return;
gotFirstPageInteraction = true;
player.unmute();
- if (!hasLeader() && !showingServerPause) player.play();
+ if (!hasLeader() && !showingServerPause && !player.inUserInteraction) player.play();
document.removeEventListener("click", onFirstInteraction);
}
@@ -508,24 +508,7 @@ class Main {
serverMessage(text);
case Progress:
- final data = data.progress;
- final text = switch data.type {
- case Caching:
- final caching = Lang.get("caching");
- final name = data.data;
- '$caching $name';
- case Downloading: Lang.get("downloading");
- case Uploading: Lang.get("uploading");
- }
- final percent = (data.ratio * 100).toFixed(1);
- var text = '$text...';
- if (percent > 0) text += ' $percent%';
- showProgressInfo(text);
- if (data.ratio == 1) {
- Timer.delay(() -> {
- hideDynamicChin();
- }, 500);
- }
+ onProgressEvent(data);
case AddVideo:
player.addVideoItem(data.addVideo.item, data.addVideo.atEnd);
@@ -675,6 +658,27 @@ class Main {
}
}
+ public function onProgressEvent(data:WsEvent):Void {
+ final data = data.progress;
+ final text = switch data.type {
+ case Caching:
+ final caching = Lang.get("caching");
+ final name = data.data;
+ '$caching $name';
+ case Downloading: Lang.get("downloading");
+ case Uploading: Lang.get("uploading");
+ }
+ final percent = (data.ratio * 100).toFixed(1);
+ var text = '$text...';
+ if (percent > 0) text += ' $percent%';
+ showProgressInfo(text);
+ if (data.ratio == 1) {
+ Timer.delay(() -> {
+ hideDynamicChin();
+ }, 500);
+ }
+ }
+
function updateLastStateTime():Void {
if (lastStateTimeStamp == 0) {
lastStateTimeStamp = Timer.stamp();
diff --git a/src/client/Player.hx b/src/client/Player.hx
index e5ea87c..64248fe 100644
--- a/src/client/Player.hx
+++ b/src/client/Player.hx
@@ -279,8 +279,11 @@ class Player {
if (!main.isLeader()) {
// user click, so we can unpause by removing leader
// (doesn't work in Firefox because of no video click propagation)
- final allowUnpause = (hasAutoPause && inUserInteraction);
- if (allowUnpause || main.hasUnpauseWithoutLeader()) {
+ var allowUnpause = hasAutoPause && inUserInteraction;
+ if (!allowUnpause) allowUnpause = main.hasUnpauseWithoutLeader();
+ // do not remove leader with custom rate
+ if (getPlaybackRate() != 1) allowUnpause = false;
+ if (allowUnpause) {
main.removeLeader();
} else {
// paused and no leader - instant pause
@@ -299,7 +302,9 @@ class Player {
});
if (hasAutoPause) {
// do not remove leader if user cannot request it back
- if (main.hasPermission(RequestLeaderPerm)) main.toggleLeader();
+ if (main.hasPermission(RequestLeaderPerm) && getPlaybackRate() == 1) {
+ main.removeLeader();
+ }
}
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage