aboutsummaryrefslogtreecommitdiffstats
path: root/res/client.js
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2026-10-19 15:32:53 -0700
committerPinapelz <yukais@pinapelz.com>2026-10-19 15:32:53 -0700
commit304bd1e77a5442f614aacd2b35f330777118b2cd (patch)
tree970e7da13bb1bd8edf1f9b453af4d0994c665e94 /res/client.js
parenta4f3064542ddad6939598e7e60ca0090be07df60 (diff)
merge with upstream https://github.com/RblSb/SyncTubeHEADmaster
Diffstat (limited to 'res/client.js')
-rw-r--r--res/client.js1510
1 files changed, 1199 insertions, 311 deletions
diff --git a/res/client.js b/res/client.js
index 89c5829..23ac4fe 100644
--- a/res/client.js
+++ b/res/client.js
@@ -1,4 +1,4 @@
-// Generated by Haxe 4.3.7
+// Generated by Haxe 4.3.3
(function ($hx_exports, $global) { "use strict";
$hx_exports["client"] = $hx_exports["client"] || {};
$hx_exports["client"]["JsApi"] = $hx_exports["client"]["JsApi"] || {};
@@ -68,11 +68,18 @@ ClientTools.setLeader = function(clients,name) {
}
};
ClientTools.hasLeader = function(clients) {
+ return ClientTools.getLeader(clients) != null;
+};
+ClientTools.getLeader = function(clients) {
var _g = 0;
- while(_g < clients.length) if((clients[_g++].group & 4) != 0) {
- return true;
+ while(_g < clients.length) {
+ var client = clients[_g];
+ ++_g;
+ if((client.group & 4) != 0) {
+ return client;
+ }
}
- return false;
+ return null;
};
ClientTools.getByName = function(clients,name,def) {
var _g = 0;
@@ -338,13 +345,6 @@ Reflect.fields = function(o) {
}
return a;
};
-Reflect.deleteField = function(o,field) {
- if(!Object.prototype.hasOwnProperty.call(o,field)) {
- return false;
- }
- delete(o[field]);
- return true;
-};
Reflect.copy = function(o) {
if(o == null) {
return null;
@@ -501,8 +501,14 @@ StringTools.hex = function(n,digits) {
};
var _$Types_VideoItemTools = function() { };
_$Types_VideoItemTools.__name__ = true;
+_$Types_VideoItemTools.isPlayable = function(item) {
+ if(item.isIncomplete == true && item.doCache) {
+ return false;
+ }
+ return true;
+};
_$Types_VideoItemTools.withUrl = function(item,url) {
- return { url : url, title : item.title, author : item.author, duration : item.duration, subs : item.subs, voiceOverTrack : item.voiceOverTrack, isTemp : item.isTemp, doCache : item.doCache, playerType : item.playerType};
+ return { url : url, title : item.title, author : item.author, duration : item.duration, subs : item.subs, voiceOverTrack : item.voiceOverTrack, isTemp : item.isTemp, doCache : item.doCache, isIncomplete : item.isIncomplete, playerType : item.playerType};
};
var VideoList = function() {
this.items = [];
@@ -571,7 +577,7 @@ client_Buttons.init = function(main) {
}
client_Buttons.split = new client_Split(client_Buttons.settings);
client_Buttons.split.setSize(client_Buttons.settings.chatSize);
- client_Buttons.initChatInputs(main);
+ client_Buttons.initInputs(main);
var _g = 0;
var _g1 = client_Buttons.settings.checkboxes;
while(_g < _g1.length) {
@@ -697,8 +703,12 @@ client_Buttons.init = function(main) {
haxe_Timer.delay(function() {
window.document.querySelector("#userlist-wrap").style.transition = "200ms";
},0);
+ var playlistMenuBtn = window.document.querySelector("#playlist-menu-btn");
+ var playlistMenuDropdown = window.document.querySelector("#playlist-menu-dropdown");
var toggleSynch = window.document.querySelector("#togglesynch");
toggleSynch.onclick = function(e) {
+ playlistMenuDropdown.style.display = "none";
+ playlistMenuBtn.classList.remove("active");
var icon = toggleSynch.firstElementChild;
if(main.isSyncActive) {
if(!window.confirm(Lang.get("toggleSynchConfirm"))) {
@@ -706,23 +716,29 @@ client_Buttons.init = function(main) {
}
main.isSyncActive = false;
icon.style.color = "rgba(238, 72, 67, 0.75)";
- icon.setAttribute("name","pause");
+ playlistMenuBtn.classList.add("danger");
} else {
main.isSyncActive = true;
icon.style.color = "";
- icon.setAttribute("name","play");
+ playlistMenuBtn.classList.remove("danger");
main.send({ type : "UpdatePlaylist"});
}
+ client_Buttons.updateToggleSynchBtn(main);
};
window.document.querySelector("#mediarefresh").onclick = function(e) {
main.refreshPlayer();
};
window.document.querySelector("#fullscreenbtn").onclick = function(e) {
- if((client_Utils.isTouch() || main.isVerbose()) && !client_Utils.hasFullscreen()) {
- window.scrollTo(0,0);
- return client_Utils.requestFullscreen(window.document.documentElement);
+ return client_Utils.toggleFullscreen(window.document.querySelector("#ytapiplayer"));
+ };
+ window.document.querySelector("#fullscreen-chat-btn").onclick = function(e) {
+ e.stopPropagation();
+ e.preventDefault();
+ client_Buttons.clearUnreadChatMessages();
+ if(client_Buttons.settings.pageFullscreen) {
+ client_Utils.switchToPageFullscreen();
} else {
- return client_Utils.requestFullscreen(window.document.querySelector("#ytapiplayer"));
+ client_Utils.cancelFullscreen();
}
};
client_Buttons.initPageFullscreen();
@@ -735,13 +751,41 @@ client_Buttons.init = function(main) {
icon.setAttribute("name","link");
},2000);
};
+ playlistMenuBtn.onclick = function(e) {
+ e.stopPropagation();
+ var isOpen = playlistMenuDropdown.style.display != "none";
+ if(isOpen) {
+ playlistMenuDropdown.style.display = "none";
+ playlistMenuBtn.classList.remove("active");
+ } else {
+ main.hasSeenSkipVote = true;
+ playlistMenuDropdown.style.display = "";
+ playlistMenuBtn.classList.add("active");
+ window.document.querySelector("#playlist-menu-indicator").style.display = "none";
+ }
+ };
+ window.document.addEventListener("click",function(e) {
+ var target = e.target;
+ if(!playlistMenuBtn.contains(target) && !playlistMenuDropdown.contains(target)) {
+ playlistMenuDropdown.style.display = "none";
+ playlistMenuBtn.classList.remove("active");
+ }
+ });
+ window.document.querySelector("#voteskip").addEventListener("click",function() {
+ playlistMenuDropdown.style.display = "none";
+ playlistMenuBtn.classList.remove("active");
+ });
window.document.querySelector("#clearplaylist").onclick = function(e) {
+ playlistMenuDropdown.style.display = "none";
+ playlistMenuBtn.classList.remove("active");
if(!window.confirm(Lang.get("clearPlaylistConfirm"))) {
return;
}
main.send({ type : "ClearPlaylist"});
};
window.document.querySelector("#shuffleplaylist").onclick = function(e) {
+ playlistMenuDropdown.style.display = "none";
+ playlistMenuBtn.classList.remove("active");
if(!window.confirm(Lang.get("shufflePlaylistConfirm"))) {
return;
}
@@ -760,6 +804,8 @@ client_Buttons.init = function(main) {
};
var showMediaUrl = window.document.querySelector("#showmediaurl");
showMediaUrl.onclick = function(e) {
+ playlistMenuDropdown.style.display = "none";
+ playlistMenuBtn.classList.remove("active");
if(client_Buttons.showPlayerGroup(showMediaUrl)) {
haxe_Timer.delay(function() {
window.document.querySelector("#addfromurl").scrollIntoView();
@@ -769,6 +815,8 @@ client_Buttons.init = function(main) {
};
var showCustomEmbed = window.document.querySelector("#showcustomembed");
showCustomEmbed.onclick = function(e) {
+ playlistMenuDropdown.style.display = "none";
+ playlistMenuBtn.classList.remove("active");
if(client_Buttons.showPlayerGroup(showCustomEmbed)) {
haxe_Timer.delay(function() {
window.document.querySelector("#customembed").scrollIntoView();
@@ -905,6 +953,39 @@ client_Buttons.initTextButtons = function(main) {
client_Buttons.updateHotkeysBtn();
};
client_Buttons.updateHotkeysBtn();
+ window.document.querySelector("#pageFullscreenBtn").onclick = function(e) {
+ client_Buttons.settings.pageFullscreen = !client_Buttons.settings.pageFullscreen;
+ client_Settings.write(client_Buttons.settings);
+ client_Buttons.updatePageFullscreenBtn();
+ if(client_Buttons.settings.pageFullscreen) {
+ client_Utils.switchToPageFullscreen();
+ } else {
+ client_Utils.cancelFullscreen();
+ }
+ };
+ client_Buttons.updatePageFullscreenBtn();
+ var fullscreenActionBtn = window.document.querySelector("#fullscreenActionBtn");
+ if(fullscreenActionBtn != null) {
+ fullscreenActionBtn.onclick = function(e) {
+ client_Buttons.settings.fullscreenAction = !client_Buttons.settings.fullscreenAction;
+ client_Settings.write(client_Buttons.settings);
+ client_Buttons.updateFullscreenActionBtn();
+ };
+ client_Buttons.updateFullscreenActionBtn();
+ }
+ window.document.body.addEventListener("click",function(e) {
+ if(!client_Buttons.settings.pageFullscreen) {
+ return;
+ }
+ if(client_Utils.hasFullscreen()) {
+ return;
+ }
+ var target = e.target;
+ if(target != null && target.closest("button, input, a, textarea, select, #optionsPanel, #chatline, #userlist, .queue_sortable, .nav") != null) {
+ return;
+ }
+ client_Utils.requestFullscreen(window.document.documentElement);
+ });
var removeBtn = window.document.querySelector("#removePlayerBtn");
removeBtn.onclick = function(e) {
if(main.toggleVideoElement()) {
@@ -926,6 +1007,7 @@ client_Buttons.initTextButtons = function(main) {
client_JsApi.setVideoSrc(url);
});
};
+ client_Buttons.updateToggleSynchBtn(main);
};
client_Buttons.initHotkeys = function(main,player) {
window.document.querySelector("#mediarefresh").title += " (Alt-R)";
@@ -967,6 +1049,9 @@ client_Buttons.initHotkeys = function(main,player) {
case 83:
window.document.querySelector("#voteskip").onclick();
break;
+ case 85:
+ window.document.querySelector("#togglesynch").onclick();
+ break;
default:
return;
}
@@ -991,11 +1076,43 @@ client_Buttons.updateSynchThresholdBtn = function() {
window.document.querySelector("#synchThresholdBtn").innerText = tmp + "s";
};
client_Buttons.updateHotkeysBtn = function() {
- var text = Lang.get("hotkeys");
- var state = client_Buttons.settings.hotkeysEnabled ? Lang.get("on") : Lang.get("off");
- window.document.querySelector("#hotkeysBtn").innerText = "" + text + ": " + state;
+ var btn = window.document.querySelector("#hotkeysBtn");
+ var switchEl = btn.querySelector(".toggle-switch");
+ if(switchEl == null) {
+ btn.innerHTML = "<span>" + Lang.get("hotkeys") + "</span><div class=\"toggle-switch\"></div>";
+ switchEl = btn.querySelector(".toggle-switch");
+ }
+ switchEl.classList.toggle("on",client_Buttons.settings.hotkeysEnabled);
+ window.document.body.classList.toggle("hotkeys-disabled",!client_Buttons.settings.hotkeysEnabled);
+};
+client_Buttons.updatePageFullscreenBtn = function() {
+ var btn = window.document.querySelector("#pageFullscreenBtn");
+ var switchEl = btn.querySelector(".toggle-switch");
+ if(switchEl == null) {
+ btn.innerHTML = "<span>" + Lang.get("pageFullscreen") + "</span><div class=\"toggle-switch\"></div>";
+ switchEl = btn.querySelector(".toggle-switch");
+ }
+ switchEl.classList.toggle("on",client_Buttons.settings.pageFullscreen);
};
-client_Buttons.initChatInputs = function(main) {
+client_Buttons.updateFullscreenActionBtn = function() {
+ var btn = window.document.querySelector("#fullscreenActionBtn");
+ var switchEl = btn.querySelector(".toggle-switch");
+ if(switchEl == null) {
+ btn.innerHTML = "<span>" + Lang.get(client_Utils.isTouch() ? "fullscreenActionTouch" : "fullscreenActionDesktop") + "</span><div class=\"toggle-switch\"></div>";
+ switchEl = btn.querySelector(".toggle-switch");
+ }
+ switchEl.classList.toggle("on",client_Buttons.settings.fullscreenAction);
+};
+client_Buttons.updateToggleSynchBtn = function(main) {
+ var toggleSynch = window.document.querySelector("#togglesynch");
+ var span = toggleSynch.querySelector("span");
+ var text = Lang.get(main.isSyncActive ? "disableVideoSync" : "enableVideoSync");
+ toggleSynch.title = "" + text + " (Alt-U)";
+ if(span != null) {
+ span.innerHTML = "" + text + " <span class=\"hotkey-hint\">(Alt-U)</span>";
+ }
+};
+client_Buttons.initInputs = function(main) {
var guestName = window.document.querySelector("#guestname");
guestName.onkeydown = function(e) {
if(e.keyCode == 13) {
@@ -1015,19 +1132,6 @@ client_Buttons.initChatInputs = function(main) {
}
}
};
- var chatline = window.document.querySelector("#chatline");
- chatline.onfocus = function(e) {
- if(client_Utils.isIOS()) {
- var startY = 0;
- haxe_Timer.delay(function() {
- window.scrollBy(0,-(window.scrollY - startY));
- window.document.querySelector("#video").scrollTop = 0;
- main.scrollChatToEnd();
- },100);
- } else if(client_Utils.isTouch()) {
- main.scrollChatToEnd();
- }
- };
var viewport = window.visualViewport;
if(viewport != null) {
viewport.addEventListener("resize",function(e) {
@@ -1035,16 +1139,6 @@ client_Buttons.initChatInputs = function(main) {
});
client_Buttons.onViewportResize();
}
- new client_InputWithHistory(chatline,null,50,function(value) {
- if(main.handleCommands(value)) {
- return true;
- }
- main.send({ type : "Message", message : { clientName : "", text : value}});
- if(client_Utils.isTouch()) {
- chatline.blur();
- }
- return true;
- });
var checkboxes = [window.document.querySelector("#add-temp")];
var _g = 0;
while(_g < checkboxes.length) {
@@ -1078,17 +1172,302 @@ client_Buttons.onViewportResize = function() {
}
window.document.querySelector("#chat").style.height = "" + h + "px";
};
+client_Buttons.onNewChatMessage = function() {
+ client_Buttons.hasUnreadChatMessages = true;
+ client_Buttons.updateFullscreenChatBtn();
+};
+client_Buttons.clearUnreadChatMessages = function() {
+ client_Buttons.hasUnreadChatMessages = false;
+ client_Buttons.updateFullscreenChatBtn();
+};
+client_Buttons.updateFullscreenChatBtn = function() {
+ var chatBtn = window.document.querySelector("#fullscreen-chat-btn");
+ if(client_Utils.hasFullscreen() && client_Buttons.hasUnreadChatMessages) {
+ chatBtn.classList.add("has-unread");
+ } else {
+ chatBtn.classList.remove("has-unread");
+ }
+};
client_Buttons.initPageFullscreen = function() {
window.document.onfullscreenchange = function(e) {
- var el = window.document.documentElement;
- if(client_Utils.hasFullscreen()) {
- if(e.target == el) {
- el.classList.add("mobile-view");
+ client_Buttons.clearUnreadChatMessages();
+ client_Buttons.updateFullscreenChatBtn();
+ };
+};
+var client_ChatInput = function(main) {
+ this.selectedCommandIndex = -1;
+ this.filteredCommands = [];
+ this.main = main;
+ this.chatline = window.document.querySelector("#chatline");
+ this.commandsWrap = window.document.querySelector("#chat-commands-wrap");
+ this.commandsList = window.document.querySelector("#chat-commands-list");
+ this.setupFocusHandler();
+ this.setupAutocomplete();
+ this.inputWithHistory = new client_InputWithHistory(this.chatline,null,50,$bind(this,this.onEnter),$bind(this,this.onInterceptKeyDown));
+};
+client_ChatInput.__name__ = true;
+client_ChatInput.prototype = {
+ setupFocusHandler: function() {
+ var _gthis = this;
+ this.chatline.onfocus = function(e) {
+ if(client_Utils.isIOS()) {
+ var startY = 0;
+ haxe_Timer.delay(function() {
+ window.scrollBy(0,-(window.scrollY - startY));
+ window.document.querySelector("#video").scrollTop = 0;
+ _gthis.main.scrollChatToEnd();
+ },100);
+ } else if(client_Utils.isTouch()) {
+ _gthis.main.scrollChatToEnd();
}
+ };
+ }
+ ,setupAutocomplete: function() {
+ var _gthis = this;
+ this.commandsList.addEventListener("mousemove",function(e) {
+ _gthis.commandsList.classList.remove("keyboard-nav");
+ });
+ this.chatline.addEventListener("input",function(e) {
+ var val = _gthis.chatline.value;
+ if(StringTools.startsWith(val,"/")) {
+ _gthis.filteredCommands = client_Commands.filterForAutocomplete(val);
+ _gthis.selectedCommandIndex = _gthis.filteredCommands.length > 0 ? 0 : -1;
+ _gthis.renderCommands();
+ } else {
+ _gthis.commandsWrap.style.display = "none";
+ _gthis.selectedCommandIndex = -1;
+ }
+ });
+ this.chatline.addEventListener("blur",function(e) {
+ return _gthis.commandsWrap.style.display = "none";
+ });
+ }
+ ,renderCommands: function() {
+ var _gthis = this;
+ this.commandsList.innerHTML = "";
+ if(this.filteredCommands.length == 0) {
+ this.commandsWrap.style.display = "none";
+ return;
+ }
+ var parsed = client_Commands.parse(this.chatline.value);
+ var currentArgIndex = parsed.currentArgIndex;
+ var _g = 0;
+ var _g1 = this.filteredCommands.length;
+ while(_g < _g1) {
+ var i = [_g++];
+ var cmd = [this.filteredCommands[i[0]]];
+ var item = window.document.createElement("div");
+ item.className = "chat-command-item" + (i[0] == this.selectedCommandIndex ? " active" : "");
+ item.onclick = (function(cmd) {
+ return function(e) {
+ _gthis.chatline.value = (cmd[0].name == null ? "null" : cmd[0].name) + (cmd[0].args > 0 ? " " : "");
+ _gthis.chatline.focus();
+ if(cmd[0].args == 0) {
+ _gthis.commandsWrap.style.display = "none";
+ _gthis.selectedCommandIndex = -1;
+ } else {
+ _gthis.chatline.dispatchEvent(new Event("input"));
+ }
+ };
+ })(cmd);
+ item.onmouseenter = (function(i) {
+ return function(e) {
+ if(!_gthis.commandsList.classList.contains("keyboard-nav")) {
+ _gthis.selectedCommandIndex = i[0];
+ var _g = 0;
+ var _g1 = _gthis.commandsList.children.length;
+ while(_g < _g1) {
+ var j = _g++;
+ var child = _gthis.commandsList.children[j];
+ if(j == i[0]) {
+ child.classList.add("active");
+ } else {
+ child.classList.remove("active");
+ }
+ }
+ }
+ };
+ })(i);
+ var nameDiv = window.document.createElement("div");
+ nameDiv.className = "chat-command-item-name";
+ nameDiv.innerText = cmd[0].name;
+ var descDiv = window.document.createElement("div");
+ descDiv.className = "chat-command-item-desc";
+ descDiv.innerHTML = client_Commands.formatDescWithHighlight(Lang.get(cmd[0].lang),currentArgIndex);
+ item.appendChild(nameDiv);
+ item.appendChild(descDiv);
+ this.commandsList.appendChild(item);
+ }
+ this.commandsWrap.style.display = "";
+ if(this.selectedCommandIndex >= 0 && this.commandsList.children.length > this.selectedCommandIndex) {
+ var selectedEl = this.commandsList.children[this.selectedCommandIndex];
+ selectedEl.scrollIntoView({ block : "center"});
+ }
+ }
+ ,onEnter: function(value) {
+ if(this.main.handleCommands(value)) {
+ return true;
+ }
+ this.main.send({ type : "Message", message : { clientName : "", text : value}});
+ if(client_Utils.isTouch()) {
+ this.chatline.blur();
+ }
+ this.commandsWrap.style.display = "none";
+ return true;
+ }
+ ,onInterceptKeyDown: function(e) {
+ if(this.commandsWrap.style.display == "none") {
+ return false;
+ }
+ var key = e.keyCode;
+ switch(key) {
+ case 9:case 13:
+ if(this.selectedCommandIndex < 0 || this.selectedCommandIndex >= this.filteredCommands.length) {
+ return false;
+ }
+ var selectedCmd = this.filteredCommands[this.selectedCommandIndex];
+ var val = this.chatline.value;
+ var hasSpace = val.indexOf(" ") >= 0;
+ if(key == 13) {
+ if(hasSpace || selectedCmd.args == 0 && StringTools.trim(val).toLowerCase() == selectedCmd.name) {
+ return false;
+ }
+ }
+ if(!hasSpace) {
+ this.chatline.value = (selectedCmd.name == null ? "null" : selectedCmd.name) + (selectedCmd.args > 0 ? " " : "");
+ }
+ e.preventDefault();
+ this.chatline.dispatchEvent(new Event("input"));
+ return true;
+ case 27:
+ this.commandsWrap.style.display = "none";
+ return false;
+ case 38:
+ this.commandsList.classList.add("keyboard-nav");
+ if(this.selectedCommandIndex > 0) {
+ this.selectedCommandIndex--;
+ } else {
+ this.selectedCommandIndex = this.filteredCommands.length - 1;
+ }
+ this.renderCommands();
+ e.preventDefault();
+ return true;
+ case 40:
+ this.commandsList.classList.add("keyboard-nav");
+ if(this.selectedCommandIndex < this.filteredCommands.length - 1) {
+ this.selectedCommandIndex++;
+ } else {
+ this.selectedCommandIndex = 0;
+ }
+ this.renderCommands();
+ e.preventDefault();
+ return true;
+ default:
+ return false;
+ }
+ }
+};
+var client_CommandInfo = function(name,args,aliases) {
+ if(args == null) {
+ args = 0;
+ }
+ this.name = name;
+ this.args = args;
+ this.aliases = aliases != null ? aliases : [];
+ this.lang = this.getLangId();
+};
+client_CommandInfo.__name__ = true;
+client_CommandInfo.prototype = {
+ getLangId: function() {
+ var withoutSlash = HxOverrides.substr(this.name,1,null);
+ return "cmd" + withoutSlash.charAt(0).toUpperCase() + HxOverrides.substr(withoutSlash,1,null);
+ }
+};
+var client_Commands = function() { };
+client_Commands.__name__ = true;
+client_Commands.find = function(name) {
+ var lower = name.toLowerCase();
+ var _g = 0;
+ var _g1 = client_Commands.list;
+ while(_g < _g1.length) {
+ var c = _g1[_g];
+ ++_g;
+ if(c.name == lower) {
+ return c;
+ }
+ var _g2 = 0;
+ var _g3 = c.aliases;
+ while(_g2 < _g3.length) if(_g3[_g2++].toLowerCase() == lower) {
+ return c;
+ }
+ }
+ return null;
+};
+client_Commands.parse = function(input) {
+ if(!StringTools.startsWith(input,"/")) {
+ return { cmd : null, rawCmd : "", args : [], currentArgIndex : -1};
+ }
+ var parts = input.split(" ");
+ var rawCmd = parts[0];
+ var args = parts.slice(1);
+ var currentArgIndex = args.length > 0 ? args.length - 1 : -1;
+ return { cmd : client_Commands.find(rawCmd), rawCmd : rawCmd, args : args, currentArgIndex : currentArgIndex};
+};
+client_Commands.filterForAutocomplete = function(val) {
+ if(!StringTools.startsWith(val,"/")) {
+ return [];
+ }
+ var parts = val.toLowerCase().split(" ");
+ var searchCmd = parts[0];
+ var spaceCount = parts.length - 1;
+ var result = [];
+ var _g = 0;
+ var _g1 = client_Commands.list;
+ while(_g < _g1.length) {
+ var c = _g1[_g];
+ ++_g;
+ if(spaceCount == 0) {
+ if(StringTools.startsWith(c.name,searchCmd)) {
+ result.push(c);
+ } else {
+ var _g2 = 0;
+ var _g3 = c.aliases;
+ while(_g2 < _g3.length) if(StringTools.startsWith(_g3[_g2++].toLowerCase(),searchCmd)) {
+ result.push(c);
+ break;
+ }
+ }
+ } else if(spaceCount <= c.args) {
+ if(c.name == searchCmd) {
+ result.push(c);
+ } else {
+ var _g4 = 0;
+ var _g5 = c.aliases;
+ while(_g4 < _g5.length) if(_g5[_g4++].toLowerCase() == searchCmd) {
+ result.push(c);
+ break;
+ }
+ }
+ }
+ }
+ return result;
+};
+client_Commands.formatDescWithHighlight = function(desc,activeArgIndex) {
+ desc = StringTools.htmlEscape(desc);
+ var argCounter = 0;
+ desc = new EReg("&lt;[^&]+&gt;","g").map(desc,function(reg) {
+ var token = reg.matched(0);
+ var isCurrent = argCounter == activeArgIndex;
+ argCounter += 1;
+ if(isCurrent) {
+ return "<span class=\"chat-command-arg-active\">" + token + "</span>";
} else {
- el.classList.remove("mobile-view");
+ return token;
}
- };
+ });
+ return new EReg("`([^`]+)`","g").map(desc,function(reg) {
+ return "<span class=\"chat-command-code\">" + reg.matched(1) + "</span>";
+ });
};
var client_FileUploader = function(main) {
this.main = main;
@@ -1102,52 +1481,104 @@ client_FileUploader.prototype = {
return;
}
var _this_r = new RegExp("[?#%/\\\\]","g".split("u").join(""));
- var name = StringTools.trim(file.name.replace(_this_r,""));
- if(name.length == 0) {
- name = "video";
+ var title = StringTools.trim(file.name.replace(_this_r,""));
+ if(title.length == 0) {
+ title = "video";
}
- name = window.encodeURIComponent(name);
+ var name = window.encodeURIComponent(title);
+ var isTemp = client_Main.isTempChecked(window.document.querySelector("#addfromurl .add-temp"));
this.uploadLastChunk(file,name,function(data) {
if(data.errorId != null) {
_gthis.main.serverMessage(data.info,true,false);
return;
}
- window.document.querySelector("#mediaurl").value = data.url;
- _gthis.uploadFullFile(name,file);
+ var url = data.url;
+ _gthis.getFileDuration(file,function(duration) {
+ if(duration == 0 || isNaN(duration) || !isFinite(duration)) {
+ _gthis.main.serverMessage(Lang.get("addVideoError"),true,false);
+ return;
+ }
+ _gthis.uploadFullFile(name,file,url,function() {
+ _gthis.main.addUploadedVideo(url,title,duration,true,isTemp);
+ });
+ });
});
}
- ,uploadFullFile: function(name,file) {
+ ,getFileDuration: function(file,callback) {
+ var objUrl = URL.createObjectURL(file);
+ var video = window.document.createElement("video");
+ video.preload = "metadata";
+ video.muted = true;
+ video.onloadedmetadata = function() {
+ var duration = video.duration;
+ URL.revokeObjectURL(objUrl);
+ callback(duration);
+ };
+ video.onerror = function(e) {
+ URL.revokeObjectURL(objUrl);
+ callback(0);
+ };
+ video.src = objUrl;
+ }
+ ,uploadFullFile: function(name,file,url,onStarted) {
var _gthis = this;
var request = new XMLHttpRequest();
request.open("POST","/upload",true);
request.setRequestHeader("content-name",name);
var tmp = this.main.settings.uuid;
request.setRequestHeader("x-client-uuid",tmp != null ? tmp : "");
+ var added = false;
+ var ensureAdded = function() {
+ if(added) {
+ return;
+ }
+ added = true;
+ onStarted();
+ _gthis.main.registerUpload(url,function() {
+ request.abort();
+ });
+ };
+ var sendProgress = function(type,ratio) {
+ _gthis.main.send({ type : "Progress", progress : { type : type, ratio : ratio, url : url}});
+ };
+ var lastSentRatio = 0.0;
request.upload.onprogress = function(event) {
+ ensureAdded();
var ratio = 0.0;
if(event.lengthComputable) {
var v = event.loaded / event.total;
ratio = v < 0 ? 0 : v > 1 ? 1 : v;
}
- _gthis.main.onProgressEvent({ type : "Progress", progress : { type : "Uploading", ratio : ratio}});
+ if(ratio - lastSentRatio < 0.01 && ratio < 1) {
+ return;
+ }
+ lastSentRatio = ratio;
+ sendProgress("Uploading",ratio);
};
request.onload = function(e) {
+ _gthis.main.unregisterUpload(url);
var data;
try {
data = JSON.parse(request.responseText);
} catch( _g ) {
- haxe_Log.trace(haxe_Exception.caught(_g),{ fileName : "src/client/FileUploader.hx", lineNumber : 66, className : "client.FileUploader", methodName : "uploadFullFile"});
+ haxe_Log.trace(haxe_Exception.caught(_g),{ fileName : "src/client/FileUploader.hx", lineNumber : 112, className : "client.FileUploader", methodName : "uploadFullFile"});
+ sendProgress("Canceled",0);
return;
}
- if(data.errorId == null) {
+ if(data.errorId != null) {
+ _gthis.main.serverMessage(data.info,true,false);
+ sendProgress("Canceled",0);
return;
}
- _gthis.main.serverMessage(data.info,true,false);
+ ensureAdded();
+ sendProgress("Completed",1);
};
- request.onloadend = function() {
- return haxe_Timer.delay(function() {
- _gthis.main.hideDynamicChin();
- },500);
+ request.onerror = function(e) {
+ _gthis.main.unregisterUpload(url);
+ sendProgress("Canceled",0);
+ };
+ request.onabort = function(e) {
+ _gthis.main.unregisterUpload(url);
};
request.send(file);
}
@@ -1163,7 +1594,7 @@ client_FileUploader.prototype = {
});
}
};
-var client_InputWithHistory = function(element,history,maxItems,onEnter) {
+var client_InputWithHistory = function(element,history,maxItems,onEnter,onInterceptKeyDown) {
this.historyId = -1;
this.element = element;
if(history != null) {
@@ -1173,6 +1604,7 @@ var client_InputWithHistory = function(element,history,maxItems,onEnter) {
}
this.maxItems = maxItems;
this.onEnter = onEnter;
+ this.onInterceptKeyDown = onInterceptKeyDown;
element.onkeydown = $bind(this,this.onKeyDown);
};
client_InputWithHistory.__name__ = true;
@@ -1184,6 +1616,9 @@ client_InputWithHistory.pushIfNotLast = function(arr,item) {
};
client_InputWithHistory.prototype = {
onKeyDown: function(e) {
+ if(this.onInterceptKeyDown != null && this.onInterceptKeyDown(e)) {
+ return;
+ }
var key = e.keyCode;
switch(key) {
case 13:
@@ -1201,6 +1636,9 @@ client_InputWithHistory.prototype = {
this.element.value = "";
this.onInput();
break;
+ case 27:
+ e.preventDefault();
+ break;
case 38:
this.historyId--;
if(this.historyId == -2) {
@@ -1231,9 +1669,7 @@ client_InputWithHistory.prototype = {
}
}
,onInput: function() {
- if(this.element.oninput != null) {
- this.element.oninput();
- }
+ this.element.dispatchEvent(new Event("input"));
}
};
var client_JsApi = function() { };
@@ -1268,9 +1704,10 @@ client_JsApi.addScriptToHead = $hx_exports["client"]["JsApi"]["addScriptToHead"]
window.document.head.appendChild(script);
};
client_JsApi.hasScriptInHead = $hx_exports["client"]["JsApi"]["hasScriptInHead"] = function(url) {
+ var abs = new URL(url,window.document.baseURI).href;
var _g = 0;
var _g1 = window.document.getElementsByTagName("head")[0].children;
- while(_g < _g1.length) if(_g1[_g++].src == url) {
+ while(_g < _g1.length) if(_g1[_g++].src == abs) {
return true;
}
return false;
@@ -1282,11 +1719,11 @@ client_JsApi.getVideoItems = $hx_exports["client"]["JsApi"]["getVideoItems"] = f
while(_g1 < items.length) _g.push(Reflect.copy(items[_g1++]));
return _g;
};
-client_JsApi.addVideoItem = $hx_exports["client"]["JsApi"]["addVideoItem"] = function(url,atEnd,isTemp,callback,doCache) {
+client_JsApi.addVideoItem = $hx_exports["client"]["JsApi"]["addVideoItem"] = function(url,atEnd,isTemp,afterSend,doCache) {
if(doCache == null) {
doCache = false;
}
- client_JsApi.main.addVideo(url,atEnd,isTemp,doCache,callback);
+ client_JsApi.main.addVideo(url,atEnd,isTemp,doCache,afterSend);
};
client_JsApi.removeVideoItem = $hx_exports["client"]["JsApi"]["removeVideoItem"] = function(url) {
client_JsApi.main.removeVideoItem(url);
@@ -1329,24 +1766,24 @@ client_JsApi.once = $hx_exports["client"]["JsApi"]["once"] = function(type,callb
client_JsApi.onceListeners.unshift({ type : type, callback : callback});
};
client_JsApi.fireEvents = function(event) {
- var _g_arr = client_JsApi.onListeners;
- var _g_i = _g_arr.length - 1;
+ var listeners = client_JsApi.onListeners.slice();
+ var _g_i = listeners.length - 1;
while(_g_i > -1) {
- var listener = _g_arr[_g_i--];
+ var listener = listeners[_g_i--];
if(listener.type != event.type) {
continue;
}
listener.callback(event);
}
- var _g_arr = client_JsApi.onceListeners;
- var _g_i = _g_arr.length - 1;
+ var onces = client_JsApi.onceListeners.slice();
+ var _g_i = onces.length - 1;
while(_g_i > -1) {
- var listener = _g_arr[_g_i--];
+ var listener = onces[_g_i--];
if(listener.type != event.type) {
continue;
}
- listener.callback(event);
HxOverrides.remove(client_JsApi.onceListeners,listener);
+ listener.callback(event);
}
};
client_JsApi.notifyOnVideoChange = $hx_exports["client"]["JsApi"]["notifyOnVideoChange"] = function(callback) {
@@ -1373,6 +1810,7 @@ client_JsApi.fireVideoRemoveEvents = function(item) {
};
var client_Main = function() {
this.matchSimpleDate = new EReg("^-?([0-9]+d)?([0-9]+h)?([0-9]+m)?([0-9]+s?)?$","");
+ this.activeUploads = new haxe_ds_StringMap();
this.urlMask = new EReg("\\${([0-9]+)-([0-9]+)}","g");
this.isPageVisible = true;
this.isPageUnloading = false;
@@ -1388,6 +1826,9 @@ var client_Main = function() {
this.lastStateTimeStamp = 0.0;
this.lastState = { time : 0, rate : 1.0, paused : false, pausedByServer : false};
this.timeFromLastState = 0.0;
+ this.skipVoteRequired = 0;
+ this.skipVoteCount = 0;
+ this.hasSeenSkipVote = false;
this.showingServerPause = false;
this.playersCacheSupport = [];
this.isPlaylistOpen = true;
@@ -1403,7 +1844,7 @@ var client_Main = function() {
if(this.host == "") {
this.host = "localhost";
}
- client_Settings.init({ version : 6, uuid : null, name : "", hash : "", chatSize : 300, synchThreshold : 1, isSwapped : false, isUserListHidden : true, latestLinks : [], latestSubs : [], hotkeysEnabled : true, showHintList : true, checkboxes : [], checkedCache : []},$bind(this,this.settingsPatcher));
+ client_Settings.init({ version : 7, uuid : null, name : "", hash : "", chatSize : 300, synchThreshold : 1, isSwapped : false, isUserListHidden : true, latestLinks : [], latestSubs : [], hotkeysEnabled : true, pageFullscreen : false, fullscreenAction : client_Utils.isTouch(), showHintList : true, checkboxes : [], checkedCache : []},$bind(this,this.settingsPatcher));
this.settings = client_Settings.read();
this.initListeners();
this.onTimeGet = new haxe_Timer(this.settings.synchThreshold * 1000);
@@ -1443,6 +1884,17 @@ client_Main.__name__ = true;
client_Main.main = function() {
new client_Main();
};
+client_Main.isTempChecked = function(checkbox) {
+ if(checkbox == null) {
+ return true;
+ }
+ var isHidden = checkbox.style.display == "none";
+ if(isHidden) {
+ return true;
+ } else {
+ return checkbox.checked;
+ }
+};
client_Main.prototype = {
onFirstInteraction: function() {
if(this.gotFirstPageInteraction) {
@@ -1460,32 +1912,18 @@ client_Main.prototype = {
}
,settingsPatcher: function(data,version) {
switch(version) {
- case 1:
- data.hotkeysEnabled = true;
- break;
- case 2:
- data.latestSubs = [];
- break;
- case 3:
- data.showHintList = true;
- break;
- case 4:
- data.checkboxes = [];
+ case 1:case 2:case 3:case 4:
break;
case 5:
- var data1 = data;
- data1.checkedCache = [];
- Reflect.deleteField(data1,"playerSize");
- Reflect.deleteField(data1,"isExtendedPlayer");
- var oldCheck = Lambda.find(data1.checkboxes,function(item) {
- return item.id == "cache-on-server";
- });
- if(oldCheck != null) {
- HxOverrides.remove(data1.checkboxes,oldCheck);
- data1.checkedCache.push("YoutubeType");
- }
+ client_Settings.reset();
+ data = client_Settings.read();
break;
case 6:
+ var data1 = data;
+ data1.pageFullscreen = false;
+ data1.fullscreenAction = client_Utils.isTouch();
+ break;
+ case 7:
throw haxe_Exception.thrown("skipped version " + version);
default:
throw haxe_Exception.thrown("skipped version " + version);
@@ -1499,6 +1937,9 @@ client_Main.prototype = {
if(this.player.isListEmpty()) {
return;
}
+ if(!_$Types_VideoItemTools.isPlayable(this.player.getCurrentItem())) {
+ return;
+ }
this.send({ type : "GetTime"});
}
,openWebSocket: function() {
@@ -1545,6 +1986,7 @@ client_Main.prototype = {
}
,initListeners: function() {
var _gthis = this;
+ this.chatInput = new client_ChatInput(this);
client_Buttons.init(this);
var openBtn = window.document.getElementById("openChatBtn");
var openBtnFadeTimer = null;
@@ -1625,9 +2067,7 @@ client_Main.prototype = {
e.preventDefault();
};
window.document.querySelector("#voteskip").onclick = function(e) {
- if(client_Utils.isTouch() && !window.confirm(Lang.get("skipItemConfirm"))) {
- return;
- }
+ _gthis.hasSeenSkipVote = true;
if(_gthis.player.isListEmpty()) {
return;
}
@@ -1697,7 +2137,7 @@ client_Main.prototype = {
,addVideoUrl: function(atEnd) {
var mediaUrl = window.document.querySelector("#mediaurl");
var subsUrl = window.document.querySelector("#subsurl");
- var isTemp = window.document.querySelector("#addfromurl .add-temp").checked;
+ var isTemp = client_Main.isTempChecked(window.document.querySelector("#addfromurl .add-temp"));
var checkboxCache = window.document.querySelector("#cache-on-server");
var doCache = (this.personal.group & 8) != 0 && checkboxCache.checked && checkboxCache.parentElement.style.display != "none";
var url = mediaUrl.value;
@@ -1758,7 +2198,7 @@ client_Main.prototype = {
_gthis.addVideoArray(links,atEnd,isTemp,doCache);
});
}
- ,addVideo: function(url,atEnd,isTemp,doCache,callback) {
+ ,addVideo: function(url,atEnd,isTemp,doCache,afterSend) {
var _gthis = this;
var protocol = $global.location.protocol;
if(StringTools.startsWith(url,"/")) {
@@ -1771,26 +2211,60 @@ client_Main.prototype = {
url = "" + protocol + "//" + url;
}
}
- var obj = { url : url, atEnd : atEnd};
- if(doCache) {
- this.showProgressInfo(Lang.get("caching") + "...");
+ var sendItem = function(data) {
+ var tmp = data.url;
+ var tmp1 = data.title;
+ _gthis.send({ type : "AddVideo", addVideo : { item : { url : tmp != null ? tmp : url, title : tmp1 != null ? tmp1 : "", author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, doCache : doCache, subs : data.subs, voiceOverTrack : data.voiceOverTrack, playerType : data.playerType}, atEnd : atEnd}});
+ if(afterSend != null) {
+ afterSend();
+ }
+ };
+ var isServerResolvesMeta = doCache && this.isServerCacheServiceEnabled();
+ var linkPlayerType = this.getLinkPlayerType(url);
+ if(isServerResolvesMeta && (linkPlayerType == "VkType" || linkPlayerType == "VimeoType")) {
+ sendItem({ duration : 0, title : "", url : url, playerType : linkPlayerType});
+ return;
}
- this.player.getVideoData(obj,function(data) {
+ this.player.getVideoData({ url : url, atEnd : atEnd},function(data) {
if(data.duration == 0) {
- if(doCache) {
- _gthis.hideDynamicChin();
+ if(!isServerResolvesMeta) {
+ _gthis.serverMessage(Lang.get("addVideoError"));
+ return;
}
- _gthis.serverMessage(Lang.get("addVideoError"));
- return;
- }
- data.title = data.title != null ? data.title : Lang.get("rawVideo");
- data.url = data.url != null ? data.url : url;
- _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, doCache : doCache, subs : data.subs, voiceOverTrack : data.voiceOverTrack, playerType : data.playerType}, atEnd : atEnd}});
- if(callback != null) {
- callback();
+ } else {
+ data.title = data.title != null ? data.title : Lang.get("rawVideo");
}
+ sendItem(data);
+ });
+ }
+ ,isServerCacheServiceEnabled: function() {
+ return Lambda.exists(this.playersCacheSupport,function(type) {
+ return type != "RawType";
});
}
+ ,registerUpload: function(url,cancel) {
+ this.activeUploads.h[url] = cancel;
+ }
+ ,unregisterUpload: function(url) {
+ var _this = this.activeUploads;
+ if(Object.prototype.hasOwnProperty.call(_this.h,url)) {
+ delete(_this.h[url]);
+ }
+ }
+ ,cancelUpload: function(url) {
+ var tmp = this.activeUploads.h[url];
+ if(tmp == null) {
+ return;
+ }
+ var _this = this.activeUploads;
+ if(Object.prototype.hasOwnProperty.call(_this.h,url)) {
+ delete(_this.h[url]);
+ }
+ tmp();
+ }
+ ,addUploadedVideo: function(url,title,duration,atEnd,isTemp) {
+ this.send({ type : "AddVideo", addVideo : { item : { url : url, title : title, author : this.personal.name, duration : duration, isTemp : isTemp, doCache : false, isIncomplete : true, playerType : "RawType"}, atEnd : atEnd}});
+ }
,addIframe: function(atEnd) {
var _gthis = this;
var iframeCode = window.document.querySelector("#customembed-content");
@@ -1802,7 +2276,6 @@ client_Main.prototype = {
var mediaTitle = window.document.querySelector("#customembed-title");
var title = mediaTitle.value;
mediaTitle.value = "";
- var isTemp = window.document.querySelector("#customembed .add-temp").checked;
this.player.getIframeData({ url : iframe, atEnd : atEnd},function(data) {
if(data.duration == 0) {
_gthis.serverMessage(Lang.get("addVideoError"));
@@ -1813,7 +2286,7 @@ client_Main.prototype = {
}
data.title = data.title != null ? data.title : "Custom Media";
data.url = data.url != null ? data.url : iframe;
- _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, doCache : false, playerType : "IframeType"}, atEnd : atEnd}});
+ _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : true, doCache : false, playerType : "IframeType"}, atEnd : atEnd}});
});
}
,removeVideoItem: function(url) {
@@ -1854,7 +2327,7 @@ client_Main.prototype = {
var data = JSON.parse(e.data);
if(this.config != null && this.config.isVerbose) {
var t = data.type;
- haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 547, className : "client.Main", methodName : "onMessage", customParams : [Reflect.field(data,t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null))]});
+ haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 599, className : "client.Main", methodName : "onMessage", customParams : [Reflect.field(data,t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null))]});
}
client_JsApi.fireEvents(data);
switch(data.type) {
@@ -1870,7 +2343,9 @@ client_Main.prototype = {
this.clearChat();
break;
case "ClearPlaylist":
+ this.resetSkipVoteUi();
this.player.clearItems();
+ this.updateServerPauseUi();
if(this.player.isListEmpty()) {
this.player.pause();
}
@@ -1892,20 +2367,10 @@ client_Main.prototype = {
data.getTime.paused = data.getTime.paused != null && data.getTime.paused;
data.getTime.pausedByServer = data.getTime.pausedByServer != null && data.getTime.pausedByServer;
data.getTime.rate = data.getTime.rate != null ? data.getTime.rate : 1;
- var isPauseChanged = this.lastState.paused != data.getTime.paused;
this.lastState.time = data.getTime.time;
- this.lastState.paused = data.getTime.paused;
- this.lastState.pausedByServer = data.getTime.pausedByServer;
this.lastState.rate = data.getTime.rate;
this.updateLastStateTime();
- if(isPauseChanged) {
- this.updateUserList();
- }
- if(data.getTime.pausedByServer) {
- this.showServerUnpause();
- } else if(this.showingServerPause) {
- this.hideDynamicChin();
- }
+ this.updatePauseState(data.getTime.paused,data.getTime.pausedByServer);
if(this.player.getPlaybackRate() != data.getTime.rate) {
this.player.setPlaybackRate(data.getTime.rate);
}
@@ -1974,10 +2439,8 @@ client_Main.prototype = {
break;
case "Pause":
this.lastState.time = data.pause.time;
- this.lastState.paused = true;
this.updateLastStateTime();
- this.player.setPauseIndicator(this.lastState.paused);
- this.updateUserList();
+ this.updatePauseState(true,this.lastState.pausedByServer);
if((this.personal.group & 4) != 0) {
return;
}
@@ -1986,10 +2449,8 @@ client_Main.prototype = {
break;
case "Play":
this.lastState.time = data.play.time;
- this.lastState.paused = false;
this.updateLastStateTime();
- this.player.setPauseIndicator(this.lastState.paused);
- this.updateUserList();
+ this.updatePauseState(false);
if((this.personal.group & 4) != 0) {
return;
}
@@ -2001,13 +2462,21 @@ client_Main.prototype = {
this.player.play();
break;
case "PlayItem":
+ this.resetSkipVoteUi();
this.player.setVideo(data.playItem.pos);
break;
case "Progress":
this.onProgressEvent(data);
break;
case "RemoveVideo":
+ var tmp = this.player.getCurrentItem();
+ var isCurrent = (tmp != null ? tmp.url : null) == data.removeVideo.url;
+ this.cancelUpload(data.removeVideo.url);
this.player.removeItem(data.removeVideo.url);
+ if(isCurrent) {
+ this.resetSkipVoteUi();
+ }
+ this.updateServerPauseUi();
if(this.player.isListEmpty()) {
this.player.pause();
}
@@ -2038,6 +2507,9 @@ client_Main.prototype = {
if((this.personal.group & 4) != 0) {
this.player.onSetTime();
}
+ if(!this.hasLeader()) {
+ this.updatePauseState(this.lastState.paused);
+ }
break;
case "SetNextItem":
this.player.setNextItem(data.setNextItem.pos);
@@ -2061,11 +2533,28 @@ client_Main.prototype = {
case "ShufflePlaylist":
break;
case "SkipVideo":
+ this.resetSkipVoteUi();
this.player.skipItem(data.skipVideo.url);
+ this.updateServerPauseUi();
if(this.player.isListEmpty()) {
this.player.pause();
}
break;
+ case "SkipVideoStats":
+ if(data.skipVideoStats.voted == 1 && this.skipVoteCount == 0) {
+ this.serverMessage(Lang.get("skipVoteInitiated"));
+ }
+ this.skipVoteCount = data.skipVideoStats.voted;
+ this.skipVoteRequired = data.skipVideoStats.required;
+ var tmp = "" + ("(" + this.skipVoteCount + "/" + this.skipVoteRequired + ")") + " ";
+ var tmp1 = Lang.get("voteForSkip");
+ window.document.querySelector("#voteskip-text").textContent = tmp + tmp1;
+ var indicator = window.document.querySelector("#playlist-menu-indicator");
+ var dropdown = window.document.querySelector("#playlist-menu-dropdown");
+ if(!this.hasSeenSkipVote && dropdown.style.display == "none") {
+ indicator.style.display = "";
+ }
+ break;
case "ToggleItemType":
this.player.toggleItemType(data.toggleItemType.pos);
break;
@@ -2084,10 +2573,10 @@ client_Main.prototype = {
this.player.setItems(data.updatePlaylist.videoList);
break;
case "VideoLoaded":
- this.lastState.paused = false;
- this.lastState.pausedByServer = false;
+ this.resetSkipVoteUi();
this.lastState.time = 0;
this.updateLastStateTime();
+ this.updatePauseState(false);
this.player.setTime(0);
this.player.play();
if((this.personal.group & 4) != 0 && !this.player.isVideoLoaded()) {
@@ -2097,33 +2586,21 @@ client_Main.prototype = {
}
}
,onProgressEvent: function(data) {
- var _gthis = this;
var data1 = data.progress;
- var text;
+ var tmp = data1.url;
+ if(tmp == null) {
+ return;
+ }
switch(data1.type) {
- case "Caching":
- text = "" + Lang.get("caching") + " " + data1.data;
- break;
case "Canceled":
- this.hideDynamicChin();
- return;
- case "Downloading":
- text = Lang.get("downloading");
+ this.player.removeItem(tmp);
break;
- case "Uploading":
- text = Lang.get("uploading");
+ case "Completed":
+ this.player.completeItem(tmp);
+ break;
+ case "Caching":case "Downloading":case "Uploading":
+ this.player.setItemProgress(tmp,data1.ratio);
break;
- }
- var percent = tools_MathTools.toFixed(data1.ratio * 100,1);
- var text1 = "" + text + "...";
- if(percent > 0) {
- text1 += " " + percent + "%";
- }
- this.showProgressInfo(text1);
- if(data1.ratio == 1) {
- haxe_Timer.delay(function() {
- _gthis.hideDynamicChin();
- },500);
}
}
,updateLastStateTime: function() {
@@ -2451,9 +2928,12 @@ client_Main.prototype = {
if((client.group & 8) != 0) {
klass += " userlist_owner";
}
- list_b += Std.string("<span class=\"" + klass + "\">" + client.name + "</span></div>");
+ list_b += Std.string("<span class=\"" + klass + "\">" + StringTools.htmlEscape(client.name) + "</span></div>");
}
window.document.querySelector("#userlist").innerHTML = list_b;
+ if(this.player != null) {
+ this.player.updateTitle();
+ }
}
,getPageTitle: function() {
return "" + this.pageTitle + " (" + this.clients.length + ")";
@@ -2519,6 +2999,9 @@ client_Main.prototype = {
if(this.onBlinkTab == null) {
this.blinkTabWithTitle("*" + Lang.get("chat") + "*");
}
+ if(name != this.personal.name) {
+ client_Buttons.onNewChatMessage();
+ }
}
,getFirstMessageDiv: function() {
if(this.isMessageBufferReversed()) {
@@ -2558,43 +3041,66 @@ client_Main.prototype = {
return btn.style.display = "none";
},{ once : true});
}
- ,showProgressInfo: function(text) {
- var chin = window.document.querySelector("#dynamic-chin");
- var div = chin.querySelector("#progress-info");
- if(div == null) {
- div = window.document.createElement("div");
- div.id = "progress-info";
- chin.prepend(div);
+ ,resetSkipVoteUi: function() {
+ this.hasSeenSkipVote = false;
+ this.skipVoteCount = 0;
+ this.skipVoteRequired = 0;
+ window.document.querySelector("#voteskip-text").textContent = Lang.get("voteForSkip");
+ window.document.querySelector("#playlist-menu-indicator").style.display = "none";
+ }
+ ,updatePauseState: function(paused,pausedByServer) {
+ if(pausedByServer == null) {
+ pausedByServer = false;
+ }
+ var isPauseChanged = this.lastState.paused != paused;
+ this.lastState.paused = paused;
+ this.lastState.pausedByServer = pausedByServer;
+ this.player.setPauseIndicator(this.lastState.paused);
+ if(isPauseChanged) {
+ this.updateUserList();
}
- div.textContent = text;
- this.showDynamicChin();
+ this.updateServerPauseUi();
}
- ,showServerUnpause: function() {
- var _gthis = this;
- if(this.showingServerPause) {
+ ,updateServerPauseUi: function() {
+ var show = this.lastState.pausedByServer && !this.player.isListEmpty();
+ if(this.showingServerPause == show) {
return;
}
- this.showingServerPause = true;
+ this.showingServerPause = show;
+ this.renderDynamicChin();
+ }
+ ,renderDynamicChin: function() {
+ var _gthis = this;
var chin = window.document.querySelector("#dynamic-chin");
+ if(!this.showingServerPause) {
+ this.hideDynamicChinAnim();
+ return;
+ }
chin.innerHTML = "";
+ var wrapper = window.document.createElement("div");
+ wrapper.style.display = "flex";
+ wrapper.style.flexDirection = "column";
+ wrapper.style.gap = "0.5rem";
var div = window.document.createElement("div");
div.className = "server-whisper";
+ div.style.textAlign = "center";
div.textContent = Lang.get("leaderDisconnectedServerOnPause");
- chin.appendChild(div);
+ wrapper.appendChild(div);
var btn = window.document.createElement("button");
btn.id = "unpause-server";
btn.textContent = Lang.get("unpause");
- chin.appendChild(btn);
+ wrapper.appendChild(btn);
btn.onclick = function() {
- _gthis.hideDynamicChin();
+ _gthis.updatePauseState(_gthis.lastState.paused,false);
_gthis.send({ type : "SetLeader", setLeader : { clientName : _gthis.personal.name}});
client_JsApi.once("SetLeader",function(event) {
_gthis.removeLeader();
});
};
- this.showDynamicChin();
+ chin.appendChild(wrapper);
+ this.showDynamicChinAnim();
}
- ,showDynamicChin: function() {
+ ,showDynamicChinAnim: function() {
var chin = window.document.querySelector("#dynamic-chin");
if(chin.style.display == "") {
return;
@@ -2619,9 +3125,11 @@ client_Main.prototype = {
};
chin.addEventListener("transitionend",onTransitionEnd);
}
- ,hideDynamicChin: function() {
- this.showingServerPause = false;
+ ,hideDynamicChinAnim: function() {
var chin = window.document.querySelector("#dynamic-chin");
+ if(chin.style.display == "none") {
+ return;
+ }
var h = chin.clientHeight;
chin.style.height = "" + h + "px";
haxe_Timer.delay(function() {
@@ -2686,79 +3194,81 @@ client_Main.prototype = {
if(!StringTools.startsWith(command,"/")) {
return false;
}
- var args = StringTools.trim(command).split(" ");
- command = HxOverrides.substr(args.shift(),1,null);
- if(command.length == 0) {
- return false;
- }
- switch(command) {
- case "ad":
- this.player.skipAd();
- return false;
- case "ban":
- this.mergeRedundantArgs(args,0,2);
- var name = args[0];
- var time = this.parseSimpleDate(args[1]);
- if(time < 0) {
- return true;
+ var parsed = client_Commands.parse(command);
+ var args = parsed.args;
+ var tmp = parsed.cmd;
+ var _g = tmp != null ? tmp.name : null;
+ if(_g == null) {
+ var cmdNameWithoutSlash = HxOverrides.substr(parsed.rawCmd,1,null);
+ if(this.matchSimpleDate.match(cmdNameWithoutSlash)) {
+ this.send({ type : "Rewind", rewind : { time : this.parseSimpleDate(cmdNameWithoutSlash)}});
}
- this.send({ type : "BanClient", banClient : { name : name, time : time}});
- return true;
- case "clear":
- this.send({ type : "ClearChat"});
- return true;
- case "crash":
- this.send({ type : "CrashTest"});
- return true;
- case "dump":
- this.send({ type : "Dump"});
- return true;
- case "fb":case "flashback":
- this.send({ type : "Flashback"});
return false;
- case "giveup":
- this.mergeRedundantArgs(args,0,1);
- var tmp = args[0];
- this.send({ type : "SetLeader", setLeader : { clientName : tmp != null ? tmp : ""}});
- return true;
- case "help":
- this.showChatHintList();
- return true;
- case "kick":
- this.mergeRedundantArgs(args,0,1);
- this.send({ type : "KickClient", kickClient : { name : args[0]}});
- return true;
- case "removeBan":case "unban":
- this.mergeRedundantArgs(args,0,1);
- this.send({ type : "BanClient", banClient : { name : args[0], time : 0}});
- return true;
- case "volume":
- var v = parseFloat(args[0]);
- if(isNaN(v)) {
- v = 1;
- }
- if(v < 0) {
- v = 0;
- } else if(v > 3) {
- v = 3;
- }
- var wasNotFull = this.player.getVolume() < 1;
- this.player.setVolume(v < 0 ? 0 : v > 1 ? 1 : v);
- if(this.player.getPlayerType() != "RawType") {
+ } else {
+ switch(_g) {
+ case "/ad":
+ this.player.skipAd();
+ return false;
+ case "/ban":
+ this.mergeRedundantArgs(args,0,2);
+ var name = args[0];
+ var time = this.parseSimpleDate(args[1]);
+ if(time < 0) {
+ return true;
+ }
+ this.send({ type : "BanClient", banClient : { name : name, time : time}});
return true;
- }
- if(wasNotFull && v > 1) {
- this.serverMessage("Volume was not maxed yet to be boosted, you can send command again.");
+ case "/clear":
+ this.send({ type : "ClearChat"});
+ return true;
+ case "/crash":
+ this.send({ type : "CrashTest"});
+ return true;
+ case "/dump":
+ this.send({ type : "Dump"});
+ return true;
+ case "/fb":
+ this.send({ type : "Flashback"});
+ return false;
+ case "/giveup":
+ this.mergeRedundantArgs(args,0,1);
+ var tmp = args[0];
+ this.send({ type : "SetLeader", setLeader : { clientName : tmp != null ? tmp : ""}});
+ return true;
+ case "/help":
+ this.showChatHintList();
+ return true;
+ case "/kick":
+ this.mergeRedundantArgs(args,0,1);
+ this.send({ type : "KickClient", kickClient : { name : args[0]}});
+ return true;
+ case "/unban":
+ this.mergeRedundantArgs(args,0,1);
+ this.send({ type : "BanClient", banClient : { name : args[0], time : 0}});
+ return true;
+ case "/volume":
+ var v = parseFloat(args[0]);
+ if(isNaN(v)) {
+ v = 1;
+ }
+ if(v < 0) {
+ v = 0;
+ } else if(v > 3) {
+ v = 3;
+ }
+ var wasNotFull = this.player.getVolume() < 1;
+ this.player.setVolume(v < 0 ? 0 : v > 1 ? 1 : v);
+ if(this.player.getPlayerType() != "RawType") {
+ return true;
+ }
+ if(wasNotFull && v > 1) {
+ this.serverMessage("Volume was not maxed yet to be boosted, you can send command again.");
+ return true;
+ }
+ this.player.rawPlayer.boostVolume(v);
return true;
}
- this.player.rawPlayer.boostVolume(v);
- return true;
}
- if(this.matchSimpleDate.match(command)) {
- this.send({ type : "Rewind", rewind : { time : this.parseSimpleDate(command)}});
- return false;
- }
- return false;
}
,parseSimpleDate: function(text) {
if(text == null) {
@@ -2870,6 +3380,9 @@ client_Main.prototype = {
,hasLeader: function() {
return ClientTools.hasLeader(this.clients);
}
+ ,getLeader: function() {
+ return ClientTools.getLeader(this.clients);
+ }
,hasLeaderOnPauseRequest: function() {
if(this.config.requestLeaderOnPause) {
return this.isPageVisible && !this.isPageUnloading;
@@ -2900,9 +3413,6 @@ client_Main.prototype = {
}
return this.gotFirstPageInteraction;
}
- ,isVerbose: function() {
- return this.config.isVerbose;
- }
,escapeRegExp: function(regex) {
var _this_r = new RegExp("([.*+?^${}()|[\\]\\\\])","g".split("u").join(""));
return regex.replace(_this_r,"\\$1");
@@ -2923,9 +3433,9 @@ var client_Player = function(main) {
var _gthis = this;
this.main = main;
this.youtube = new client_players_Youtube(main,this);
- this.players = [this.youtube,new client_players_Vk(main,this),new client_players_Streamable(main,this),new client_players_Peertube(main,this)];
this.iframePlayer = new client_players_Iframe(main,this);
this.rawPlayer = new client_players_Raw(main,this);
+ this.players = [this.youtube,new client_players_Vimeo(main,this),new client_players_Vk(main,this),new client_players_Streamable(main,this),new client_players_Peertube(main,this),this.iframePlayer];
this.initItemButtons();
var resizeObserver = client_Utils.createResizeObserver(function(entries) {
if(_gthis.isVideoLoaded() || _gthis.videoList.items.length == 0) {
@@ -2949,6 +3459,22 @@ var client_Player = function(main) {
_gthis.inUserInteraction = false;
},350);
},{ });
+ this.playerEl.oncontextmenu = function(e) {
+ if(!main.settings.fullscreenAction) {
+ return;
+ }
+ e.preventDefault();
+ var isPlayerFs = window.document.fullscreenElement == _gthis.playerEl;
+ if(isPlayerFs) {
+ if(main.settings.pageFullscreen) {
+ client_Utils.switchToPageFullscreen();
+ } else {
+ client_Utils.cancelFullscreen();
+ }
+ } else {
+ client_Utils.requestFullscreen(_gthis.playerEl);
+ }
+ };
};
client_Player.__name__ = true;
client_Player.prototype = {
@@ -2965,13 +3491,20 @@ client_Player.prototype = {
_gthis.main.send({ type : "SetNextItem", setNextItem : { pos : i}});
}
if(btn.classList.contains("qbtn-tmp")) {
- _gthis.main.send({ type : "ToggleItemType", toggleItemType : { pos : i}});
+ if(e.altKey || e.shiftKey) {
+ _gthis.toggleAllItemTypes(i);
+ } else {
+ _gthis.main.send({ type : "ToggleItemType", toggleItemType : { pos : i}});
+ }
}
if(btn.classList.contains("qbtn-delete")) {
_gthis.main.removeVideoItem(item.querySelector(".qe_title").getAttribute("href"));
}
};
}
+ ,toggleAllItemTypes: function(pos) {
+ this.main.send({ type : "ToggleItemType", toggleItemType : { pos : pos, all : true}});
+ }
,setNextItem: function(pos) {
this.videoList.setNextItem(pos);
var next = this.videoItemsEl.children[pos];
@@ -3055,10 +3588,12 @@ client_Player.prototype = {
return;
}
var item = this.videoList.items[i];
+ if(!_$Types_VideoItemTools.isPlayable(item)) {
+ return;
+ }
this.setSupportedPlayer(item.url,item.playerType);
- this.removeActiveLabel(this.videoList.pos);
this.videoList.setPos(i);
- this.addActiveLabel(this.videoList.pos);
+ this.addActiveItemLabel();
this.canBePlayedSent = false;
if(this.main.isVideoEnabled) {
this.player.loadVideo(item);
@@ -3067,7 +3602,7 @@ client_Player.prototype = {
this.onCanBePlayed();
}
client_JsApi.fireVideoChangeEvents(item);
- window.document.querySelector("#currenttitle").textContent = item.title;
+ this.updateTitle();
}
,setExternalAudioTrack: function(item) {
var _gthis = this;
@@ -3089,7 +3624,7 @@ client_Player.prototype = {
return _gthis.isAudioTrackLoaded = true;
};
this.audioTrack.onerror = function(e) {
- haxe_Log.trace(e,{ fileName : "src/client/Player.hx", lineNumber : 220, className : "client.Player", methodName : "setExternalAudioTrack"});
+ haxe_Log.trace(e,{ fileName : "src/client/Player.hx", lineNumber : 255, className : "client.Player", methodName : "setExternalAudioTrack"});
_gthis.audioTrack.oncanplay = null;
_gthis.audioTrack.onerror = null;
_gthis.isAudioTrackLoaded = false;
@@ -3139,19 +3674,41 @@ client_Player.prototype = {
var _this = this.videoList;
client_JsApi.fireVideoRemoveEvents(_this.items[_this.pos]);
this.player.removeVideo();
- window.document.querySelector("#currenttitle").textContent = Lang.get("nothingPlaying");
+ this.updateTitle();
this.setPauseIndicator(false);
}
+ ,updateTitle: function() {
+ var baseTitle;
+ if(this.isListEmpty()) {
+ baseTitle = Lang.get("nothingPlaying");
+ } else {
+ var _this = this.videoList;
+ baseTitle = _this.items[_this.pos].title;
+ }
+ if(!this.main.lastState.paused) {
+ window.document.querySelector("#currenttitle").textContent = baseTitle;
+ return;
+ }
+ var pauserName = Lang.get("server");
+ if(!this.main.lastState.pausedByServer) {
+ var leader = this.main.getLeader();
+ if(leader != null) {
+ pauserName = leader.name;
+ }
+ }
+ var tmp = "" + ("<span class=\"paused-by\">" + StringTools.htmlEscape(StringTools.replace(Lang.get("pausedBy"),"$NAME",pauserName)) + "</span>") + " ";
+ var tmp1 = StringTools.htmlEscape(baseTitle);
+ window.document.querySelector("#currenttitle").innerHTML = tmp + tmp1;
+ }
,setPauseIndicator: function(isPause) {
if(!this.main.isSyncActive) {
return;
}
- var state = isPause ? "pause" : "play";
- window.document.querySelector("#pause-indicator").setAttribute("name",state);
- var el2 = window.document.querySelector("#pause-indicator-portrait");
- el2.setAttribute("name",state);
+ var el = window.document.querySelector("#pause-indicator-chat");
+ el.setAttribute("name",isPause ? "pause" : "play");
var tmp = isPause || this.main.hasLeader() ? "" : "none";
- el2.style.display = tmp;
+ el.style.display = tmp;
+ this.updateTitle();
}
,onCanBePlayed: function() {
if(!this.canBePlayedSent) {
@@ -3285,8 +3842,9 @@ client_Player.prototype = {
,addVideoItem: function(item,atEnd) {
var url = StringTools.htmlEscape(item.url,true);
var duration = item.playerType == "IframeType" ? "" : this.duration(item.duration);
- var author = StringTools.htmlEscape(item.author);
- var itemEl = client_Utils.nodeFromString("<li class=\"queue_entry info\" title=\"" + Lang.get("addedBy") + ": " + author + "\">\n\t\t\t\t<header>\n\t\t\t\t\t<span class=\"qe_time\">" + duration + "</span>\n\t\t\t\t\t<h4><a class=\"qe_title\" href=\"" + url + "\" target=\"_blank\">" + StringTools.htmlEscape(item.title) + "</a></h4>\n\t\t\t\t\t<small class=\"qe_author\">" + Lang.get("addedBy") + ": " + author + "</small>\n\t\t\t\t</header>\n\t\t\t\t<span class=\"controls\">\n\t\t\t\t\t<button class=\"qbtn-play\" title=\"" + Lang.get("play") + "\"><ion-icon name=\"play\"></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-next\" title=\"" + Lang.get("setNext") + "\"><ion-icon name=\"arrow-up\"></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-tmp\"><ion-icon></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-delete\" title=\"" + Lang.get("delete") + "\"><ion-icon name=\"close\"></ion-icon></button>\n\t\t\t\t</span>\n\t\t\t</li>");
+ var author = StringTools.htmlEscape(item.author,true);
+ var isIncomplete = item.isIncomplete == true;
+ var itemEl = client_Utils.nodeFromString("<li class=\"queue_entry info" + (isIncomplete ? " queue_incomplete" : "") + "\" title=\"" + Lang.get("addedBy") + ": " + author + "\">\n\t\t\t\t" + (isIncomplete ? "<div class=\"qe_progress\"></div>" : "") + "<header>\n\t\t\t\t\t<span class=\"qe_time\">" + duration + "</span>\n\t\t\t\t\t<h4><a class=\"qe_title\" href=\"" + url + "\" target=\"_blank\">" + StringTools.htmlEscape(item.title) + "</a></h4>\n\t\t\t\t\t<small class=\"qe_author\">" + Lang.get("addedBy") + ": " + author + "</small>\n\t\t\t\t</header>\n\t\t\t\t<span class=\"controls\">\n\t\t\t\t\t<button class=\"qbtn-play\" title=\"" + Lang.get("play") + "\"><ion-icon name=\"play\"></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-next\" title=\"" + Lang.get("setNext") + "\"><ion-icon name=\"arrow-up\"></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-tmp\"><ion-icon></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-delete\" title=\"" + Lang.get("delete") + "\"><ion-icon name=\"close\"></ion-icon></button>\n\t\t\t\t</span>\n\t\t\t</li>");
this.videoList.addItem(item,atEnd);
this.setItemElementType(itemEl,item.isTemp);
if(atEnd) {
@@ -3318,17 +3876,61 @@ client_Player.prototype = {
this.setVideo(this.videoList.pos);
}
}
- ,removeElementItem: function(url) {
+ ,findItemElement: function(url) {
var _g = 0;
var _g1 = this.videoItemsEl.children;
while(_g < _g1.length) {
var child = _g1[_g];
++_g;
if(child.querySelector(".qe_title").getAttribute("href") == url) {
- this.videoItemsEl.removeChild(child);
- break;
+ return child;
+ }
+ }
+ return null;
+ }
+ ,removeElementItem: function(url) {
+ var tmp = this.findItemElement(url);
+ if(tmp == null) {
+ return;
+ }
+ this.videoItemsEl.removeChild(tmp);
+ }
+ ,setItemProgress: function(url,ratio) {
+ var tmp = this.findItemElement(url);
+ if(tmp == null) {
+ return;
+ }
+ var tmp1 = tmp.querySelector(".qe_progress");
+ if(tmp1 == null) {
+ return;
+ }
+ tmp1.style.width = "" + ratio * 100 + "%";
+ }
+ ,completeItem: function(url) {
+ var index = this.videoList.findIndex(function(item) {
+ return item.url == url;
+ });
+ if(index == -1) {
+ return;
+ }
+ var item = this.videoList.items[index];
+ if(item.isIncomplete != true) {
+ return;
+ }
+ var wasPlayable = _$Types_VideoItemTools.isPlayable(item);
+ item.isIncomplete = false;
+ var el = this.findItemElement(url);
+ if(el != null) {
+ el.classList.remove("queue_incomplete");
+ el.classList.add("queue_cached");
+ var bar = el.querySelector(".qe_progress");
+ if(bar != null) {
+ el.removeChild(bar);
}
}
+ if(index == this.videoList.pos && !wasPlayable) {
+ this.setVideo(index);
+ }
}
,skipItem: function(url) {
var pos = this.videoList.findIndex(function(item) {
@@ -3337,7 +3939,6 @@ client_Player.prototype = {
if(pos == -1) {
return;
}
- this.removeActiveLabel(this.videoList.pos);
this.videoList.setPos(pos);
var _this = this.videoList;
if(_this.items[_this.pos].isTemp) {
@@ -3350,16 +3951,19 @@ client_Player.prototype = {
}
this.setVideo(this.videoList.pos);
}
- ,addActiveLabel: function(pos) {
+ ,addActiveItemLabel: function() {
var childs = this.videoItemsEl.children;
- if(childs[this.videoList.pos] != null) {
- childs[this.videoList.pos].classList.add("queue_active");
+ var _g = 0;
+ while(_g < childs.length) {
+ var element = childs[_g];
+ ++_g;
+ if(element.classList.contains("queue_active")) {
+ element.classList.remove("queue_active");
+ break;
+ }
}
- }
- ,removeActiveLabel: function(pos) {
- var childs = this.videoItemsEl.children;
if(childs[this.videoList.pos] != null) {
- childs[this.videoList.pos].classList.remove("queue_active");
+ childs[this.videoList.pos].classList.add("queue_active");
}
}
,updateCounters: function() {
@@ -3392,7 +3996,7 @@ client_Player.prototype = {
if(currentUrl != _this.items[_this.pos].url) {
this.setVideo(this.videoList.pos);
} else {
- this.addActiveLabel(this.videoList.pos);
+ this.addActiveItemLabel();
}
}
,clearItems: function() {
@@ -3455,7 +4059,7 @@ client_Player.prototype = {
return this.videoList.pos;
}
,hasVideo: function() {
- return this.playerEl.children.length != 0;
+ return this.playerEl.querySelector("video, iframe, embed, object") != null;
}
,getDuration: function() {
if(this.videoList.pos >= this.videoList.items.length) {
@@ -3612,7 +4216,7 @@ client_Player.prototype = {
}
};
http.onError = function(msg) {
- haxe_Log.trace(msg,{ fileName : "src/client/Player.hx", lineNumber : 677, className : "client.Player", methodName : "skipAd"});
+ haxe_Log.trace(msg,{ fileName : "src/client/Player.hx", lineNumber : 756, className : "client.Player", methodName : "skipAd"});
};
http.request();
}
@@ -3710,6 +4314,12 @@ client_Settings.write = function(data) {
}
client_Settings.storage.setItem("data",JSON.stringify(data));
};
+client_Settings.reset = function() {
+ if(client_Settings.defaults == null) {
+ throw haxe_Exception.thrown("reset: default data is null");
+ }
+ client_Settings.write(client_Settings.defaults);
+};
var client_Split = function(settings) {
this.settings = settings;
this.split = new Split({ columnGutters : [{ element : window.document.querySelector(".gutter"), track : 1}], minSize : 200, snapOffset : 0, onDragEnd : $bind(this,this.saveSize)});
@@ -3801,23 +4411,48 @@ client_Utils.getIndex = function(parent,child) {
return i;
};
client_Utils.hasFullscreen = function() {
- var doc = window.document;
- if(!(window.document.fullscreenElement != null || doc.mozFullScreenElement != null)) {
- return doc.webkitFullscreenElement != null;
- } else {
- return true;
- }
+ return window.document.fullscreenElement != null;
};
client_Utils.requestFullscreen = function(el) {
- var el2 = el;
if(el.requestFullscreen != null) {
el.requestFullscreen();
- } else if(el2.webkitRequestFullscreen != null) {
- el2.webkitRequestFullscreen(HTMLElement.ALLOW_KEYBOARD_INPUT);
+ return true;
+ }
+ return false;
+};
+client_Utils.cancelFullscreen = function(el) {
+ if(window.document.exitFullscreen != null) {
+ window.document.exitFullscreen();
+ }
+};
+client_Utils.switchToPageFullscreen = function() {
+ var docEl = window.document.documentElement;
+ if(window.document.fullscreenElement == docEl) {
+ return;
+ }
+ if(window.document.fullscreenElement == null) {
+ client_Utils.requestFullscreen(docEl);
+ return;
+ }
+ var promise = window.document.exitFullscreen();
+ if(promise != null) {
+ promise.then(function(_) {
+ client_Utils.switchToPageFullscreen();
+ }).catch(function(_) {
+ return;
+ });
} else {
+ haxe_Timer.delay(function() {
+ client_Utils.switchToPageFullscreen();
+ },1);
+ }
+};
+client_Utils.toggleFullscreen = function(el) {
+ if(client_Utils.hasFullscreen()) {
+ client_Utils.cancelFullscreen(el);
return false;
}
- return true;
+ return client_Utils.requestFullscreen(el);
};
client_Utils.copyToClipboard = function(text) {
var clipboardData = window.clipboardData;
@@ -3941,18 +4576,38 @@ var client_players_Iframe = function(main,player) {
this.player = player;
};
client_players_Iframe.__name__ = true;
+client_players_Iframe.extractTwitchChannel = function(url) {
+ url = StringTools.trim(url);
+ if(!client_players_Iframe.matchTwitchChannel.match(url)) {
+ return "";
+ }
+ return client_players_Iframe.matchTwitchChannel.matched(1);
+};
client_players_Iframe.prototype = {
getPlayerType: function() {
return "IframeType";
}
,isSupportedLink: function(url) {
- return true;
+ var trimmed = StringTools.trim(url);
+ if(client_players_Iframe.extractTwitchChannel(trimmed).length > 0) {
+ return true;
+ }
+ if(StringTools.startsWith(trimmed,"<iframe") || StringTools.startsWith(trimmed,"<object")) {
+ return true;
+ }
+ return false;
}
,getVideoData: function(data,callback) {
+ var rawUrl = StringTools.trim(data.url);
+ var channel = client_players_Iframe.extractTwitchChannel(rawUrl);
+ if(channel.length > 0) {
+ callback({ duration : 356400, title : "Twitch: " + channel, url : "<iframe src=\"https://player.twitch.tv/?channel=" + channel + "&parent=www.example.com\" frameborder=\"0\" allowfullscreen=\"true\" scrolling=\"no\" height=\"378\" width=\"620\"></iframe>"});
+ return;
+ }
var iframe = window.document.createElement("div");
- iframe.innerHTML = StringTools.trim(data.url);
+ iframe.innerHTML = rawUrl;
if(this.isValidIframe(iframe)) {
- callback({ duration : 356400, title : "Iframe media"});
+ callback({ duration : 356400, title : "Iframe media", url : rawUrl});
} else {
callback({ duration : 0});
}
@@ -4799,6 +5454,245 @@ client_players_Streamable.prototype = $extend(client_players_Raw.prototype,{
http.request();
}
});
+var client_players_Vimeo = function(main,player) {
+ this.matchVimeoId = new EReg("vimeo\\.com/(?:channels/(?:\\w+/)?|groups/[^/]+/videos/|video/|ondemand/[^/]+/)?([0-9]+)","i");
+ this.matchVimeo = new EReg("(?:vimeo\\.com|player\\.vimeo\\.com)","i");
+ this.prevTime = 0;
+ this.volume = 1;
+ this.playbackRate = 1;
+ this.currentTime = 0;
+ this.isPausedState = true;
+ this.isLoaded = false;
+ this.playerEl = window.document.querySelector("#ytapiplayer");
+ this.main = main;
+ this.player = player;
+};
+client_players_Vimeo.__name__ = true;
+client_players_Vimeo.prototype = {
+ getPlayerType: function() {
+ return "VimeoType";
+ }
+ ,isSupportedLink: function(url) {
+ if(this.matchVimeo.match(url)) {
+ return this.extractVideoId(url).length > 0;
+ } else {
+ return false;
+ }
+ }
+ ,extractVideoId: function(url) {
+ if(!this.matchVimeoId.match(url)) {
+ return "";
+ }
+ return this.matchVimeoId.matched(1);
+ }
+ ,loadApi: function(callback) {
+ if(client_players_Vimeo.isApiLoaded) {
+ callback();
+ return;
+ }
+ client_players_Vimeo.apiCallbacks.push(callback);
+ if(client_players_Vimeo.isApiLoading) {
+ return;
+ }
+ client_players_Vimeo.isApiLoading = true;
+ client_JsApi.addScriptToHead("https://player.vimeo.com/api/player.js",function() {
+ client_players_Vimeo.isApiLoaded = true;
+ client_players_Vimeo.isApiLoading = false;
+ var _g = 0;
+ var _g1 = client_players_Vimeo.apiCallbacks;
+ while(_g < _g1.length) _g1[_g++]();
+ client_players_Vimeo.apiCallbacks = [];
+ });
+ }
+ ,getVideoData: function(data,callback) {
+ var _gthis = this;
+ var url = data.url;
+ if(!this.isSupportedLink(url)) {
+ callback({ duration : 0});
+ return;
+ }
+ var http = new haxe_http_HttpJs("https://vimeo.com/api/oembed.json?url=" + encodeURIComponent(url));
+ http.onData = function(text) {
+ try {
+ var json = JSON.parse(text);
+ var tmp = json.title;
+ var tmp1 = json.duration;
+ callback({ duration : tmp1 != null ? tmp1 : 0, title : tmp != null ? tmp : "Vimeo video", url : url});
+ } catch( _g ) {
+ _gthis.getRemoteDataFallback(url,callback);
+ }
+ };
+ http.onError = function(msg) {
+ _gthis.getRemoteDataFallback(url,callback);
+ };
+ http.request();
+ }
+ ,getRemoteDataFallback: function(url,callback) {
+ var _gthis = this;
+ if(!client_players_Vimeo.isApiLoaded) {
+ this.loadApi(function() {
+ _gthis.getRemoteDataFallback(url,callback);
+ });
+ return;
+ }
+ var tempVideo = window.document.createElement("div");
+ tempVideo.className = "temp-videoplayer";
+ tempVideo.style.display = "none";
+ this.playerEl.appendChild(tempVideo);
+ var tempPlayer = null;
+ tempPlayer = new window.Vimeo.Player(tempVideo, { url : url});
+ tempPlayer.on("loaded",function() {
+ return tempPlayer.getDuration().then(function(dur) {
+ try {
+ tempPlayer.destroy();
+ } catch( _g ) {
+ }
+ if(_gthis.playerEl.contains(tempVideo)) {
+ _gthis.playerEl.removeChild(tempVideo);
+ }
+ callback({ title : "Vimeo video", duration : dur, url : url});
+ });
+ });
+ tempPlayer.on("error",function(err) {
+ try {
+ tempPlayer.destroy();
+ } catch( _g ) {
+ }
+ if(_gthis.playerEl.contains(tempVideo)) {
+ _gthis.playerEl.removeChild(tempVideo);
+ }
+ callback({ duration : 0});
+ });
+ }
+ ,loadVideo: function(item) {
+ var _gthis = this;
+ if(!client_players_Vimeo.isApiLoaded) {
+ this.loadApi(function() {
+ _gthis.loadVideo(item);
+ });
+ return;
+ }
+ this.removeVideo();
+ this.video = window.document.createElement("div");
+ this.video.id = "videoplayer";
+ this.playerEl.appendChild(this.video);
+ this.vimeoPlayer = new window.Vimeo.Player(this.video, { url : item.url, autoplay : true, playsinline : true, responsive : true});
+ this.vimeoPlayer.on("loaded",function() {
+ if(!_gthis.main.isAutoplayAllowed()) {
+ _gthis.vimeoPlayer.setVolume(0);
+ }
+ _gthis.isLoaded = true;
+ if(_gthis.main.lastState.paused) {
+ _gthis.vimeoPlayer.pause();
+ }
+ _gthis.player.onCanBePlayed();
+ });
+ this.vimeoPlayer.on("play",function() {
+ _gthis.isPausedState = false;
+ if(!_gthis.isLoaded) {
+ _gthis.isLoaded = true;
+ _gthis.player.onCanBePlayed();
+ }
+ _gthis.player.onPlay();
+ });
+ this.vimeoPlayer.on("pause",function() {
+ _gthis.isPausedState = true;
+ if(!_gthis.isLoaded) {
+ _gthis.isLoaded = true;
+ _gthis.player.onCanBePlayed();
+ }
+ _gthis.player.onPause();
+ });
+ this.vimeoPlayer.on("timeupdate",function(data) {
+ var sec = data.seconds;
+ _gthis.currentTime = sec;
+ var diff = Math.abs(_gthis.prevTime - sec);
+ _gthis.prevTime = sec;
+ if(diff > 1) {
+ _gthis.player.onSetTime();
+ }
+ });
+ this.vimeoPlayer.on("ratechange",function(data) {
+ _gthis.playbackRate = data.playbackRate;
+ _gthis.player.onRateChange();
+ });
+ this.vimeoPlayer.on("volumechange",function(data) {
+ return _gthis.volume = data.volume;
+ });
+ this.vimeoPlayer.on("error",function(data) {
+ haxe_Log.trace("Vimeo error: " + data,{ fileName : "src/client/players/Vimeo.hx", lineNumber : 234, className : "client.players.Vimeo", methodName : "loadVideo"});
+ });
+ }
+ ,removeVideo: function() {
+ if(this.video == null) {
+ return;
+ }
+ this.isLoaded = false;
+ this.isPausedState = true;
+ if(this.vimeoPlayer != null) {
+ try {
+ this.vimeoPlayer.destroy();
+ } catch( _g ) {
+ haxe_Log.trace(haxe_Exception.caught(_g),{ fileName : "src/client/players/Vimeo.hx", lineNumber : 246, className : "client.players.Vimeo", methodName : "removeVideo"});
+ }
+ this.vimeoPlayer = null;
+ }
+ if(this.playerEl.contains(this.video)) {
+ this.playerEl.removeChild(this.video);
+ }
+ this.video = null;
+ }
+ ,isVideoLoaded: function() {
+ return this.isLoaded;
+ }
+ ,play: function() {
+ if(this.vimeoPlayer != null) {
+ this.vimeoPlayer.play();
+ }
+ }
+ ,pause: function() {
+ if(this.vimeoPlayer != null) {
+ this.vimeoPlayer.pause();
+ }
+ }
+ ,isPaused: function() {
+ return this.isPausedState;
+ }
+ ,getTime: function() {
+ return this.currentTime;
+ }
+ ,setTime: function(time) {
+ this.currentTime = time;
+ if(this.vimeoPlayer != null) {
+ this.vimeoPlayer.setCurrentTime(time);
+ }
+ }
+ ,getPlaybackRate: function() {
+ return this.playbackRate;
+ }
+ ,setPlaybackRate: function(rate) {
+ this.playbackRate = rate;
+ if(this.vimeoPlayer != null) {
+ this.vimeoPlayer.setPlaybackRate(rate);
+ }
+ }
+ ,getVolume: function() {
+ return this.volume;
+ }
+ ,setVolume: function(vol) {
+ this.volume = vol;
+ if(this.vimeoPlayer != null) {
+ this.vimeoPlayer.setVolume(vol);
+ }
+ }
+ ,unmute: function() {
+ if(this.vimeoPlayer == null) {
+ return;
+ }
+ this.vimeoPlayer.setMuted(false);
+ this.vimeoPlayer.setVolume(1);
+ }
+};
var client_players_Vk = function(main,player) {
this.matchIds = new EReg("video(-?[0-9]+)_([0-9]+)","g");
this.matchVk = new EReg("(vk.com/video|vkvideo)","g");
@@ -6025,18 +6919,6 @@ js_youtube_Youtube.init = function(onAPIReady) {
}
};
};
-var tools_MathTools = function() { };
-tools_MathTools.__name__ = true;
-tools_MathTools.toFixed = function(v,digits) {
- if(digits == null) {
- digits = 2;
- }
- if(digits > 8) {
- throw haxe_Exception.thrown("digits is " + digits + ", but cannot be bigger than 8 (for value " + v + ")");
- }
- var ratio = Math.pow(10,digits);
- return (v * ratio | 0) / ratio;
-};
var utils_YoutubeUtils = function() { };
utils_YoutubeUtils.__name__ = true;
utils_YoutubeUtils.extractVideoId = function(url) {
@@ -6074,6 +6956,8 @@ js_Boot.__toStr = ({ }).toString;
Lang.langs = new haxe_ds_StringMap();
Lang.ids = ["en","ru"];
Lang.lang = HxOverrides.substr($global.navigator.language,0,2).toLowerCase();
+client_Buttons.hasUnreadChatMessages = false;
+client_Commands.list = [new client_CommandInfo("/help",0,null),new client_CommandInfo("/clear",0,null),new client_CommandInfo("/ban",2,null),new client_CommandInfo("/unban",1,null),new client_CommandInfo("/kick",1,null),new client_CommandInfo("/ad",0,null),new client_CommandInfo("/volume",1,null),new client_CommandInfo("/dump",0,null),new client_CommandInfo("/crash",0,null),new client_CommandInfo("/giveup",1,null),new client_CommandInfo("/fb",0,["/flashback"])];
client_JsApi.subtitleFormats = [];
client_JsApi.videoChange = [];
client_JsApi.videoRemove = [];
@@ -6081,7 +6965,11 @@ client_JsApi.onListeners = [];
client_JsApi.onceListeners = [];
client_Settings.isSupported = false;
client_Utils.isMacSafari = client_Utils._isMacSafari();
+client_players_Iframe.matchTwitchChannel = new EReg("^(?:https?://)?(?:www\\.|m\\.)?twitch\\.tv/([A-Za-z0-9_]+)/?$","i");
client_players_RawSubs.assTimeStamp = new EReg("([0-9]+):([0-9][0-9]):([0-9][0-9]).([0-9][0-9])","");
+client_players_Vimeo.isApiLoaded = false;
+client_players_Vimeo.isApiLoading = false;
+client_players_Vimeo.apiCallbacks = [];
haxe_crypto_Base64.CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
haxe_crypto_Base64.BYTES = haxe_io_Bytes.ofString(haxe_crypto_Base64.CHARS);
js_youtube_Youtube.isLoadedAPI = false;
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage