aboutsummaryrefslogtreecommitdiffstats
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/Buttons.hx180
-rw-r--r--src/client/Main.hx136
-rw-r--r--src/client/Player.hx30
-rw-r--r--src/client/Split.hx44
-rw-r--r--src/client/players/Iframe.hx4
-rw-r--r--src/client/players/Raw.hx8
-rw-r--r--src/client/players/Vk.hx4
-rw-r--r--src/client/players/Youtube.hx4
8 files changed, 215 insertions, 195 deletions
diff --git a/src/client/Buttons.hx b/src/client/Buttons.hx
index 334debc..99e12cb 100644
--- a/src/client/Buttons.hx
+++ b/src/client/Buttons.hx
@@ -2,7 +2,7 @@ package client;
import Types.UploadResponse;
import Types.WsEvent;
-import client.Main.ge;
+import client.Main.getEl;
import haxe.Timer;
import haxe.io.Path;
import js.Browser.document;
@@ -15,28 +15,30 @@ import js.html.TransitionEvent;
import js.html.VisualViewport;
class Buttons {
- static inline var CHAT_MIN_SIZE = 200;
static var split:Split;
static var settings:ClientSettings;
public static function init(main:Main):Void {
settings = main.settings;
if (settings.isSwapped) swapPlayerAndChat();
- initSplit();
- setSplitSize(settings.chatSize);
+
+ split?.destroy();
+ split = new Split(settings);
+ split.setSize(settings.chatSize);
+
initChatInputs(main);
for (item in settings.checkboxes) {
if (item.checked == null) continue;
- final checkbox:InputElement = ge('#${item.id}') ?? continue;
+ final checkbox:InputElement = getEl('#${item.id}') ?? continue;
checkbox.checked = item.checked;
}
- final passIcon = ge("#guestpass_icon");
+ final passIcon = getEl("#guestpass_icon");
passIcon.onclick = e -> {
final icon = passIcon.firstElementChild;
final isOpen = icon.getAttribute("name") == "eye-off";
- final pass:InputElement = cast ge("#guestpass");
+ final pass:InputElement = getEl("#guestpass");
if (isOpen) {
pass.type = "password";
icon.setAttribute("name", "eye");
@@ -46,10 +48,10 @@ class Buttons {
}
}
- final smilesBtn = ge("#smilesbtn");
+ final smilesBtn = getEl("#smilesbtn");
smilesBtn.onclick = e -> {
- final wrap = ge("#smiles-wrap");
- final list = ge("#smiles-list");
+ final wrap = getEl("#smiles-wrap");
+ final list = getEl("#smiles-list");
if (list.children.length == 0) return;
final isActive = smilesBtn.classList.toggle("active");
if (isActive) {
@@ -70,22 +72,22 @@ class Buttons {
}
}
- final scrollToChatEndBtn = ge("#scroll-to-chat-end");
+ final scrollToChatEndBtn = getEl("#scroll-to-chat-end");
scrollToChatEndBtn.onclick = e -> {
main.scrollChatToEnd();
main.hideScrollToChatEndBtn();
}
// hide scroll button when chat is scrolled to the end
- final msgBuf = ge("#messagebuffer");
+ final msgBuf = getEl("#messagebuffer");
msgBuf.onscroll = e -> {
if (!main.isInChatEnd(1)) return;
main.hideScrollToChatEndBtn();
}
- ge("#clearchatbtn").onclick = e -> {
+ getEl("#clearchatbtn").onclick = e -> {
if (main.isAdmin()) main.send({type: ClearChat});
}
- final userList = ge("#userlist");
+ final userList = getEl("#userlist");
userList.onclick = e -> {
if (!main.isAdmin()) return;
var el:Element = cast e.target;
@@ -105,12 +107,12 @@ class Buttons {
});
}
- final userlistToggle = ge("#userlisttoggle");
+ final userlistToggle = getEl("#userlisttoggle");
userlistToggle.onclick = e -> {
final icon = userlistToggle.firstElementChild;
final isHidden = icon.getAttribute("name") == "chevron-forward";
- final wrap = ge("#userlist-wrap");
- final style = ge("#userlist").style;
+ final wrap = getEl("#userlist-wrap");
+ final style = getEl("#userlist").style;
if (isHidden) {
icon.setAttribute("name", "chevron-down");
style.display = "";
@@ -126,19 +128,19 @@ class Buttons {
settings.isUserListHidden = !isHidden;
Settings.write(settings);
}
- ge("#usercount").onclick = userlistToggle.onclick;
+ getEl("#usercount").onclick = userlistToggle.onclick;
if (settings.isUserListHidden) userlistToggle.onclick();
else {
- final wrap = ge("#userlist-wrap");
+ final wrap = getEl("#userlist-wrap");
final list = wrap.firstElementChild;
wrap.style.height = "15vh";
}
// enable animation after page loads
Timer.delay(() -> {
- ge("#userlist-wrap").style.transition = "200ms";
+ getEl("#userlist-wrap").style.transition = "200ms";
}, 0);
- final toggleSynch = ge("#togglesynch");
+ final toggleSynch = getEl("#togglesynch");
toggleSynch.onclick = e -> {
final icon = toggleSynch.firstElementChild;
if (main.isSyncActive) {
@@ -153,21 +155,21 @@ class Buttons {
main.send({type: UpdatePlaylist});
}
}
- final mediaRefresh = ge("#mediarefresh");
+ final mediaRefresh = getEl("#mediarefresh");
mediaRefresh.onclick = e -> {
main.refreshPlayer();
}
- final fullscreenBtn = ge("#fullscreenbtn");
+ final fullscreenBtn = getEl("#fullscreenbtn");
fullscreenBtn.onclick = e -> {
if ((Utils.isTouch() || main.isVerbose()) && !Utils.hasFullscreen()) {
window.scrollTo(0, 0);
Utils.requestFullscreen(document.documentElement);
} else {
- Utils.requestFullscreen(ge("#ytapiplayer"));
+ Utils.requestFullscreen(getEl("#ytapiplayer"));
}
}
initPageFullscreen();
- final getPlaylist = ge("#getplaylist");
+ final getPlaylist = getEl("#getplaylist");
getPlaylist.onclick = e -> {
final text = main.getPlaylistLinks().join(",");
Utils.copyToClipboard(text);
@@ -177,18 +179,18 @@ class Buttons {
icon.setAttribute("name", "link");
}, 2000);
}
- final clearPlaylist = ge("#clearplaylist");
+ final clearPlaylist = getEl("#clearplaylist");
clearPlaylist.onclick = e -> {
if (!window.confirm(Lang.get("clearPlaylistConfirm"))) return;
main.send({type: ClearPlaylist});
}
- final shufflePlaylist = ge("#shuffleplaylist");
+ final shufflePlaylist = getEl("#shuffleplaylist");
shufflePlaylist.onclick = e -> {
if (!window.confirm(Lang.get("shufflePlaylistConfirm"))) return;
main.send({type: ShufflePlaylist});
}
- final lockPlaylist = ge("#lockplaylist");
+ final lockPlaylist = getEl("#lockplaylist");
lockPlaylist.onclick = e -> {
if (!main.hasPermission(LockPlaylistPerm)) return;
if (main.isPlaylistOpen) {
@@ -199,36 +201,36 @@ class Buttons {
});
}
- final showMediaUrl = ge("#showmediaurl");
+ final showMediaUrl = getEl("#showmediaurl");
showMediaUrl.onclick = e -> {
final isOpen = showPlayerGroup(showMediaUrl);
if (isOpen) Timer.delay(() -> {
- ge("#addfromurl").scrollIntoView();
- ge("#mediaurl").focus();
+ getEl("#addfromurl").scrollIntoView();
+ getEl("#mediaurl").focus();
}, 100);
}
- final showCustomEmbed = ge("#showcustomembed");
+ final showCustomEmbed = getEl("#showcustomembed");
showCustomEmbed.onclick = e -> {
final isOpen = showPlayerGroup(showCustomEmbed);
if (isOpen) Timer.delay(() -> {
- ge("#customembed").scrollIntoView();
- ge("#customembed-title").focus();
+ getEl("#customembed").scrollIntoView();
+ getEl("#customembed-title").focus();
}, 100);
}
- final mediaUrl:InputElement = cast ge("#mediaurl");
+ final mediaUrl:InputElement = getEl("#mediaurl");
mediaUrl.oninput = () -> {
final url = mediaUrl.value;
final playerType = main.getLinkPlayerType(url);
final isSingle = main.isSingleVideoUrl(url);
final isSingleRawVideo = url != "" && playerType == RawType && isSingle;
- ge("#mediatitleblock").style.display = isSingleRawVideo ? "" : "none";
- ge("#subsurlblock").style.display = isSingleRawVideo ? "" : "none";
- ge("#voiceoverblock").style.display = (url.length > 0 && isSingle) ? "" : "none";
+ getEl("#mediatitleblock").style.display = isSingleRawVideo ? "" : "none";
+ getEl("#subsurlblock").style.display = isSingleRawVideo ? "" : "none";
+ getEl("#voiceoverblock").style.display = (url.length > 0 && isSingle) ? "" : "none";
final showCache = isSingle && main.playersCacheSupport.contains(playerType);
- ge("#cache-on-server").parentElement.style.display = showCache ? "" : "none";
- final panel = ge("#addfromurl");
+ getEl("#cache-on-server").parentElement.style.display = showCache ? "" : "none";
+ final panel = getEl("#addfromurl");
final oldH = panel.style.height; // save for animation
panel.style.height = ""; // to calculate height from content
final newH = Utils.outerHeight(panel) + "px";
@@ -237,12 +239,12 @@ class Buttons {
}
mediaUrl.onfocus = mediaUrl.oninput;
- ge("#insert_template").onclick = e -> {
+ getEl("#insert_template").onclick = e -> {
mediaUrl.value = main.getTemplateUrl();
mediaUrl.focus();
}
- ge("#mediaurl-upload").onclick = e -> {
+ getEl("#mediaurl-upload").onclick = e -> {
Utils.browseFile((buffer, name) -> {
if (name == null || name.length == 0) name = "video";
@@ -288,7 +290,7 @@ class Buttons {
final data = event.progress;
if (data.type != Uploading) return;
if (data.data == null) return;
- final input:InputElement = ge("#mediaurl");
+ final input:InputElement = getEl("#mediaurl");
input.value = data.data;
JsApi.off(Progress, onStartUpload);
}
@@ -296,24 +298,24 @@ class Buttons {
});
}
- final showOptions = ge("#showoptions");
+ final showOptions = getEl("#showoptions");
showOptions.onclick = e -> {
final isActive = toggleGroup(showOptions);
- ge("#optionsPanel").style.opacity = isActive ? "1" : "0";
+ getEl("#optionsPanel").style.opacity = isActive ? "1" : "0";
Timer.delay(() -> {
if (showOptions.classList.contains("active") != isActive) return;
- ge("#optionsPanel").classList.toggle("collapse", !isActive);
+ getEl("#optionsPanel").classList.toggle("collapse", !isActive);
}, isActive ? 0 : 200);
}
- final exitBtn = ge("#exitBtn");
+ final exitBtn = getEl("#exitBtn");
exitBtn.onclick = e -> {
showOptions.onclick();
if (main.isUser()) main.send({type: Logout});
- else ge("#guestname").focus();
+ else getEl("#guestname").focus();
}
- final swapLayoutBtn = ge("#swapLayoutBtn");
+ final swapLayoutBtn = getEl("#swapLayoutBtn");
swapLayoutBtn.onclick = e -> {
swapPlayerAndChat();
Settings.write(settings);
@@ -332,7 +334,7 @@ class Buttons {
static function toggleGroup(el:Element):Bool {
el.classList.toggle("collapsed");
- final target = ge(el.dataset.target);
+ final target = getEl(el.dataset.target);
final isClosed = target.classList.toggle("collapse");
if (isClosed) {
target.style.height = "0";
@@ -347,42 +349,14 @@ class Buttons {
}
static function swapPlayerAndChat():Void {
- settings.isSwapped = ge("body").classList.toggle("swap");
+ settings.isSwapped = getEl("body").classList.toggle("swap");
final sizes = document.body.style.gridTemplateColumns.split(" ");
sizes.reverse();
document.body.style.gridTemplateColumns = sizes.join(" ");
}
- static function initSplit():Void {
- if (split != null) split.destroy();
- split = new Split({
- columnGutters: [{
- element: ge(".gutter"),
- track: 1,
- }],
- minSize: 200,
- snapOffset: 0,
- onDragEnd: saveSplitSize
- });
- }
-
- static function setSplitSize(chatSize:Float):Void {
- if (chatSize < CHAT_MIN_SIZE) return;
- final sizes = document.body.style.gridTemplateColumns.split(" ");
- final chatId = settings.isSwapped ? 0 : sizes.length - 1;
- sizes[chatId] = '${chatSize}px';
- document.body.style.gridTemplateColumns = sizes.join(" ");
- }
-
- static function saveSplitSize():Void {
- final sizes = document.body.style.gridTemplateColumns.split(" ");
- if (settings.isSwapped) sizes.reverse();
- settings.chatSize = Std.parseFloat(sizes[sizes.length - 1]);
- Settings.write(settings);
- }
-
public static function initTextButtons(main:Main):Void {
- final synchThresholdBtn = ge("#synchThresholdBtn");
+ final synchThresholdBtn = getEl("#synchThresholdBtn");
synchThresholdBtn.onclick = e -> {
var secs = settings.synchThreshold + 1;
if (secs > 5) secs = 1;
@@ -391,7 +365,7 @@ class Buttons {
}
updateSynchThresholdBtn();
- final hotkeysBtn = ge("#hotkeysBtn");
+ final hotkeysBtn = getEl("#hotkeysBtn");
hotkeysBtn.onclick = e -> {
settings.hotkeysEnabled = !settings.hotkeysEnabled;
Settings.write(settings);
@@ -399,7 +373,7 @@ class Buttons {
}
updateHotkeysBtn();
- final removeBtn = ge("#removePlayerBtn");
+ final removeBtn = getEl("#removePlayerBtn");
removeBtn.onclick = e -> {
final isActive = main.toggleVideoElement();
if (isActive) {
@@ -408,7 +382,7 @@ class Buttons {
removeBtn.innerText = Lang.get("restorePlayer");
}
}
- final setVideoUrlBtn = ge("#setVideoUrlBtn");
+ final setVideoUrlBtn = getEl("#setVideoUrlBtn");
setVideoUrlBtn.onclick = e -> {
final src = window.prompt(Lang.get("setVideoUrlPrompt"));
if (src.trim() == "") { // reset to default url
@@ -417,7 +391,7 @@ class Buttons {
}
JsApi.setVideoSrc(src);
}
- final selectLocalVideoBtn = ge("#selectLocalVideoBtn");
+ final selectLocalVideoBtn = getEl("#selectLocalVideoBtn");
selectLocalVideoBtn.onclick = e -> {
Utils.browseFileUrl((url, name) -> {
JsApi.setVideoSrc(url);
@@ -426,11 +400,11 @@ class Buttons {
}
public static function initHotkeys(main:Main, player:Player):Void {
- ge("#mediarefresh").title += " (Alt-R)";
- ge("#voteskip").title += " (Alt-S)";
- ge("#getplaylist").title += " (Alt-C)";
- ge("#fullscreenbtn").title += " (Alt-F)";
- ge("#leader_btn").title += " (Alt-L)";
+ getEl("#mediarefresh").title += " (Alt-R)";
+ getEl("#voteskip").title += " (Alt-S)";
+ getEl("#getplaylist").title += " (Alt-C)";
+ getEl("#fullscreenbtn").title += " (Alt-F)";
+ getEl("#leader_btn").title += " (Alt-L)";
window.onkeydown = (e:KeyboardEvent) -> {
if (!settings.hotkeysEnabled) return;
final target:Element = cast e.target;
@@ -440,13 +414,13 @@ class Buttons {
if (!e.altKey) return;
switch (key) {
case R:
- ge("#mediarefresh").onclick();
+ getEl("#mediarefresh").onclick();
case S:
- ge("#voteskip").onclick();
+ getEl("#voteskip").onclick();
case C:
- ge("#getplaylist").onclick();
+ getEl("#getplaylist").onclick();
case F:
- ge("#fullscreenbtn").onclick();
+ getEl("#fullscreenbtn").onclick();
case L:
main.toggleLeader();
case P:
@@ -469,17 +443,17 @@ class Buttons {
static function updateSynchThresholdBtn():Void {
final text = Lang.get("synchThreshold");
final secs = settings.synchThreshold;
- ge("#synchThresholdBtn").innerText = '$text: ${secs}s';
+ getEl("#synchThresholdBtn").innerText = '$text: ${secs}s';
}
static function updateHotkeysBtn():Void {
final text = Lang.get("hotkeys");
final state = settings.hotkeysEnabled ? Lang.get("on") : Lang.get("off");
- ge("#hotkeysBtn").innerText = '$text: $state';
+ getEl("#hotkeysBtn").innerText = '$text: $state';
}
static function initChatInputs(main:Main):Void {
- final guestName:InputElement = cast ge("#guestname");
+ final guestName:InputElement = getEl("#guestname");
guestName.onkeydown = e -> {
if (e.keyCode == KeyCode.Return) {
main.guestLogin(guestName.value);
@@ -487,7 +461,7 @@ class Buttons {
}
}
- final guestPass:InputElement = cast ge("#guestpass");
+ final guestPass:InputElement = getEl("#guestpass");
guestPass.onkeydown = e -> {
if (e.keyCode == KeyCode.Return) {
main.userLogin(guestName.value, guestPass.value);
@@ -496,14 +470,14 @@ class Buttons {
}
}
- final chatline:InputElement = cast ge("#chatline");
+ final chatline:InputElement = getEl("#chatline");
chatline.onfocus = e -> {
if (Utils.isIOS()) {
// final startY = window.scrollY;
final startY = 0;
Timer.delay(() -> {
window.scrollBy(0, -(window.scrollY - startY));
- ge("#video").scrollTop = 0;
+ getEl("#video").scrollTop = 0;
main.scrollChatToEnd();
}, 100);
} else if (Utils.isTouch()) {
@@ -528,8 +502,8 @@ class Buttons {
return true;
});
final checkboxes:Array<InputElement> = [
- ge("#add-temp"),
- ge("#cache-on-server"),
+ getEl("#add-temp"),
+ getEl("#cache-on-server"),
];
for (checkbox in checkboxes) {
checkbox.addEventListener("change", () -> {
@@ -545,10 +519,10 @@ class Buttons {
public static function onViewportResize():Void {
final viewport = getVisualViewport() ?? return;
final isPortrait = window.innerHeight > window.innerWidth;
- final playerH = ge("#ytapiplayer").offsetHeight;
+ final playerH = getEl("#ytapiplayer").offsetHeight;
var h = viewport.height - playerH;
if (!isPortrait) h = viewport.height;
- ge("#chat").style.height = '${h}px';
+ getEl("#chat").style.height = '${h}px';
}
static inline function getVisualViewport():Null<VisualViewport> {
diff --git a/src/client/Main.hx b/src/client/Main.hx
index 61b3c3a..84f6838 100644
--- a/src/client/Main.hx
+++ b/src/client/Main.hx
@@ -38,7 +38,7 @@ class Main {
public var isPlaylistOpen(default, null) = true;
public var playersCacheSupport(default, null):Array<PlayerType> = [];
public var showingServerPause(default, null) = false;
- /** How much time passed from last GetTime **/
+ /** How much time passed since lastState.time update **/
public var timeFromLastState(default, null) = 0.0;
public final lastState:GetTimeEvent = {
time: 0,
@@ -63,7 +63,7 @@ class Main {
var onTimeGet:Timer;
var onBlinkTab:Null<Timer>;
var gotFirstPageInteraction = false;
- var msgBuf = ge("#messagebuffer");
+ var msgBuf = getEl("#messagebuffer");
static function main():Void {
instance = new Main();
@@ -189,14 +189,14 @@ class Main {
function initListeners():Void {
Buttons.init(this);
- final leaderBtn = ge("#leader_btn");
+ final leaderBtn = getEl("#leader_btn");
leaderBtn.onclick = toggleLeader;
leaderBtn.oncontextmenu = (e:MouseEvent) -> {
toggleLeaderAndPause();
e.preventDefault();
}
- final voteSkip = ge("#voteskip");
+ final voteSkip = getEl("#voteskip");
voteSkip.onclick = e -> {
if (Utils.isTouch() && !window.confirm(Lang.get("skipItemConfirm"))) return;
if (player.isListEmpty()) return;
@@ -210,29 +210,29 @@ class Main {
});
}
- ge("#queue_next").onclick = e -> addVideoUrl(false);
- ge("#queue_end").onclick = e -> addVideoUrl(true);
- new InputWithHistory(cast ge("#mediaurl"), settings.latestLinks, 10, value -> {
+ getEl("#queue_next").onclick = e -> addVideoUrl(false);
+ getEl("#queue_end").onclick = e -> addVideoUrl(true);
+ new InputWithHistory(getEl("#mediaurl"), settings.latestLinks, 10, value -> {
addVideoUrl(true);
return false;
});
- ge("#mediatitle").onkeydown = (e:KeyboardEvent) -> {
+ getEl("#mediatitle").onkeydown = (e:KeyboardEvent) -> {
if (e.keyCode == KeyCode.Return) addVideoUrl(true);
}
- new InputWithHistory(cast ge("#subsurl"), settings.latestSubs, 10, value -> {
+ new InputWithHistory(getEl("#subsurl"), settings.latestSubs, 10, value -> {
addVideoUrl(true);
return false;
});
- ge("#ce_queue_next").onclick = e -> addIframe(false);
- ge("#ce_queue_end").onclick = e -> addIframe(true);
- ge("#customembed-title").onkeydown = (e:KeyboardEvent) -> {
+ getEl("#ce_queue_next").onclick = e -> addIframe(false);
+ getEl("#ce_queue_end").onclick = e -> addIframe(true);
+ getEl("#customembed-title").onkeydown = (e:KeyboardEvent) -> {
if (e.keyCode == KeyCode.Return) {
addIframe(true);
e.preventDefault();
}
}
- ge("#customembed-content").onkeydown = ge("#customembed-title").onkeydown;
+ getEl("#customembed-content").onkeydown = getEl("#customembed-title").onkeydown;
}
public inline function isUser():Bool {
@@ -274,11 +274,11 @@ class Main {
}
function addVideoUrl(atEnd:Bool):Void {
- final mediaUrl:InputElement = cast ge("#mediaurl");
- final subsUrl:InputElement = cast ge("#subsurl");
- final checkboxTemp:InputElement = cast ge("#addfromurl .add-temp");
+ final mediaUrl:InputElement = getEl("#mediaurl");
+ final subsUrl:InputElement = getEl("#subsurl");
+ final checkboxTemp:InputElement = getEl("#addfromurl .add-temp");
final isTemp = checkboxTemp.checked;
- final checkboxCache:InputElement = cast ge("#cache-on-server");
+ final checkboxCache:InputElement = getEl("#cache-on-server");
final doCache = checkboxCache.checked
&& checkboxCache.parentElement.style.display != "none";
final url = mediaUrl.value;
@@ -364,14 +364,14 @@ class Main {
}
function addIframe(atEnd:Bool):Void {
- final iframeCode:InputElement = cast ge("#customembed-content");
+ final iframeCode:InputElement = getEl("#customembed-content");
final iframe = iframeCode.value;
if (iframe.length == 0) return;
iframeCode.value = "";
- final mediaTitle:InputElement = cast ge("#customembed-title");
+ final mediaTitle:InputElement = getEl("#customembed-title");
final title = mediaTitle.value;
mediaTitle.value = "";
- final checkbox:InputElement = cast ge("#customembed .add-temp");
+ final checkbox:InputElement = getEl("#customembed .add-temp");
final isTemp = checkbox.checked;
final obj:VideoDataRequest = {
url: iframe,
@@ -699,7 +699,7 @@ class Main {
} else {
onLogin(connected.clients, connected.clientName);
}
- final guestName:InputElement = cast ge("#guestname");
+ final guestName:InputElement = getEl("#guestname");
var name = settings.name;
if (name.length == 0) name = guestName.value;
final hash = settings.hash;
@@ -743,30 +743,30 @@ class Main {
serverMessage(text, false, false);
- ge("#addVideosHintButton").onclick = e -> {
- final addBtn = ge("#showmediaurl");
+ getEl("#addVideosHintButton").onclick = e -> {
+ final addBtn = getEl("#showmediaurl");
addBtn.scrollIntoView();
Timer.delay(() -> {
- if (!ge("#addfromurl").classList.contains("collapse")) {
- ge("#mediaurl").focus();
+ if (!getEl("#addfromurl").classList.contains("collapse")) {
+ getEl("#mediaurl").focus();
return;
}
addBtn.onclick();
}, 300);
}
- ge("#requestLeaderHintButton").onclick = (e:MouseEvent) -> {
+ getEl("#requestLeaderHintButton").onclick = (e:MouseEvent) -> {
window.scrollTo(0, 0);
if (Utils.isTouch()) blinkLeaderButton();
}
- ge("#requestLeaderHintButton").onpointerenter = e -> {
+ getEl("#requestLeaderHintButton").onpointerenter = e -> {
if (Utils.isTouch()) return;
- ge("#leader_btn").classList.add("hint");
+ getEl("#leader_btn").classList.add("hint");
}
- ge("#requestLeaderHintButton").onpointerleave = e -> {
- ge("#leader_btn").classList.remove("hint");
+ getEl("#requestLeaderHintButton").onpointerleave = e -> {
+ getEl("#leader_btn").classList.remove("hint");
}
if (Utils.isAndroid()) {
- ge("#openInApp").onclick = e -> {
+ getEl("#openInApp").onclick = e -> {
var isRedirected = false;
window.addEventListener("blur", e -> isRedirected = true, {once: true});
window.setTimeout(function() {
@@ -777,26 +777,26 @@ class Main {
return false;
}
}
- ge("#hideHintList").onclick = e -> {
- ge("#hideHintList").parentElement.remove();
+ getEl("#hideHintList").onclick = e -> {
+ getEl("#hideHintList").parentElement.remove();
settings.showHintList = false;
Settings.write(settings);
}
}
public function blinkLeaderButton():Void {
- ge("#leader_btn").classList.add("hint");
- Timer.delay(() -> ge("#leader_btn").classList.remove("hint"), 500);
+ getEl("#leader_btn").classList.add("hint");
+ Timer.delay(() -> getEl("#leader_btn").classList.remove("hint"), 500);
}
function onUserGroupChanged():Void {
- final button:ButtonElement = cast ge("#queue_next");
+ final button:ButtonElement = getEl("#queue_next");
if (personal.hasPermission(ChangeOrderPerm, config.permissions)) {
button.disabled = false;
} else {
button.disabled = true;
}
- final adminMenu = ge("#adminMenu");
+ final adminMenu = getEl("#adminMenu");
if (isAdmin()) adminMenu.style.display = "";
else adminMenu.style.display = "none";
}
@@ -840,9 +840,9 @@ class Main {
config.unpauseWithoutLeader = false;
}
pageTitle = config.channelName;
- final login:InputElement = cast ge("#guestname");
+ final login:InputElement = getEl("#guestname");
login.maxLength = config.maxLoginLength;
- final form:InputElement = cast ge("#chatline");
+ final form:InputElement = getEl("#chatline");
form.maxLength = config.maxMessageLength;
filters.resize(0);
@@ -860,14 +860,14 @@ class Main {
replace: '$1<$tag class="channel-emote" src="${emote.image}" title="${emote.name}"/>'
});
}
- ge("#smilesbtn").classList.remove("active");
- final smilesWrap = ge("#smiles-wrap");
+ getEl("#smilesbtn").classList.remove("active");
+ final smilesWrap = getEl("#smiles-wrap");
smilesWrap.style.display = "none";
- final smilesList = ge("#smiles-list");
+ final smilesList = getEl("#smiles-list");
smilesList.onclick = (e:MouseEvent) -> {
final el:Element = cast e.target;
if (el == smilesList) return;
- final form:InputElement = cast ge("#chatline");
+ final form:InputElement = getEl("#chatline");
form.value += ' ${el.title}';
form.focus();
}
@@ -892,25 +892,25 @@ class Main {
}
function showGuestLoginPanel():Void {
- ge("#guestlogin").style.display = "";
- ge("#guestpassword").style.display = "none";
- ge("#chatbox").style.display = "none";
- ge("#exitBtn").textContent = Lang.get("login");
+ getEl("#guestlogin").style.display = "";
+ getEl("#guestpassword").style.display = "none";
+ getEl("#chatbox").style.display = "none";
+ getEl("#exitBtn").textContent = Lang.get("login");
}
function hideGuestLoginPanel():Void {
- ge("#guestlogin").style.display = "none";
- ge("#guestpassword").style.display = "none";
- ge("#chatbox").style.display = "";
- ge("#exitBtn").textContent = Lang.get("exit");
+ getEl("#guestlogin").style.display = "none";
+ getEl("#guestpassword").style.display = "none";
+ getEl("#chatbox").style.display = "";
+ getEl("#exitBtn").textContent = Lang.get("exit");
}
function showGuestPasswordPanel():Void {
- ge("#guestlogin").style.display = "none";
- ge("#chatbox").style.display = "none";
- ge("#guestpassword").style.display = "";
- (cast ge("#guestpass") : InputElement).type = "password";
- ge("#guestpass_icon").setAttribute("name", "eye");
+ getEl("#guestlogin").style.display = "none";
+ getEl("#chatbox").style.display = "none";
+ getEl("#guestpassword").style.display = "";
+ (getEl("#guestpass") : InputElement).type = "password";
+ getEl("#guestpass_icon").setAttribute("name", "eye");
}
function updateClients(newClients:Array<ClientData>):Void {
@@ -982,7 +982,7 @@ class Main {
}
function updateUserList():Void {
- final userCount = ge("#usercount");
+ final userCount = getEl("#usercount");
userCount.textContent = clients.length + " " + Lang.get("online");
document.title = getPageTitle();
@@ -995,7 +995,7 @@ class Main {
if (client.isAdmin) klass += " userlist_owner";
list.add('<span class="$klass">${client.name}</span></div>');
}
- final userlist = ge("#userlist");
+ final userlist = getEl("#userlist");
userlist.innerHTML = list.toString();
}
@@ -1076,13 +1076,13 @@ class Main {
}
public function showScrollToChatEndBtn():Void {
- final btn = ge("#scroll-to-chat-end");
+ final btn = getEl("#scroll-to-chat-end");
btn.style.display = "";
Timer.delay(() -> btn.style.opacity = "1", 0);
}
public function hideScrollToChatEndBtn():Void {
- final btn = ge("#scroll-to-chat-end");
+ final btn = getEl("#scroll-to-chat-end");
if (btn.style.opacity == "0") return;
btn.style.opacity = "0";
btn.addEventListener("transitionend", e -> {
@@ -1091,7 +1091,7 @@ class Main {
}
public function showProgressInfo(text:String):Void {
- final chin = ge("#dynamic-chin");
+ final chin = getEl("#dynamic-chin");
var div = chin.querySelector("#progress-info");
if (div == null) {
div = document.createDivElement();
@@ -1105,7 +1105,7 @@ class Main {
public function showServerUnpause():Void {
if (showingServerPause) return;
showingServerPause = true;
- final chin = ge("#dynamic-chin");
+ final chin = getEl("#dynamic-chin");
chin.innerHTML = "";
final div = document.createDivElement();
@@ -1131,7 +1131,7 @@ class Main {
}
function showDynamicChin():Void {
- final chin = ge("#dynamic-chin");
+ final chin = getEl("#dynamic-chin");
if (chin.style.display == "") return;
chin.style.display = "";
chin.style.transition = "none";
@@ -1153,7 +1153,7 @@ class Main {
public function hideDynamicChin():Void {
showingServerPause = false;
- final chin = ge("#dynamic-chin");
+ final chin = getEl("#dynamic-chin");
final h = chin.clientHeight;
chin.style.height = '${h}px';
Timer.delay(() -> {
@@ -1171,7 +1171,7 @@ class Main {
function onChatImageLoaded(e:Event):Void {
scrollChatToEnd();
(cast e.target : Element).onload = null;
- final btn = ge("#scroll-to-chat-end");
+ final btn = getEl("#scroll-to-chat-end");
btn.style.opacity = "0";
btn.style.display = "none";
}
@@ -1337,13 +1337,13 @@ class Main {
}
function setLeaderButton(flag:Bool):Void {
- final leaderBtn = ge("#leader_btn");
+ final leaderBtn = getEl("#leader_btn");
leaderBtn.classList.toggle("success-bg", flag);
}
function setPlaylistLock(isOpen:Bool):Void {
isPlaylistOpen = isOpen;
- final lockPlaylist = ge("#lockplaylist");
+ final lockPlaylist = getEl("#lockplaylist");
final icon = lockPlaylist.firstElementChild;
if (isOpen) {
lockPlaylist.title = Lang.get("playlistOpen");
@@ -1439,7 +1439,7 @@ class Main {
}
@:generic
- public static inline function ge<T:Element>(id:String):T {
+ public static inline function getEl<T:Element>(id:String):T {
return cast document.querySelector(id);
}
}
diff --git a/src/client/Player.hx b/src/client/Player.hx
index 92f34e9..e5ea87c 100644
--- a/src/client/Player.hx
+++ b/src/client/Player.hx
@@ -4,7 +4,7 @@ import Types.PlayerType;
import Types.VideoData;
import Types.VideoDataRequest;
import Types.VideoItem;
-import client.Main.ge;
+import client.Main.getEl;
import client.players.Iframe;
import client.players.Raw;
import client.players.Streamable;
@@ -24,15 +24,15 @@ class Player {
final iframePlayer:IPlayer;
final rawPlayer:IPlayer;
final videoList = new VideoList();
- final videoItemsEl = ge("#queue");
- final playerEl = ge("#ytapiplayer");
+ final videoItemsEl = getEl("#queue");
+ final playerEl = getEl("#ytapiplayer");
var player:Null<IPlayer>;
var isLoaded = false;
var skipSetTime = false;
var skipSetRate = false;
var streamable:Streamable;
- final voiceOverInput:InputElement = cast ge("#voiceoverurl");
+ final voiceOverInput:InputElement = getEl("#voiceoverurl");
var audioTrack:Null<Audio>;
var isAudioTrackLoaded = false;
var needsVolumeReset = false;
@@ -76,7 +76,7 @@ class Player {
}
function initItemButtons():Void {
- final queue = ge("#queue");
+ final queue = getEl("#queue");
queue.onclick = e -> {
final btn:Element = cast e.target;
final item = btn.parentElement.parentElement;
@@ -192,7 +192,7 @@ class Player {
onCanBePlayed();
}
JsApi.fireVideoChangeEvents(item);
- ge("#currenttitle").textContent = item.title;
+ getEl("#currenttitle").textContent = item.title;
}
function setExternalAudioTrack(item:VideoItem):Void {
@@ -248,17 +248,17 @@ class Player {
public function removeVideo():Void {
JsApi.fireVideoRemoveEvents(videoList.currentItem);
player.removeVideo();
- ge("#currenttitle").textContent = Lang.get("nothingPlaying");
+ getEl("#currenttitle").textContent = Lang.get("nothingPlaying");
setPauseIndicator(false);
}
public function setPauseIndicator(isPause:Bool):Void {
if (!main.isSyncActive) return;
final state = isPause ? "pause" : "play";
- final el = ge("#pause-indicator");
+ final el = getEl("#pause-indicator");
el.setAttribute("name", state);
- final el2 = ge("#pause-indicator-portrait");
+ final el2 = getEl("#pause-indicator-portrait");
el2.setAttribute("name", state);
var isVisible = isPause || main.hasLeader();
el2.style.display = isVisible ? "" : "none";
@@ -484,8 +484,8 @@ class Player {
}
function updateCounters():Void {
- ge("#plcount").textContent = '${videoList.length} ${Lang.get("videos")}';
- ge("#pllength").textContent = totalDuration();
+ getEl("#plcount").textContent = '${videoList.length} ${Lang.get("videos")}';
+ getEl("#pllength").textContent = totalDuration();
}
public function getItems():Array<VideoItem> {
@@ -625,8 +625,12 @@ class Player {
public function skipAd():Void {
final item = videoList.currentItem ?? return;
- if (!youtube.isSupportedLink(item.url)) return;
- final id = youtube.extractVideoId(item.url);
+ var itemUrl = item.url;
+ if (!youtube.isSupportedLink(itemUrl)) {
+ itemUrl = itemUrl.replace("/cache/", "youtu.be/");
+ if (!youtube.isSupportedLink(itemUrl)) return;
+ }
+ final id = youtube.extractVideoId(itemUrl);
final url = 'https://sponsor.ajay.app/api/skipSegments?videoID=$id';
final http = new Http(url);
http.onData = text -> {
diff --git a/src/client/Split.hx b/src/client/Split.hx
index 66055d0..102fbc6 100644
--- a/src/client/Split.hx
+++ b/src/client/Split.hx
@@ -1,7 +1,49 @@
package client;
+import client.Main.getEl;
+import js.Browser.document;
+
@:native("Split")
-extern class Split {
+private extern class JsSplit {
function new(options:Any):Void;
function destroy(?immediate:Bool = true):Void;
}
+
+class Split {
+ static inline var CHAT_MIN_SIZE = 200;
+
+ final settings:ClientSettings;
+ final split:JsSplit;
+
+ public function new(settings:ClientSettings) {
+ this.settings = settings;
+ split = new JsSplit({
+ columnGutters: [{
+ element: getEl(".gutter"),
+ track: 1,
+ }],
+ minSize: CHAT_MIN_SIZE,
+ snapOffset: 0,
+ onDragEnd: saveSize
+ });
+ }
+
+ public function setSize(chatSize:Float):Void {
+ if (chatSize < CHAT_MIN_SIZE) return;
+ final sizes = document.body.style.gridTemplateColumns.split(" ");
+ final chatId = settings.isSwapped ? 0 : sizes.length - 1;
+ sizes[chatId] = '${chatSize}px';
+ document.body.style.gridTemplateColumns = sizes.join(" ");
+ }
+
+ function saveSize():Void {
+ final sizes = document.body.style.gridTemplateColumns.split(" ");
+ if (settings.isSwapped) sizes.reverse();
+ settings.chatSize = Std.parseFloat(sizes[sizes.length - 1]);
+ Settings.write(settings);
+ }
+
+ public function destroy():Void {
+ split.destroy();
+ }
+}
diff --git a/src/client/players/Iframe.hx b/src/client/players/Iframe.hx
index 6614f9d..000bf8a 100644
--- a/src/client/players/Iframe.hx
+++ b/src/client/players/Iframe.hx
@@ -4,14 +4,14 @@ import Types.PlayerType;
import Types.VideoData;
import Types.VideoDataRequest;
import Types.VideoItem;
-import client.Main.ge;
+import client.Main.getEl;
import js.Browser.document;
import js.html.Element;
class Iframe implements IPlayer {
final main:Main;
final player:Player;
- final playerEl:Element = ge("#ytapiplayer");
+ final playerEl:Element = getEl("#ytapiplayer");
var video:Element;
public function new(main:Main, player:Player) {
diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx
index 10a54e8..e3337ae 100644
--- a/src/client/players/Raw.hx
+++ b/src/client/players/Raw.hx
@@ -4,7 +4,7 @@ import Types.PlayerType;
import Types.VideoData;
import Types.VideoDataRequest;
import Types.VideoItem;
-import client.Main.ge;
+import client.Main.getEl;
import haxe.Timer;
import js.Browser.document;
import js.Browser;
@@ -17,9 +17,9 @@ import js.html.VideoElement;
class Raw implements IPlayer {
final main:Main;
final player:Player;
- final playerEl:Element = ge("#ytapiplayer");
- final titleInput:InputElement = cast ge("#mediatitle");
- final subsInput:InputElement = cast ge("#subsurl");
+ final playerEl:Element = getEl("#ytapiplayer");
+ final titleInput:InputElement = getEl("#mediatitle");
+ final subsInput:InputElement = getEl("#subsurl");
final matchName = ~/^(.+)\.(.+)/;
var controlsHider:Timer;
var playAllowed = true;
diff --git a/src/client/players/Vk.hx b/src/client/players/Vk.hx
index 599b5eb..99643de 100644
--- a/src/client/players/Vk.hx
+++ b/src/client/players/Vk.hx
@@ -4,7 +4,7 @@ import Types.PlayerType;
import Types.VideoData;
import Types.VideoDataRequest;
import Types.VideoItem;
-import client.Main.ge;
+import client.Main.getEl;
import haxe.Constraints.Function;
import js.Browser.document;
import js.html.Element;
@@ -41,7 +41,7 @@ private extern class VkPlayer {
class Vk implements IPlayer {
final main:Main;
final player:Player;
- final playerEl:Element = ge("#ytapiplayer");
+ final playerEl:Element = getEl("#ytapiplayer");
var video:Element;
var vkPlayer:VkPlayer;
var isLoaded = false;
diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx
index f5fb88c..7c851fb 100644
--- a/src/client/players/Youtube.hx
+++ b/src/client/players/Youtube.hx
@@ -4,7 +4,7 @@ import Types.PlayerType;
import Types.VideoData;
import Types.VideoDataRequest;
import Types.VideoItem;
-import client.Main.ge;
+import client.Main.getEl;
import haxe.Http;
import haxe.Json;
import js.Browser.document;
@@ -20,7 +20,7 @@ class Youtube implements IPlayer {
final urlVideoId = "?part=snippet&fields=nextPageToken,items(snippet/resourceId/videoId)";
final main:Main;
final player:Player;
- final playerEl:Element = ge("#ytapiplayer");
+ final playerEl:Element = getEl("#ytapiplayer");
var apiKey:String;
var video:Element;
var youtube:YoutubePlayer;
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage