aboutsummaryrefslogtreecommitdiffstats
path: root/src/client/Main.hx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/Main.hx')
-rw-r--r--src/client/Main.hx104
1 files changed, 99 insertions, 5 deletions
diff --git a/src/client/Main.hx b/src/client/Main.hx
index 9a4b426..62fa7de 100644
--- a/src/client/Main.hx
+++ b/src/client/Main.hx
@@ -2,6 +2,7 @@ package client;
import Client.ClientData;
import Types.Config;
+import Types.GetTimeEvent;
import Types.Permission;
import Types.PlayerType;
import Types.VideoData;
@@ -19,6 +20,7 @@ import js.html.Event;
import js.html.InputElement;
import js.html.KeyboardEvent;
import js.html.MouseEvent;
+import js.html.TransitionEvent;
import js.html.URL;
import js.html.VideoElement;
import js.html.WebSocket;
@@ -37,6 +39,13 @@ class Main {
public var globalIp(default, null) = "";
public var isPlaylistOpen(default, null) = true;
public var playersCacheSupport(default, null):Array<PlayerType> = [];
+ public var showingServerPause(default, null) = false;
+ public final lastState:GetTimeEvent = {
+ time: 0,
+ rate: 1.0,
+ paused: false,
+ pausedByServer: false
+ };
final clients:Array<Client> = [];
var pageTitle = document.title;
@@ -109,7 +118,7 @@ class Main {
if (!player.isVideoLoaded()) return;
gotFirstPageInteraction = true;
player.unmute();
- if (!hasLeader()) player.play();
+ if (!hasLeader() && !showingServerPause) player.play();
document.removeEventListener("click", onFirstInteraction);
}
@@ -515,14 +524,16 @@ class Main {
if (player.isListEmpty()) player.pause();
case Pause:
- player.setPauseIndicator(false);
+ lastState.paused = true;
+ player.setPauseIndicator(lastState.paused);
updateUserList();
if (isLeader()) return;
player.pause();
player.setTime(data.pause.time);
case Play:
- player.setPauseIndicator(true);
+ lastState.paused = false;
+ player.setPauseIndicator(lastState.paused);
updateUserList();
if (isLeader()) return;
final synchThreshold = settings.synchThreshold;
@@ -535,8 +546,24 @@ class Main {
case GetTime:
data.getTime.paused ??= false;
+ data.getTime.pausedByServer ??= false;
data.getTime.rate ??= 1;
+ final isPauseChanged = lastState.paused != data.getTime.paused;
+ lastState.time = data.getTime.time;
+ lastState.paused = data.getTime.paused;
+ lastState.pausedByServer = data.getTime.pausedByServer;
+ lastState.rate = data.getTime.rate;
+
+ if (isPauseChanged) updateUserList();
+
+ final pausedByServer = data.getTime.pausedByServer;
+ if (pausedByServer) {
+ showServerUnpause();
+ } else if (showingServerPause) {
+ hideDynamicChin();
+ }
+
if (player.getPlaybackRate() != data.getTime.rate) {
player.setPlaybackRate(data.getTime.rate);
}
@@ -558,7 +585,7 @@ class Main {
} else {
if (data.getTime.paused) player.pause();
}
- player.setPauseIndicator(!data.getTime.paused);
+ player.setPauseIndicator(data.getTime.paused);
if (Math.abs(time - newTime) < synchThreshold) return;
// +0.5s for buffering
if (!data.getTime.paused) player.setTime(newTime + 0.5);
@@ -913,7 +940,7 @@ class Main {
final list = new StringBuf();
for (client in clients) {
list.add('<div class="userlist_item">');
- final iconName = player.isPaused() ? "pause" : "play";
+ final iconName = lastState.paused ? "pause" : "play";
if (client.isLeader) list.add('<ion-icon name="$iconName"></ion-icon>');
var klass = client.isBanned ? "userlist_banned" : "";
if (client.isAdmin) klass += " userlist_owner";
@@ -1014,6 +1041,73 @@ class Main {
}, {once: true});
}
+ public function showServerUnpause():Void {
+ if (showingServerPause) return;
+ showingServerPause = true;
+ final chin = ge("#dynamic-chin");
+ chin.innerHTML = "";
+
+ final div = document.createDivElement();
+ div.className = "server-whisper";
+ div.textContent = Lang.get("leaderDisconnectedServerOnPause");
+ chin.appendChild(div);
+ final btn = document.createButtonElement();
+ btn.id = "unpause-server";
+ btn.textContent = Lang.get("unpause");
+ chin.appendChild(btn);
+ btn.onclick = () -> {
+ hideDynamicChin();
+ send({
+ type: SetLeader,
+ setLeader: {
+ clientName: personal.name
+ }
+ });
+ JsApi.once(SetLeader, event -> {
+ send({
+ type: SetLeader,
+ setLeader: {
+ clientName: ""
+ }
+ });
+ });
+ }
+
+ chin.style.display = "";
+ chin.style.transition = "none";
+ chin.classList.remove("collapsed");
+ final h = chin.clientHeight;
+ chin.classList.add("collapsed");
+ Timer.delay(() -> {
+ chin.style.transition = "";
+ chin.classList.remove("collapsed");
+ chin.style.height = '${h}px';
+ }, 0);
+ function onTransitionEnd(e:TransitionEvent):Void {
+ if (e.propertyName != "height") return;
+ chin.style.height = "";
+ chin.removeEventListener("transitionend", onTransitionEnd);
+ }
+ chin.addEventListener("transitionend", onTransitionEnd);
+ }
+
+ public function hideDynamicChin():Void {
+ showingServerPause = false;
+ final chin = ge("#dynamic-chin");
+ final h = chin.clientHeight;
+ chin.style.height = '${h}px';
+ Timer.delay(() -> {
+ chin.style.height = "";
+ chin.classList.add("collapsed");
+ }, 0);
+ function onTransitionEnd(e:TransitionEvent):Void {
+ if (e.propertyName != "height") return;
+ chin.style.display = "none";
+ chin.removeEventListener("transitionend", onTransitionEnd);
+ }
+ chin.addEventListener("transitionend", onTransitionEnd);
+ }
+
function onChatImageLoaded(e:Event):Void {
scrollChatToEnd();
(cast e.target : Element).onload = null;
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage