aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRblSb <msrblsb@gmail.com>2020-05-13 06:44:54 +0300
committerRblSb <msrblsb@gmail.com>2020-05-13 06:44:54 +0300
commit2d82ca5f1049fb332b521691c29b9d789d08f690 (patch)
tree829e2c8a22c00fd9bf3c222e8f8a1cfcef372432
parent28a1d1c271dd722dc36cebc5b61f87d80138dba3 (diff)
Add hotkeys
-rw-r--r--build/server.js4
-rw-r--r--res/client.js102
-rw-r--r--res/index.html1
-rw-r--r--res/langs/en.json1
-rw-r--r--res/langs/ru.json1
-rw-r--r--src/KeyCode.hx202
-rw-r--r--src/client/Buttons.hx57
-rw-r--r--src/client/ClientSettings.hx3
-rw-r--r--src/client/Main.hx18
9 files changed, 361 insertions, 28 deletions
diff --git a/build/server.js b/build/server.js
index 7e5c7f8..5d559b7 100644
--- a/build/server.js
+++ b/build/server.js
@@ -3285,7 +3285,9 @@ server_HttpServer.proxyUrl = function(req,res) {
if(url1.host == req.headers["host"]) {
return false;
}
- var proxy = (url1.protocol == "https:" ? js_node_Https.request : js_node_Http.request)({ host : url1.host, port : Std.parseInt(url1.port), path : url1.pathname + url1.search, method : req.method},function(proxyRes) {
+ var url2 = url1.host;
+ var options = Std.parseInt(url1.port);
+ var proxy = (url1.protocol == "https:" ? js_node_Https.request : js_node_Http.request)({ host : url2, port : options, path : url1.pathname + url1.search, method : req.method},function(proxyRes) {
res.writeHead(proxyRes.statusCode,proxyRes.headers);
return proxyRes.pipe(res,{ end : true});
});
diff --git a/res/client.js b/res/client.js
index cb8ea2a..d348a2d 100644
--- a/res/client.js
+++ b/res/client.js
@@ -764,26 +764,96 @@ client_Buttons.initNavBar = function(main) {
client_Buttons.initTextButtons = function(main) {
var synchThresholdBtn = window.document.querySelector("#synchThresholdBtn");
synchThresholdBtn.onclick = function(e) {
- var secs = main.settings.synchThreshold + 1;
+ var secs = client_Buttons.settings.synchThreshold + 1;
if(secs > 5) {
secs = 1;
}
main.setSynchThreshold(secs);
- client_Buttons.updateSynchThresholdBtn(main);
+ client_Buttons.updateSynchThresholdBtn();
synchThresholdBtn.blur();
return;
};
- client_Buttons.updateSynchThresholdBtn(main);
+ client_Buttons.updateSynchThresholdBtn();
+ var hotkeysBtn = window.document.querySelector("#hotkeysBtn");
+ hotkeysBtn.onclick = function(e1) {
+ client_Buttons.settings.hotkeysEnabled = !client_Buttons.settings.hotkeysEnabled;
+ client_Settings.write(client_Buttons.settings);
+ client_Buttons.updateHotkeysBtn();
+ hotkeysBtn.blur();
+ return;
+ };
+ client_Buttons.updateHotkeysBtn();
+};
+client_Buttons.initHotkeys = function(main,player) {
+ window.document.querySelector("#mediarefresh").title += " (Alt-R)";
+ window.document.querySelector("#voteskip").title += " (Alt-S)";
+ window.document.querySelector("#getplaylist").title += " (Alt-C)";
+ window.document.querySelector("#fullscreenbtn").title += " (Alt-F)";
+ window.document.querySelector("#leader_btn").title += " (Alt-L)";
+ window.onkeydown = function(e) {
+ if(!client_Buttons.settings.hotkeysEnabled) {
+ return;
+ }
+ var target = e.target;
+ if(target.isContentEditable) {
+ return;
+ }
+ var tagName = target.tagName;
+ if(tagName == "INPUT" || tagName == "TEXTAREA") {
+ return;
+ }
+ var key = e.keyCode;
+ if(key == 8) {
+ e.preventDefault();
+ }
+ if(!e.altKey) {
+ return;
+ }
+ switch(key) {
+ case 67:
+ window.document.querySelector("#getplaylist").onclick();
+ break;
+ case 70:
+ window.document.querySelector("#fullscreenbtn").onclick();
+ break;
+ case 76:
+ window.document.querySelector("#leader_btn").onclick();
+ break;
+ case 80:
+ if((main.personal.group & 2) == 0) {
+ haxe_Timer.delay(function() {
+ player.pause();
+ return;
+ },500);
+ }
+ window.document.querySelector("#leader_btn").onclick();
+ break;
+ case 82:
+ window.document.querySelector("#mediarefresh").onclick();
+ break;
+ case 83:
+ window.document.querySelector("#voteskip").onclick();
+ break;
+ default:
+ return;
+ }
+ e.preventDefault();
+ };
};
client_Buttons.hideMenus = function() {
var menus = window.document.querySelectorAll(".dropdown-menu");
var _g = 0;
while(_g < menus.length) menus[_g++].style.display = "";
};
-client_Buttons.updateSynchThresholdBtn = function(main) {
- var tmp = "" + Lang.get("synchThreshold") + ": " + main.settings.synchThreshold;
+client_Buttons.updateSynchThresholdBtn = function() {
+ var tmp = "" + Lang.get("synchThreshold") + ": " + client_Buttons.settings.synchThreshold;
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;
+};
client_Buttons.initChatInput = function(main) {
var guestName = window.document.querySelector("#guestname");
guestName.onkeydown = function(e) {
@@ -946,7 +1016,7 @@ var client_Main = function(host,port) {
if(port == "") {
port = "80";
}
- client_Settings.init({ version : 1, name : "", hash : "", isExtendedPlayer : false, chatSize : 40, playerSize : 60, synchThreshold : 2, isSwapped : false, isUserListHidden : false, latestLinks : []},$bind(this,this.settingsPatcher));
+ client_Settings.init({ version : 2, name : "", hash : "", isExtendedPlayer : false, chatSize : 40, playerSize : 60, synchThreshold : 2, isSwapped : false, isUserListHidden : false, latestLinks : [], hotkeysEnabled : true},$bind(this,this.settingsPatcher));
this.settings = client_Settings.read();
this.initListeners();
this.onTimeGet = new haxe_Timer(this.settings.synchThreshold * 1000);
@@ -961,6 +1031,7 @@ var client_Main = function(host,port) {
};
Lang.init("langs",function() {
client_Buttons.initTextButtons(_gthis);
+ client_Buttons.initHotkeys(_gthis,_gthis.player);
_gthis.openWebSocket(host,port);
return;
});
@@ -971,11 +1042,16 @@ client_Main.main = function() {
};
client_Main.prototype = {
settingsPatcher: function(data,version) {
- if(version == 1) {
+ switch(version) {
+ case 1:
+ data.hotkeysEnabled = true;
+ break;
+ case 2:
throw new js__$Boot_HaxeError("skipped version " + version);
- } else {
+ default:
throw new js__$Boot_HaxeError("skipped version " + version);
}
+ return data;
}
,requestTime: function() {
if(!this.isSyncActive) {
@@ -1204,7 +1280,7 @@ client_Main.prototype = {
var data = JSON.parse(e.data);
var t = data.type;
var t1 = t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null);
- haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 326, className : "client.Main", methodName : "onMessage", customParams : [data[t1]]});
+ haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 324, className : "client.Main", methodName : "onMessage", customParams : [data[t1]]});
switch(data.type) {
case "AddVideo":
this.player.addVideoItem(data.addVideo.item,data.addVideo.atEnd);
@@ -1235,10 +1311,11 @@ client_Main.prototype = {
if(this.player.getPlaybackRate() != data.getTime.rate) {
this.player.setPlaybackRate(data.getTime.rate);
}
+ var synchThreshold = this.settings.synchThreshold;
var newTime = data.getTime.time;
var time = this.player.getTime();
if((this.personal.group & 1 << ClientGroup.Leader._hx_index) != 0) {
- if(Math.abs(time - newTime) < this.settings.synchThreshold) {
+ if(Math.abs(time - newTime) < synchThreshold) {
return;
}
this.player.setTime(time,false);
@@ -1252,7 +1329,7 @@ client_Main.prototype = {
} else {
this.player.pause();
}
- if(Math.abs(time - newTime) < this.settings.synchThreshold) {
+ if(Math.abs(time - newTime) < synchThreshold) {
return;
}
this.player.setTime(newTime);
@@ -1329,9 +1406,10 @@ client_Main.prototype = {
this.player.setPlaybackRate(data.setRate.rate);
break;
case "SetTime":
+ var synchThreshold1 = this.settings.synchThreshold;
var newTime1 = data.setTime.time;
var time1 = this.player.getTime();
- if(Math.abs(time1 - newTime1) < this.settings.synchThreshold) {
+ if(Math.abs(time1 - newTime1) < synchThreshold1) {
return;
}
this.player.setTime(newTime1);
diff --git a/res/index.html b/res/index.html
index 27962d4..36d79be 100644
--- a/res/index.html
+++ b/res/index.html
@@ -35,6 +35,7 @@
<li class="dropdown"><a class="dropdown-toggle" href="#" data-toggle="dropdown">${settings}<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#" id="synchThresholdBtn">${synchThreshold}</a></li>
+ <li><a href="#" id="hotkeysBtn">${hotkeys}</a></li>
</ul>
</li>
<li class="dropdown"><a class="dropdown-toggle" href="#" data-toggle="dropdown">${layout}<b class="caret"></b></a>
diff --git a/res/langs/en.json b/res/langs/en.json
index 3524b15..36cb672 100644
--- a/res/langs/en.json
+++ b/res/langs/en.json
@@ -27,6 +27,7 @@
"exit": "Exit",
"settings": "Settings",
"synchThreshold": "Synch Threshold",
+ "hotkeys": "Hotkeys",
"channel": "Channel",
"layout": "Layout",
"swapLayout": "Swap Layout",
diff --git a/res/langs/ru.json b/res/langs/ru.json
index 8297c36..808eb56 100644
--- a/res/langs/ru.json
+++ b/res/langs/ru.json
@@ -27,6 +27,7 @@
"exit": "Выход",
"settings": "Настройки",
"synchThreshold": "Частота синхронизации",
+ "hotkeys": "Горячие клавиши",
"channel": "Канал",
"layout": "Разметка",
"swapLayout": "Сменить разметку",
diff --git a/src/KeyCode.hx b/src/KeyCode.hx
new file mode 100644
index 0000000..c380329
--- /dev/null
+++ b/src/KeyCode.hx
@@ -0,0 +1,202 @@
+package;
+
+// https://github.com/Kode/Kha/blob/master/Sources/kha/input/KeyCode.hx
+enum abstract KeyCode(Int) to Int {
+ var Unknown = 0;
+ var Back = 1; // Android
+ var Cancel = 3;
+ var Help = 6;
+ var Backspace = 8;
+ var Tab = 9;
+ var Clear = 12;
+ var Return = 13;
+ var Shift = 16;
+ var Control = 17;
+ var Alt = 18;
+ var Pause = 19;
+ var CapsLock = 20;
+ var Kana = 21;
+ var Hangul = 21;
+ var Eisu = 22;
+ var Junja = 23;
+ var Final = 24;
+ var Hanja = 25;
+ var Kanji = 25;
+ var Escape = 27;
+ var Convert = 28;
+ var NonConvert = 29;
+ var Accept = 30;
+ var ModeChange = 31;
+ var Space = 32;
+ var PageUp = 33;
+ var PageDown = 34;
+ var End = 35;
+ var Home = 36;
+ var Left = 37;
+ var Up = 38;
+ var Right = 39;
+ var Down = 40;
+ var Select = 41;
+ var Print = 42;
+ var Execute = 43;
+ var PrintScreen = 44;
+ var Insert = 45;
+ var Delete = 46;
+ var Zero = 48;
+ var One = 49;
+ var Two = 50;
+ var Three = 51;
+ var Four = 52;
+ var Five = 53;
+ var Six = 54;
+ var Seven = 55;
+ var Eight = 56;
+ var Nine = 57;
+ var Colon = 58;
+ var Semicolon = 59;
+ var LessThan = 60;
+ var Equals = 61;
+ var GreaterThan = 62;
+ var QuestionMark = 63;
+ var At = 64;
+ var A = 65;
+ var B = 66;
+ var C = 67;
+ var D = 68;
+ var E = 69;
+ var F = 70;
+ var G = 71;
+ var H = 72;
+ var I = 73;
+ var J = 74;
+ var K = 75;
+ var L = 76;
+ var M = 77;
+ var N = 78;
+ var O = 79;
+ var P = 80;
+ var Q = 81;
+ var R = 82;
+ var S = 83;
+ var T = 84;
+ var U = 85;
+ var V = 86;
+ var W = 87;
+ var X = 88;
+ var Y = 89;
+ var Z = 90;
+ var Win = 91;
+ var ContextMenu = 93;
+ var Sleep = 95;
+ var Numpad0 = 96;
+ var Numpad1 = 97;
+ var Numpad2 = 98;
+ var Numpad3 = 99;
+ var Numpad4 = 100;
+ var Numpad5 = 101;
+ var Numpad6 = 102;
+ var Numpad7 = 103;
+ var Numpad8 = 104;
+ var Numpad9 = 105;
+ var Multiply = 106;
+ var Add = 107;
+ var Separator = 108;
+ var Subtract = 109;
+ var Decimal = 110;
+ var Divide = 111;
+ var F1 = 112;
+ var F2 = 113;
+ var F3 = 114;
+ var F4 = 115;
+ var F5 = 116;
+ var F6 = 117;
+ var F7 = 118;
+ var F8 = 119;
+ var F9 = 120;
+ var F10 = 121;
+ var F11 = 122;
+ var F12 = 123;
+ var F13 = 124;
+ var F14 = 125;
+ var F15 = 126;
+ var F16 = 127;
+ var F17 = 128;
+ var F18 = 129;
+ var F19 = 130;
+ var F20 = 131;
+ var F21 = 132;
+ var F22 = 133;
+ var F23 = 134;
+ var F24 = 135;
+ var NumLock = 144;
+ var ScrollLock = 145;
+ var WinOemFjJisho = 146;
+ var WinOemFjMasshou = 147;
+ var WinOemFjTouroku = 148;
+ var WinOemFjLoya = 149;
+ var WinOemFjRoya = 150;
+ var Circumflex = 160;
+ var Exclamation = 161;
+ var DoubleQuote = 162;
+ var Hash = 163;
+ var Dollar = 164;
+ var Percent = 165;
+ var Ampersand = 166;
+ var Underscore = 167;
+ var OpenParen = 168;
+ var CloseParen = 169;
+ var Asterisk = 170;
+ var Plus = 171;
+ var Pipe = 172;
+ var HyphenMinus = 173;
+ var OpenCurlyBracket = 174;
+ var CloseCurlyBracket = 175;
+ var Tilde = 176;
+ var VolumeMute = 181;
+ var VolumeDown = 182;
+ var VolumeUp = 183;
+ var Comma = 188;
+ var Period = 190;
+ var Slash = 191;
+ var BackQuote = 192;
+ var OpenBracket = 219;
+ var BackSlash = 220;
+ var CloseBracket = 221;
+ var Quote = 222;
+ var Meta = 224;
+ var AltGr = 225;
+ var WinIcoHelp = 227;
+ var WinIco00 = 228;
+ var WinIcoClear = 230;
+ var WinOemReset = 233;
+ var WinOemJump = 234;
+ var WinOemPA1 = 235;
+ var WinOemPA2 = 236;
+ var WinOemPA3 = 237;
+ var WinOemWSCTRL = 238;
+ var WinOemCUSEL = 239;
+ var WinOemATTN = 240;
+ var WinOemFinish = 241;
+ var WinOemCopy = 242;
+ var WinOemAuto = 243;
+ var WinOemENLW = 244;
+ var WinOemBackTab = 245;
+ var ATTN = 246;
+ var CRSEL = 247;
+ var EXSEL = 248;
+ var EREOF = 249;
+ var Play = 250;
+ var Zoom = 251;
+ var PA1 = 253;
+ var WinOemClear = 254;
+
+ function normalize():KeyCode {
+ return switch (this) {
+ case 91, 93: Meta; // left/right in Chrome
+ case 186: Semicolon;
+ case 187: Equals;
+ case 189: HyphenMinus;
+ default: cast this;
+ }
+ }
+}
diff --git a/src/client/Buttons.hx b/src/client/Buttons.hx
index a04b444..769cb25 100644
--- a/src/client/Buttons.hx
+++ b/src/client/Buttons.hx
@@ -288,13 +288,54 @@ class Buttons {
public static function initTextButtons(main:Main):Void {
final synchThresholdBtn = ge("#synchThresholdBtn");
synchThresholdBtn.onclick = e -> {
- var secs = main.synchThreshold + 1;
+ var secs = settings.synchThreshold + 1;
if (secs > 5) secs = 1;
main.setSynchThreshold(secs);
- updateSynchThresholdBtn(main);
+ updateSynchThresholdBtn();
synchThresholdBtn.blur();
}
- updateSynchThresholdBtn(main);
+ updateSynchThresholdBtn();
+
+ final hotkeysBtn = ge("#hotkeysBtn");
+ hotkeysBtn.onclick = e -> {
+ settings.hotkeysEnabled = !settings.hotkeysEnabled;
+ Settings.write(settings);
+ updateHotkeysBtn();
+ hotkeysBtn.blur();
+ }
+ updateHotkeysBtn();
+ }
+
+ 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)";
+ window.onkeydown = function(e:KeyboardEvent) {
+ if (!settings.hotkeysEnabled) return;
+ final target:Element = cast e.target;
+ if (target.isContentEditable) return;
+ final tagName = target.tagName;
+ if (tagName == "INPUT" || tagName == "TEXTAREA") return;
+ final key:KeyCode = cast e.keyCode;
+ if (key == Backspace) e.preventDefault();
+ if (!e.altKey) return;
+ switch (key) {
+ case R: ge("#mediarefresh").onclick();
+ case S: ge("#voteskip").onclick();
+ case C: ge("#getplaylist").onclick();
+ case F: ge("#fullscreenbtn").onclick();
+ case L: ge("#leader_btn").onclick();
+ case P:
+ if (!main.isLeader()) {
+ Timer.delay(() -> player.pause(), 500);
+ }
+ ge("#leader_btn").onclick();
+ default: return;
+ }
+ e.preventDefault();
+ }
}
static function hideMenus():Void {
@@ -302,12 +343,18 @@ class Buttons {
for (menu in menus) menu.style.display = "";
}
- static function updateSynchThresholdBtn(main:Main):Void {
+ static function updateSynchThresholdBtn():Void {
final text = Lang.get("synchThreshold");
- final secs = main.synchThreshold;
+ final secs = settings.synchThreshold;
ge("#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';
+ }
+
static function initChatInput(main:Main):Void {
final guestName:InputElement = cast ge("#guestname");
guestName.onkeydown = e -> {
diff --git a/src/client/ClientSettings.hx b/src/client/ClientSettings.hx
index 4e931d3..213d463 100644
--- a/src/client/ClientSettings.hx
+++ b/src/client/ClientSettings.hx
@@ -10,5 +10,6 @@ typedef ClientSettings = {
synchThreshold:Int,
isSwapped:Bool,
isUserListHidden:Bool,
- latestLinks:Array<String>
+ latestLinks:Array<String>,
+ hotkeysEnabled:Bool
}
diff --git a/src/client/Main.hx b/src/client/Main.hx
index 9ecae82..deeb2ec 100644
--- a/src/client/Main.hx
+++ b/src/client/Main.hx
@@ -22,10 +22,9 @@ using ClientTools;
class Main {
- static inline var SETTINGS_VERSION = 1;
+ static inline var SETTINGS_VERSION = 2;
public final settings:ClientSettings;
public var isSyncActive = true;
- public var synchThreshold(get, never):Int;
final clients:Array<Client> = [];
var pageTitle = document.title;
final host:String;
@@ -59,7 +58,8 @@ class Main {
synchThreshold: 2,
isSwapped: false,
isUserListHidden: false,
- latestLinks: []
+ latestLinks: [],
+ hotkeysEnabled: true
}
Settings.init(defaults, settingsPatcher);
settings = Settings.read();
@@ -76,18 +76,16 @@ class Main {
}
Lang.init("langs", () -> {
Buttons.initTextButtons(this);
+ Buttons.initHotkeys(this, player);
openWebSocket(host, port);
});
}
- inline function get_synchThreshold():Int {
- return settings.synchThreshold;
- }
-
function settingsPatcher(data:Any, version:Int):Any {
switch (version) {
- // case 1:
- // final data:ClientSettings = data;
+ case 1:
+ final data:ClientSettings = data;
+ data.hotkeysEnabled = true;
case SETTINGS_VERSION, _:
throw 'skipped version $version';
}
@@ -400,6 +398,7 @@ class Main {
player.setPlaybackRate(data.getTime.rate);
}
+ final synchThreshold = settings.synchThreshold;
final newTime = data.getTime.time;
final time = player.getTime();
if (isLeader()) {
@@ -416,6 +415,7 @@ class Main {
player.setTime(newTime);
case SetTime:
+ final synchThreshold = settings.synchThreshold;
final newTime = data.setTime.time;
final time = player.getTime();
if (Math.abs(time - newTime) < synchThreshold) return;
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage