aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRblSb <msrblsb@gmail.com>2021-07-04 03:59:50 +0300
committerRblSb <msrblsb@gmail.com>2021-07-05 17:04:25 +0300
commitede45cea8706eb8540e466df9861c2af8ebf9c44 (patch)
tree74a20a6f082173378f918b48b08542881f31749a
parent265b3e1fb56bb0e5f797b3b35227a616b108a0c3 (diff)
Reformat
-rw-r--r--.vscode/extensions.json6
-rw-r--r--.vscode/launch.json3
-rw-r--r--.vscode/settings.json18
-rw-r--r--README.md2
-rw-r--r--build/server.js42
-rw-r--r--hxformat.json24
-rw-r--r--res/css/des.css79
-rw-r--r--res/index.html81
-rw-r--r--src/Client.hx13
-rw-r--r--src/ClientTools.hx4
-rw-r--r--src/Lang.hx10
-rw-r--r--src/VideoList.hx7
-rw-r--r--src/client/Buttons.hx43
-rw-r--r--src/client/IPlayer.hx4
-rw-r--r--src/client/InputWithHistory.hx12
-rw-r--r--src/client/JsApi.hx23
-rw-r--r--src/client/Main.hx97
-rw-r--r--src/client/Player.hx47
-rw-r--r--src/client/Settings.hx6
-rw-r--r--src/client/Utils.hx11
-rw-r--r--src/client/players/Iframe.hx15
-rw-r--r--src/client/players/Raw.hx19
-rw-r--r--src/client/players/Youtube.hx21
-rw-r--r--src/server/ConsoleInput.hx15
-rw-r--r--src/server/HttpServer.hx20
-rw-r--r--src/server/Logger.hx9
-rw-r--r--src/server/Main.hx114
-rw-r--r--src/server/ServerState.hx3
-rw-r--r--src/server/Utils.hx15
-rw-r--r--src/server/VideoTimer.hx3
-rw-r--r--test/Main.hx2
-rw-r--r--test/tests/TestTimer.hx8
32 files changed, 464 insertions, 312 deletions
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..fc94805
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+ "recommendations": [
+ "nadako.vshaxe",
+ "hookyqr.beautify"
+ ]
+}
diff --git a/.vscode/launch.json b/.vscode/launch.json
index df67501..412a615 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,13 +1,14 @@
{
"configurations": [
{
- "type": "node",
+ "type": "pwa-node",
"request": "launch",
"name": "Node: build and run",
"program": "${workspaceFolder}/build/server.js",
"args": ["--verbose"],
"sourceMaps": true,
"preLaunchTask": "Build all",
+ "killBehavior": "polite",
"console": "integratedTerminal"
}
]
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 047e16b..575d45b 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,10 +1,24 @@
{
"haxe.configurations": [
- ["build-server.hxml"]
+ ["build-server.hxml"]
],
"search.exclude": {
"build": true,
"res/temp": true,
"res/client.js": true
- }
+ },
+ "[haxe]": {
+ "editor.formatOnSave": true,
+ "editor.codeActionsOnSave": {
+ "source.organizeImports": true
+ }
+ },
+ "[html]": {
+ "editor.formatOnSave": true,
+ "editor.defaultFormatter": "vscode.html-language-features"
+ },
+ "[css]": {
+ "editor.formatOnSave": true,
+ "editor.defaultFormatter": "HookyQR.beautify"
+ },
}
diff --git a/README.md b/README.md
index 5c25aff..ce2caa1 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Default channel example: http://synctube-example.herokuapp.com/
### New features
- Reworked layout and theme
- Multi-Language support
-- Hotkeys (`Alt-P` for global play/pause, [etc](https://github.com/RblSb/SyncTube/blob/80ec4ba1747d22ec136a95d6b35ba6289e15e8ad/src/client/Buttons.hx#L254-L258))
+- Hotkeys (`Alt-P` for global play/pause, [etc](https://github.com/RblSb/SyncTube/blob/80ec4ba1747d22ec136a95d6b35ba6289e15e8ad/src/client/Buttons.hx#L267-L271))
- Mobile view with page fullscreen
- Way to play local videos for network users (without NAT loopback feature)
- Playback rate synchronization (with leader)
diff --git a/build/server.js b/build/server.js
index f23658a..8f47179 100644
--- a/build/server.js
+++ b/build/server.js
@@ -3428,7 +3428,7 @@ server_ConsoleInput.prototype = {
}
}
var _g1 = 0;
- while(_g1 < _g.length) haxe_Log.trace(haxe_io_Path.withoutExtension(_g[_g1++]),{ fileName : "src/server/ConsoleInput.hx", lineNumber : 121, className : "server.ConsoleInput", methodName : "parseLine"});
+ while(_g1 < _g.length) haxe_Log.trace(haxe_io_Path.withoutExtension(_g[_g1++]),{ fileName : "src/server/ConsoleInput.hx", lineNumber : 122, className : "server.ConsoleInput", methodName : "parseLine"});
break;
case "replay":
server_Utils.ensureDir(this.main.logsDir);
@@ -3446,7 +3446,7 @@ server_ConsoleInput.prototype = {
var len = args.length;
var actual = this.commands.h[command].args.length;
if(len != actual) {
- haxe_Log.trace("Wrong count of arguments for command \"" + command + "\" (" + len + " instead of " + actual + ")",{ fileName : "src/server/ConsoleInput.hx", lineNumber : 132, className : "server.ConsoleInput", methodName : "isValidArgs"});
+ haxe_Log.trace("Wrong count of arguments for command \"" + command + "\" (" + len + " instead of " + actual + ")",{ fileName : "src/server/ConsoleInput.hx", lineNumber : 134, className : "server.ConsoleInput", methodName : "isValidArgs"});
return false;
}
return true;
@@ -3476,7 +3476,7 @@ server_ConsoleInput.prototype = {
var data = _g.value;
list.push("" + StringTools.rpad("/" + _g.key + " " + data.args.join(" ")," ",maxLength) + " | " + data.desc);
}
- haxe_Log.trace("Unknown command \"" + line + "\". List:\n" + list.join("\n"),{ fileName : "src/server/ConsoleInput.hx", lineNumber : 151, className : "server.ConsoleInput", methodName : "printHelp"});
+ haxe_Log.trace("Unknown command \"" + line + "\". List:\n" + list.join("\n"),{ fileName : "src/server/ConsoleInput.hx", lineNumber : 153, className : "server.ConsoleInput", methodName : "printHelp"});
}
,__class__: server_ConsoleInput
};
@@ -3765,9 +3765,9 @@ var server_Main = function() {
var attempts = 5;
var preparePort = null;
preparePort = function() {
- server_Utils.isPortFree(_gthis.port,function(free) {
- if(!free && attempts > 0) {
- haxe_Log.trace("Warning: port " + _gthis.port + " is already in use. Changed to " + (_gthis.port + 1),{ fileName : "src/server/Main.hx", lineNumber : 92, className : "server.Main", methodName : "new"});
+ server_Utils.isPortFree(_gthis.port,function(isFree) {
+ if(!isFree && attempts > 0) {
+ haxe_Log.trace("Warning: port " + _gthis.port + " is already in use. Changed to " + (_gthis.port + 1),{ fileName : "src/server/Main.hx", lineNumber : 97, className : "server.Main", methodName : "new"});
attempts -= 1;
_gthis.port++;
preparePort();
@@ -3785,10 +3785,10 @@ server_Main.main = function() {
server_Main.prototype = {
runServer: function() {
var _gthis = this;
- haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 105, className : "server.Main", methodName : "runServer"});
+ haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 110, className : "server.Main", methodName : "runServer"});
server_Utils.getGlobalIp(function(ip) {
_gthis.globalIp = ip;
- haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 108, className : "server.Main", methodName : "runServer"});
+ haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 113, className : "server.Main", methodName : "runServer"});
});
var dir = "" + this.rootDir + "/res";
server_HttpServer.init(dir,"" + this.rootDir + "/user/res",this.config.localAdmins);
@@ -3865,7 +3865,7 @@ server_Main.prototype = {
var field = _g1[_g];
++_g;
if(Reflect.field(config,field) == null) {
- haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 170, className : "server.Main", methodName : "getUserConfig"});
+ haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 179, className : "server.Main", methodName : "getUserConfig"});
}
config[field] = Reflect.field(customConfig,field);
}
@@ -3876,14 +3876,14 @@ server_Main.prototype = {
var emote = _g1[_g];
++_g;
if(emoteCopies_h[emote.name]) {
- haxe_Log.trace("Warning: emote name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 175, className : "server.Main", methodName : "getUserConfig"});
+ haxe_Log.trace("Warning: emote name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 185, className : "server.Main", methodName : "getUserConfig"});
}
emoteCopies_h[emote.name] = true;
if(!this.verbose) {
continue;
}
if(emoteCopies_h[emote.image]) {
- haxe_Log.trace("Warning: emote url of name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 178, className : "server.Main", methodName : "getUserConfig"});
+ haxe_Log.trace("Warning: emote url of name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 189, className : "server.Main", methodName : "getUserConfig"});
}
emoteCopies_h[emote.image] = true;
}
@@ -3902,7 +3902,7 @@ server_Main.prototype = {
js_node_Fs.writeFileSync("" + folder + "/users.json",JSON.stringify(users,null,"\t"));
}
,saveState: function() {
- haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 200, className : "server.Main", methodName : "saveState"});
+ haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 212, className : "server.Main", methodName : "saveState"});
var json = JSON.stringify({ videoList : this.videoList, isPlaylistOpen : this.isPlaylistOpen, itemPos : this.itemPos, messages : this.messages, timer : { time : this.videoTimer.getTime(), paused : this.videoTimer.isPaused()}},null,"\t");
js_node_Fs.writeFileSync(this.statePath,json);
}
@@ -3910,7 +3910,7 @@ server_Main.prototype = {
if(!sys_FileSystem.exists(this.statePath)) {
return;
}
- haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 217, className : "server.Main", methodName : "loadState"});
+ haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 229, className : "server.Main", methodName : "loadState"});
var data = JSON.parse(js_node_Fs.readFileSync(this.statePath,{ encoding : "utf8"}));
this.videoList.length = 0;
this.messages.length = 0;
@@ -3927,7 +3927,7 @@ server_Main.prototype = {
this.videoTimer.pause();
}
,logError: function(type,data) {
- haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 231, className : "server.Main", methodName : "logError", customParams : [data]});
+ haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 247, className : "server.Main", methodName : "logError", customParams : [data]});
var crashesFolder = "" + this.rootDir + "/user/crashes";
server_Utils.ensureDir(crashesFolder);
js_node_Fs.writeFileSync("" + crashesFolder + "/" + (DateTools.format(new Date(),"%Y-%m-%d_%H_%M_%S") + "-" + type) + ".json",JSON.stringify(data,null,"\t"));
@@ -3943,7 +3943,7 @@ server_Main.prototype = {
if(_gthis.clients.length == 0) {
return;
}
- haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 246, className : "server.Main", methodName : "initIntergationHandlers"});
+ haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 262, className : "server.Main", methodName : "initIntergationHandlers"});
js_node_Http.get(url,null,function(r) {
});
};
@@ -3957,7 +3957,7 @@ server_Main.prototype = {
}
this.userList.admins.push({ name : name, hash : hash});
this.writeUsers(this.userList);
- haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 261, className : "server.Main", methodName : "addAdmin"});
+ haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 277, className : "server.Main", methodName : "addAdmin"});
}
,replayLog: function(events) {
var _gthis = this;
@@ -4001,7 +4001,7 @@ server_Main.prototype = {
var ip = req.connection.remoteAddress;
var id = this.freeIds.length > 0 ? this.freeIds.shift() : this.clients.length;
var name = "Guest " + (id + 1);
- haxe_Log.trace("" + name + " connected (" + ip + ")",{ fileName : "src/server/Main.hx", lineNumber : 299, className : "server.Main", methodName : "onConnect"});
+ haxe_Log.trace("" + name + " connected (" + ip + ")",{ fileName : "src/server/Main.hx", lineNumber : 315, className : "server.Main", methodName : "onConnect"});
var client = new Client(ws,req,id,name,0);
client.setGroupFlag(ClientGroup.Admin,this.config.localAdmins && req.connection.localAddress == ip);
this.clients.push(client);
@@ -4013,7 +4013,7 @@ server_Main.prototype = {
var obj = _gthis.wsEventParser.fromJson(data);
if(_gthis.wsEventParser.errors.length > 0 || _gthis.noTypeObj(obj)) {
var errors = "" + ("Wrong request for type \"" + obj.type + "\":") + "\n" + json2object_ErrorUtils.convertErrorArray(_gthis.wsEventParser.errors);
- haxe_Log.trace(errors,{ fileName : "src/server/Main.hx", lineNumber : 315, className : "server.Main", methodName : "onConnect"});
+ haxe_Log.trace(errors,{ fileName : "src/server/Main.hx", lineNumber : 331, className : "server.Main", methodName : "onConnect"});
_gthis.serverMessage(client,errors);
return;
}
@@ -4113,7 +4113,7 @@ server_Main.prototype = {
if(!internal) {
return;
}
- haxe_Log.trace("Client " + client.name + " disconnected",{ fileName : "src/server/Main.hx", lineNumber : 370, className : "server.Main", methodName : "onMessage"});
+ haxe_Log.trace("Client " + client.name + " disconnected",{ fileName : "src/server/Main.hx", lineNumber : 387, className : "server.Main", methodName : "onMessage"});
server_Utils.sortedPush(this.freeIds,client.id);
HxOverrides.remove(this.clients,client);
this.sendClientList();
@@ -4526,7 +4526,7 @@ server_Utils.isPortFree = function(port,callback) {
});
server.once("timeout",function() {
status = false;
- haxe_Log.trace("Timeout (" + timeout + "ms) occurred waiting for port " + port + " to be available",{ fileName : "src/server/Utils.hx", lineNumber : 27, className : "server.Utils", methodName : "isPortFree"});
+ haxe_Log.trace("Timeout (" + timeout + "ms) occurred waiting for port " + port + " to be available",{ fileName : "src/server/Utils.hx", lineNumber : 26, className : "server.Utils", methodName : "isPortFree"});
server.close();
});
server.once("listening",function() {
@@ -4540,7 +4540,7 @@ server_Utils.isPortFree = function(port,callback) {
};
server_Utils.getGlobalIp = function(callback) {
var onError = function(e) {
- haxe_Log.trace("Warning: connection error, server is local.",{ fileName : "src/server/Utils.hx", lineNumber : 40, className : "server.Utils", methodName : "getGlobalIp"});
+ haxe_Log.trace("Warning: connection error, server is local.",{ fileName : "src/server/Utils.hx", lineNumber : 39, className : "server.Utils", methodName : "getGlobalIp"});
callback("127.0.0.1");
};
var url = new js_node_url_URL("https://myexternalip.com/raw");
diff --git a/hxformat.json b/hxformat.json
new file mode 100644
index 0000000..c81c102
--- /dev/null
+++ b/hxformat.json
@@ -0,0 +1,24 @@
+{
+ "indentation": {
+ "tabWidth": 2
+ },
+ "sameLine": {
+ "ifBody": "same",
+ "elseBody": "same",
+ "ifElse": "keep",
+ "comprehensionFor": "keep"
+ },
+ "wrapping": {
+ "maxLineLength": 90,
+ "arrayMatrixWrap": "matrixWrapNoAlign",
+ "arrayWrap": {
+ "defaultWrap": "keep"
+ },
+ "functionSignature": {
+ "defaultWrap": "keep"
+ },
+ "callParameter": {
+ "defaultWrap": "keep"
+ }
+ }
+}
diff --git a/res/css/des.css b/res/css/des.css
index 6877c81..e6e9145 100644
--- a/res/css/des.css
+++ b/res/css/des.css
@@ -1,4 +1,5 @@
@charset "utf-8";
+
/* CSS Document */
@import url(https://rsms.me/inter/inter.css);
@@ -19,7 +20,10 @@
html {
box-sizing: border-box;
}
-*, *:before, *:after {
+
+*,
+*:before,
+*:after {
box-sizing: inherit;
}
@@ -140,7 +144,7 @@ button[disabled]:hover {
cursor: default;
}
-button > * {
+button>* {
line-height: 1;
}
@@ -174,7 +178,7 @@ textarea {
color: var(--foreground);
background-color: var(--background-video);
border: .125rem solid;
- border-color: var(--border);
+ border-color: var(--border);
transition: border-color ease-in-out .15s;
}
@@ -218,14 +222,16 @@ button.danger-bg:focus {
background-color: var(--error);
}
-.server-msg-disconnect, .server-msg-reconnect {
+.server-msg-disconnect,
+.server-msg-reconnect {
text-align: center;
}
.collapse {
- display :none;
- visibility :hidden;
+ display: none;
+ visibility: hidden;
}
+
.collapse.in {
display: block;
visibility: visible;
@@ -260,7 +266,7 @@ button.danger-bg:focus {
margin-right: .5rem;
}
-.info header > *:not(:last-child) {
+.info header>*:not(:last-child) {
margin-right: .5rem;
}
@@ -342,7 +348,7 @@ header h4 {
padding-top: 0;
}
-.metadata > span {
+.metadata>span {
display: flex;
align-items: center;
margin-right: 1rem;
@@ -358,7 +364,7 @@ header h4 {
min-width: 2rem;
}
-#insert_template > div:first-child {
+#insert_template>div:first-child {
text-align: center;
flex-grow: 1;
}
@@ -370,12 +376,13 @@ header h4 {
max-width: 32rem;
}
-#addfromurl > *,
-#customembed > * {
+#addfromurl>*,
+#customembed>* {
margin-bottom: 1rem;
}
-#mediatitle, #subsurl {
+#mediatitle,
+#subsurl {
margin-left: 2rem;
flex-grow: 1;
}
@@ -384,8 +391,8 @@ header h4 {
flex-grow: 2;
}
-#customembed > input,
-#customembed > textarea {
+#customembed>input,
+#customembed>textarea {
display: block;
width: 100%;
}
@@ -452,7 +459,7 @@ footer#footer {
flex-direction: column;
flex-wrap: nowrap;
padding: 1rem;
- height: calc( 100vh - 56.25vw );
+ height: calc(100vh - 56.25vw);
}
#chat header {
@@ -486,7 +493,7 @@ footer#footer {
cursor: pointer;
}
-.userlist_item > *:not(:last-child) {
+.userlist_item>*:not(:last-child) {
margin-right: .25em;
}
@@ -552,6 +559,7 @@ footer#footer {
}
/* Message buffer */
+
#messagebuffer {
flex-grow: 2;
flex-shrink: 8;
@@ -562,7 +570,7 @@ footer#footer {
height: 100%;
}
-#messagebuffer > * {
+#messagebuffer>* {
margin-bottom: 1em;
}
@@ -601,7 +609,7 @@ footer#footer {
flex-direction: row;
}
-#chatbox > *:not(:first-child) {
+#chatbox>*:not(:first-child) {
margin-left: .5rem;
}
@@ -614,14 +622,14 @@ footer#footer {
#smileswrap {
display: none;
- background: rgba(0,0,0,0.7);
+ background: rgba(0, 0, 0, 0.7);
width: 100%;
height: 12rem;
padding: 1rem;
border-radius: 1rem;
overflow-y: scroll;
text-align: center;
- grid-template-columns: repeat( auto-fit, minmax( 4rem, 1fr ) );
+ grid-template-columns: repeat(auto-fit, minmax(4rem, 1fr));
grid-gap: .5rem;
gap: .5rem;
}
@@ -643,7 +651,8 @@ footer#footer {
max-height: 12.5rem;
}
-#guestlogin, #guestpassword {
+#guestlogin,
+#guestpassword {
display: flex;
flex-direction: column;
padding-top: 1rem;
@@ -653,12 +662,13 @@ footer#footer {
/* Guest login */
-#guestlogin label, #guestpassword label {
+#guestlogin label,
+#guestpassword label {
display: block;
margin-bottom: 1em;
}
-#guestpassword span > *:not(:first-child) {
+#guestpassword span>*:not(:first-child) {
margin-left: .5rem;
}
@@ -666,6 +676,16 @@ footer#footer {
cursor: pointer;
}
+#passwordbox {
+ display: flex;
+ flex-direction: row;
+}
+
+#guestpass {
+ flex-grow: 2;
+ width: 2rem;
+}
+
/*
* End chat
*/
@@ -673,19 +693,24 @@ footer#footer {
/*
* Scrollbar
*/
+
html {
scrollbar-color: rgba(255, 255, 255, 0.1) transparent;
scrollbar-width: thin;
}
+
::-webkit-scrollbar {
width: 5px;
}
+
::-webkit-scrollbar-track {
background: transparent;
}
+
::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.1);
}
+
::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.2);
}
@@ -703,12 +728,15 @@ html {
width: 100%;
height: 100vh;
}
+
body.swap {
grid-template-areas: "chat gutter video";
}
+
.info {
flex-wrap: nowrap;
}
+
#video {
grid-area: video;
width: 100%;
@@ -716,6 +744,7 @@ html {
overflow: auto;
background: var(--background-video);
}
+
#header {
display: flex;
flex: 1;
@@ -725,10 +754,12 @@ html {
text-overflow: ellipsis;
font-size: 1.953rem;
}
+
#currenttitle {
text-overflow: ellipsis;
overflow: hidden;
}
+
.gutter {
grid-area: gutter;
display: block;
@@ -736,9 +767,11 @@ html {
background-color: var(--border);
transition: background-color ease-in-out .15s;
}
+
.gutter:hover {
background-color: var(--accent);
}
+
#chat {
grid-area: chat;
height: 100vh;
diff --git a/res/index.html b/res/index.html
index c7673b1..766ec7c 100644
--- a/res/index.html
+++ b/res/index.html
@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html>
+
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
@@ -11,11 +12,12 @@
<script type="module" src="https://cdn.jsdelivr.net/npm/ionicons@5.0.0/dist/ionicons/ionicons.esm.js"></script>
<script nomodule="" src="https://cdn.jsdelivr.net/npm/ionicons@5.0.0/dist/ionicons/ionicons.js"></script>
</head>
+
<body style="grid-template-columns: 1fr 4px 300px;">
<!-- Video -->
<main id="video">
<!-- Player -->
- <section id="player" >
+ <section id="player">
<div id="ytapiplayer" class="embed-responsive embed-responsive-16by9"></div>
<!-- Video info -->
<div class="info">
@@ -24,10 +26,18 @@
</header>
<!-- Video controls -->
<span class="controls">
- <button id="togglesynch" title="${toggleVideoSync}"><ion-icon id="pause-indicator" name="play"></ion-icon></button>
- <button id="mediarefresh" title="${refreshPlayer}"><ion-icon name="refresh"></ion-icon></button>
- <button id="fullscreenbtn" title="${fullscreenPlayer}"><ion-icon name="expand"></ion-icon></button>
- <button id="voteskip" title="${voteForSkip}"><ion-icon name="play-skip-forward"></ion-icon></button>
+ <button id="togglesynch" title="${toggleVideoSync}">
+ <ion-icon id="pause-indicator" name="play"></ion-icon>
+ </button>
+ <button id="mediarefresh" title="${refreshPlayer}">
+ <ion-icon name="refresh"></ion-icon>
+ </button>
+ <button id="fullscreenbtn" title="${fullscreenPlayer}">
+ <ion-icon name="expand"></ion-icon>
+ </button>
+ <button id="voteskip" title="${voteForSkip}">
+ <ion-icon name="play-skip-forward"></ion-icon>
+ </button>
</span>
</div>
</section>
@@ -37,21 +47,39 @@
<div class="info">
<header>
<h3>${playlist}</h3>
- <button id="lockplaylist" title="${playlistOpen}"><ion-icon name="lock-open"></ion-icon></button>
- <button id="getplaylist" title="${retrievePlaylistLinks}"><ion-icon name="link"></ion-icon></button>
+ <button id="lockplaylist" title="${playlistOpen}">
+ <ion-icon name="lock-open"></ion-icon>
+ </button>
+ <button id="getplaylist" title="${retrievePlaylistLinks}">
+ <ion-icon name="link"></ion-icon>
+ </button>
</header>
<!-- Playlist controls -->
<span class="controls">
- <button class="collapsed" id="showmediaurl" title="${addVideoFromUrl}" data-toggle="collapse" data-target="#addfromurl" aria-expanded="false"><ion-icon name="add"></ion-icon></button>
- <button class="collapsed" id="showcustomembed" title="${embedCustomFrame}" data-toggle="collapse" data-target="#customembed" aria-expanded="false"><ion-icon name="code"></ion-icon></button>
- <button id="shuffleplaylist" title="${shufflePlaylist}"><ion-icon name="shuffle"></ion-icon></button>
- <button id="clearplaylist" title="${clearPlaylist}"><ion-icon name="close"></ion-icon></button>
+ <button class="collapsed" id="showmediaurl" title="${addVideoFromUrl}" data-toggle="collapse"
+ data-target="#addfromurl" aria-expanded="false">
+ <ion-icon name="add"></ion-icon>
+ </button>
+ <button class="collapsed" id="showcustomembed" title="${embedCustomFrame}" data-toggle="collapse"
+ data-target="#customembed" aria-expanded="false">
+ <ion-icon name="code"></ion-icon>
+ </button>
+ <button id="shuffleplaylist" title="${shufflePlaylist}">
+ <ion-icon name="shuffle"></ion-icon>
+ </button>
+ <button id="clearplaylist" title="${clearPlaylist}">
+ <ion-icon name="close"></ion-icon>
+ </button>
</span>
</div>
<!-- Playlist metadata -->
<div class="metadata">
- <span><ion-icon name="logo-youtube"></ion-icon><span id="plcount">0 ${videos}</span></span>
- <span><ion-icon name="time"></ion-icon><span id="pllength">00:00</span></span>
+ <span>
+ <ion-icon name="logo-youtube"></ion-icon><span id="plcount">0 ${videos}</span>
+ </span>
+ <span>
+ <ion-icon name="time"></ion-icon><span id="pllength">00:00</span>
+ </span>
</div>
<!-- Add video -->
<div class="collapse" id="addfromurl" aria-expanded="false">
@@ -77,7 +105,8 @@
</div>
<div class="collapse" id="customembed" aria-expanded="false">
<input id="customembed-title" type="text" placeholder="${optionalTitle}">
- <textarea id="customembed-content" rows="5" placeholder="${pasteEmbedCodeAndClick} '${queueNext}' ${or} '${queueLast}'. &#10;${acceptableEmbedCodesAre} &lt;iframe&gt; ${or} &lt;object&gt;. &#10;${customEmbedsCannotBeSynchronized}."></textarea>
+ <textarea id="customembed-content" rows="5"
+ placeholder="${pasteEmbedCodeAndClick} '${queueNext}' ${or} '${queueLast}'. &#10;${acceptableEmbedCodesAre} &lt;iframe&gt; ${or} &lt;object&gt;. &#10;${customEmbedsCannotBeSynchronized}."></textarea>
<div>
<button id="ce_queue_next">${queueNext}</button>
<button id="ce_queue_end">${queueLast}</button>
@@ -87,15 +116,15 @@
</div>
</div>
<!-- Queue -->
- <div id="queuefail">
- </div>
+ <div id="queuefail"></div>
<div>
<ul class="ui-sortable queue_sortable" id="queue"></ul>
</div>
</section>
<!-- Footer -->
<footer id="footer">
- <p>Powered by <a href="https://github.com/RblSb/SyncTube" target="_blank" rel="noreferrer noopener">SyncTube</a></p>
+ <p>Powered by <a href="https://github.com/RblSb/SyncTube" target="_blank" rel="noreferrer noopener">SyncTube</a>
+ </p>
</footer>
</main>
@@ -113,7 +142,10 @@
<span>
<button id="leader_btn" title="${leaderDesc}">${leader}</button>
<!-- Settings button -->
- <button id="showoptions" class="collapsed" data-toggle="collapse" data-target="#optionsPanel" aria-expanded="false"><ion-icon name="settings-sharp"></ion-icon></button>
+ <button id="showoptions" class="collapsed" data-toggle="collapse" data-target="#optionsPanel"
+ aria-expanded="false">
+ <ion-icon name="settings-sharp"></ion-icon>
+ </button>
</span>
</div>
<!-- User list -->
@@ -144,7 +176,9 @@
<!-- Message input -->
<div id="chatbox">
<input id="chatline" type="text" placeholder="${chatlinePlaceholder}">
- <button id="smilesbtn" title="${emotes}"><ion-icon name="happy"></ion-icon></button>
+ <button id="smilesbtn" title="${emotes}">
+ <ion-icon name="happy"></ion-icon>
+ </button>
</div>
<div id="smileswrap"></div>
<!-- Guest login -->
@@ -154,10 +188,12 @@
</div>
<div id="guestpassword" style="display: none;">
<label>${enterUserPassword}</label>
- <span>
+ <div id="passwordbox">
<input id="guestpass" type="text" placeholder="${yourPassword}">
- <button id="guestpass_icon"><ion-icon name="eye"></ion-icon></button>
- </span>
+ <button id="guestpass_icon">
+ <ion-icon name="eye"></ion-icon>
+ </button>
+ </div>
</div>
</aside>
@@ -165,4 +201,5 @@
<script src="client.js"></script>
<script src="js/custom.js"></script>
</body>
+
</html>
diff --git a/src/Client.hx b/src/Client.hx
index c7bc256..254e294 100644
--- a/src/Client.hx
+++ b/src/Client.hx
@@ -18,7 +18,6 @@ typedef ClientData = {
}
class Client {
-
#if nodejs
public final ws:WebSocket;
public final id:Int;
@@ -33,17 +32,18 @@ class Client {
#if nodejs
public function new(?ws:WebSocket, ?req:IncomingMessage, ?id:Int, name:String, group:Int) {
- #else
- public function new(name:String, group:Int) {
- #end
- #if nodejs
this.ws = ws;
this.req = req;
this.id = id;
- #end
this.name = name;
this.group = new EnumFlags(group);
}
+ #else
+ public function new(name:String, group:Int) {
+ this.name = name;
+ this.group = new EnumFlags(group);
+ }
+ #end
inline function get_isUser():Bool {
return group.has(User);
@@ -85,5 +85,4 @@ class Client {
public static function fromData(data:ClientData):Client {
return new Client(data.name, data.group);
}
-
}
diff --git a/src/ClientTools.hx b/src/ClientTools.hx
index e83e450..b4ac9cb 100644
--- a/src/ClientTools.hx
+++ b/src/ClientTools.hx
@@ -1,10 +1,9 @@
package;
-import Types.Permissions;
import Types.Permission;
+import Types.Permissions;
class ClientTools {
-
public static function setLeader(clients:Array<Client>, name:String):Void {
for (client in clients) {
if (client.name == name) client.isLeader = true;
@@ -35,5 +34,4 @@ class ClientTools {
if (client.isUser) return p.user.contains(permission);
return p.guest.contains(permission);
}
-
}
diff --git a/src/Lang.hx b/src/Lang.hx
index 7b7642d..3bd6963 100644
--- a/src/Lang.hx
+++ b/src/Lang.hx
@@ -2,24 +2,25 @@ package;
import haxe.Json;
import haxe.io.Path;
+
+using Lambda;
+
#if (sys || nodejs)
import sys.io.File;
#else
import haxe.Http;
#end
-using Lambda;
private typedef LangMap = Map<String, String>;
class Lang {
-
static final langs:Map<String, LangMap> = [];
static var ids = ["en", "ru"];
#if (js && !nodejs)
static var lang = js.Browser.navigator.language.substr(0, 2).toLowerCase();
#end
- static function request(path:String, callback:(data:String)->Void):Void {
+ static function request(path:String, callback:(data:String) -> Void):Void {
#if (sys || nodejs)
callback(File.getContent(path));
#else
@@ -29,7 +30,7 @@ class Lang {
#end
}
- public static function init(folderPath:String, ?callback:()->Void):Void {
+ public static function init(folderPath:String, ?callback:() -> Void):Void {
#if (js && !nodejs)
// Filter unused languages
ids = ids.filter(id -> id == lang || id == "en");
@@ -64,5 +65,4 @@ class Lang {
return text == null ? key : text;
}
#end
-
}
diff --git a/src/VideoList.hx b/src/VideoList.hx
index 0799cfa..ef1d113 100644
--- a/src/VideoList.hx
+++ b/src/VideoList.hx
@@ -7,10 +7,8 @@ import Types.VideoItem;
// items:Array<VideoItem>,
// itemPos:Int
// }
-
@:forward
abstract VideoList(Array<VideoItem>) from Array<VideoItem> to Array<VideoItem> {
-
public function new() {
this = [];
}
@@ -68,8 +66,9 @@ abstract VideoList(Array<VideoItem>) from Array<VideoItem> to Array<VideoItem> {
public function itemsByUser(client:Client):Int {
var i = 0;
- for (item in this) if (item.author == client.name) i++;
+ for (item in this) {
+ if (item.author == client.name) i++;
+ }
return i;
}
-
}
diff --git a/src/client/Buttons.hx b/src/client/Buttons.hx
index 8ed259a..ee42f44 100644
--- a/src/client/Buttons.hx
+++ b/src/client/Buttons.hx
@@ -1,17 +1,17 @@
package client;
-import js.html.ImageElement;
-import haxe.Timer;
-import js.html.KeyboardEvent;
-import js.html.InputElement;
-import js.html.Element;
import client.Main.ge;
-import js.Browser.window;
+import haxe.Timer;
import js.Browser.document;
+import js.Browser.window;
+import js.html.Element;
+import js.html.ImageElement;
+import js.html.InputElement;
+import js.html.KeyboardEvent;
+
using StringTools;
class Buttons {
-
static inline var CHAT_MIN_SIZE = 200;
static var split:Split;
static var settings:ClientSettings;
@@ -59,8 +59,9 @@ class Buttons {
if (!main.isAdmin()) return;
var el:Element = cast e.target;
if (userList == el) return;
- if (!el.classList.contains("userlist_item"))
+ if (!el.classList.contains("userlist_item")) {
el = el.parentElement;
+ }
var name = "";
if (el.children.length == 1) {
name = el.lastElementChild.innerText;
@@ -126,7 +127,7 @@ class Buttons {
final icon = getPlaylist.firstElementChild;
icon.setAttribute("name", "checkmark");
Timer.delay(() -> {
- icon.setAttribute("name", "link");
+ icon.setAttribute("name", "link");
}, 2000);
}
final clearPlaylist = ge("#clearplaylist");
@@ -154,7 +155,8 @@ class Buttons {
final mediaUrl:InputElement = cast ge("#mediaurl");
mediaUrl.oninput = () -> {
final value = mediaUrl.value;
- final isRawSingleVideo = value != "" && main.isRawPlayerLink(value) && main.isSingleVideoLink(value);
+ final isRawSingleVideo = value != "" && main.isRawPlayerLink(value)
+ && main.isSingleVideoLink(value);
ge("#mediatitleblock").style.display = isRawSingleVideo ? "" : "none";
if (JsApi.hasSubtitleSupport()) {
ge("#subsurlblock").style.display = isRawSingleVideo ? "" : "none";
@@ -228,7 +230,7 @@ class Buttons {
document.body.style.gridTemplateColumns = sizes.join(" ");
}
- static function saveSplitSize():Void {
+ static function saveSplitSize():Void {
final sizes = document.body.style.gridTemplateColumns.split(" ");
if (settings.isSwapped) sizes.reverse();
settings.chatSize = Std.parseFloat(sizes[sizes.length - 1]);
@@ -277,11 +279,16 @@ class Buttons {
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: main.toggleLeader();
+ case R:
+ ge("#mediarefresh").onclick();
+ case S:
+ ge("#voteskip").onclick();
+ case C:
+ ge("#getplaylist").onclick();
+ case F:
+ ge("#fullscreenbtn").onclick();
+ case L:
+ main.toggleLeader();
case P:
if (!main.isLeader()) {
JsApi.once(SetLeader, event -> {
@@ -290,7 +297,8 @@ class Buttons {
});
}
main.toggleLeader();
- default: return;
+ default:
+ return;
}
e.preventDefault();
}
@@ -346,5 +354,4 @@ class Buttons {
} else el.classList.remove("mobile-view");
}
}
-
}
diff --git a/src/client/IPlayer.hx b/src/client/IPlayer.hx
index 7f626b1..903902e 100644
--- a/src/client/IPlayer.hx
+++ b/src/client/IPlayer.hx
@@ -1,12 +1,12 @@
package client;
-import Types.VideoDataRequest;
import Types.VideoData;
+import Types.VideoDataRequest;
import Types.VideoItem;
interface IPlayer {
function isSupportedLink(url:String):Bool;
- function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void;
+ function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void;
function loadVideo(item:VideoItem):Void;
function removeVideo():Void;
function isVideoLoaded():Bool;
diff --git a/src/client/InputWithHistory.hx b/src/client/InputWithHistory.hx
index c4e8bf4..e7dfe83 100644
--- a/src/client/InputWithHistory.hx
+++ b/src/client/InputWithHistory.hx
@@ -1,19 +1,20 @@
package client;
-import js.html.KeyboardEvent;
import js.html.InputElement;
+import js.html.KeyboardEvent;
class InputWithHistory {
-
final element:InputElement;
final maxItems:Int;
final history:Array<String>;
- final onEnter:(value:String)->Bool;
+ final onEnter:(value:String) -> Bool;
var historyId = -1;
public function new(
- element:InputElement, ?history:Array<String>, maxItems:Int,
- onEnter:(value:String)->Bool
+ element:InputElement,
+ ?history:Array<String>,
+ maxItems:Int,
+ onEnter:(value:String) -> Bool
) {
this.element = element;
if (history != null) this.history = history;
@@ -65,5 +66,4 @@ class InputWithHistory {
function onInput():Void {
if (element.oninput != null) element.oninput();
}
-
}
diff --git a/src/client/JsApi.hx b/src/client/JsApi.hx
index a236570..4d98478 100644
--- a/src/client/JsApi.hx
+++ b/src/client/JsApi.hx
@@ -1,18 +1,18 @@
package client;
-import Types.WsEventType;
-import Types.WsEvent;
import Types.VideoItem;
+import Types.WsEvent;
+import Types.WsEventType;
import js.Browser.document;
import js.Browser.window;
import js.Syntax;
+
using StringTools;
-private typedef VideoChangeFunc = (item:VideoItem)->Void;
-private typedef OnceEventFunc = (event:WsEvent)->Void;
+private typedef VideoChangeFunc = (item:VideoItem) -> Void;
+private typedef OnceEventFunc = (event:WsEvent) -> Void;
class JsApi {
-
static var main:Main;
static var player:Player;
static final subtitleFormats = [];
@@ -32,7 +32,7 @@ class JsApi {
}
@:expose
- static function addPlugin(id:String, ?onLoaded:()->Void):Void {
+ static function addPlugin(id:String, ?onLoaded:() -> Void):Void {
addScriptToHead('/plugins/$id/index.js', () -> {
final obj = {
api: Syntax.plainCode("client.JsApi"),
@@ -49,7 +49,7 @@ class JsApi {
}
@:expose
- public static function addScriptToHead(url:String, ?onLoaded:()->Void):Void {
+ public static function addScriptToHead(url:String, ?onLoaded:() -> Void):Void {
final script = document.createScriptElement();
script.type = "text/javascript";
script.onload = onLoaded;
@@ -176,7 +176,9 @@ class JsApi {
}
public static function fireVideoChangeEvents(item:VideoItem):Void {
- for (func in videoChange) func(item);
+ for (func in videoChange) {
+ func(item);
+ }
}
@:expose
@@ -190,7 +192,8 @@ class JsApi {
}
public static function fireVideoRemoveEvents(item:VideoItem):Void {
- for (func in videoRemove) func(item);
+ for (func in videoRemove) {
+ func(item);
+ }
}
-
}
diff --git a/src/client/Main.hx b/src/client/Main.hx
index 1d9ac34..e9cda39 100644
--- a/src/client/Main.hx
+++ b/src/client/Main.hx
@@ -1,39 +1,41 @@
package client;
-import haxe.crypto.Sha256;
-import haxe.Timer;
-import haxe.Json;
-import js.html.MouseEvent;
-import js.html.KeyboardEvent;
-import js.html.Event;
-import js.html.Element;
-import js.html.VideoElement;
-import js.html.InputElement;
-import js.html.ButtonElement;
-import js.html.WebSocket;
-import js.Browser;
-import js.Browser.document;
-import js.Browser.window;
import Client.ClientData;
-import Types.VideoDataRequest;
-import Types.VideoData;
+import Client.ClientGroup;
import Types.Config;
import Types.Permission;
-import Client.ClientGroup;
+import Types.VideoData;
+import Types.VideoDataRequest;
import Types.WsEvent;
-using StringTools;
+import haxe.Json;
+import haxe.Timer;
+import haxe.crypto.Sha256;
+import js.Browser.document;
+import js.Browser.window;
+import js.Browser;
+import js.html.ButtonElement;
+import js.html.Element;
+import js.html.Event;
+import js.html.InputElement;
+import js.html.KeyboardEvent;
+import js.html.MouseEvent;
+import js.html.VideoElement;
+import js.html.WebSocket;
+
using ClientTools;
+using StringTools;
class Main {
-
static inline var SETTINGS_VERSION = 2;
+
public final settings:ClientSettings;
public var isSyncActive = true;
public var forceSyncNextTick = false;
- final clients:Array<Client> = [];
- var pageTitle = document.title;
public final host:String;
public var globalIp(default, null) = "";
+
+ final clients:Array<Client> = [];
+ var pageTitle = document.title;
var config:Null<Config>;
final filters:Array<{regex:EReg, replace:String}> = [];
var personal = new Client("Unknown", 0);
@@ -43,7 +45,9 @@ class Main {
var onTimeGet:Timer;
var onBlinkTab:Null<Timer>;
- static function main():Void new Main();
+ static function main():Void {
+ new Main();
+ }
function new() {
player = new Player(this);
@@ -162,8 +166,7 @@ class Main {
e.preventDefault();
}
}
- ge("#customembed-content").onkeydown =
- ge("#customembed-title").onkeydown;
+ ge("#customembed-content").onkeydown = ge("#customembed-title").onkeydown;
}
public inline function isUser():Bool {
@@ -242,7 +245,7 @@ class Main {
addVideo(link, atEnd, isTemp, () -> addVideoArray(links, atEnd, isTemp));
}
- public function addVideo(url:String, atEnd:Bool, isTemp:Bool, ?callback:()->Void):Void {
+ public function addVideo(url:String, atEnd:Bool, isTemp:Bool, ?callback:() -> Void):Void {
final protocol = Browser.location.protocol;
if (url.startsWith("/")) {
final host = Browser.location.hostname;
@@ -263,7 +266,8 @@ class Main {
if (data.title == null) data.title = Lang.get("rawVideo");
if (data.url == null) data.url = url;
send({
- type: AddVideo, addVideo: {
+ type: AddVideo,
+ addVideo: {
item: {
url: data.url,
title: data.title,
@@ -274,7 +278,8 @@ class Main {
isIframe: data.isIframe == true
},
atEnd: atEnd
- }});
+ }
+ });
if (callback != null) callback();
});
}
@@ -302,7 +307,8 @@ class Main {
if (data.title == null) data.title = "Custom Media";
if (data.url == null) data.url = iframe;
send({
- type: AddVideo, addVideo: {
+ type: AddVideo,
+ addVideo: {
item: {
url: data.url,
title: data.title,
@@ -312,13 +318,15 @@ class Main {
isIframe: true
},
atEnd: atEnd
- }});
+ }
+ });
});
}
public function removeVideoItem(url:String) {
send({
- type: RemoveVideo, removeVideo: {
+ type: RemoveVideo,
+ removeVideo: {
url: url
}
});
@@ -343,7 +351,8 @@ class Main {
public function getPlaylistLinks():Array<String> {
final items = player.getItems();
return [
- for (item in items) item.url
+ for (item in items)
+ item.url
];
}
@@ -556,7 +565,8 @@ class Main {
public function guestLogin(name:String):Void {
if (name.length == 0) return;
send({
- type: Login, login: {
+ type: Login,
+ login: {
clientName: name
}
});
@@ -576,7 +586,8 @@ class Main {
public function loginRequest(name:String, hash:String):Void {
send({
- type: Login, login: {
+ type: Login,
+ login: {
clientName: name,
passHash: hash
}
@@ -769,7 +780,9 @@ class Main {
userDiv.appendChild(textDiv);
msgBuf.appendChild(userDiv);
if (isInChatEnd) {
- while (msgBuf.children.length > 200) msgBuf.removeChild(msgBuf.firstChild);
+ while (msgBuf.children.length > 200) {
+ msgBuf.removeChild(msgBuf.firstChild);
+ }
msgBuf.scrollTop = msgBuf.scrollHeight;
}
if (name == personal.name) {
@@ -813,9 +826,12 @@ class Main {
if (isAdmin()) send({type: ClearChat});
}
if (matchNumbers.match(text)) {
- send({type: Rewind, rewind: {
- time: Std.parseInt(text)
- }});
+ send({
+ type: Rewind,
+ rewind: {
+ time: Std.parseInt(text)
+ }
+ });
}
}
@@ -824,9 +840,11 @@ class Main {
if (onBlinkTab != null) onBlinkTab.stop();
onBlinkTab = new Timer(1000);
onBlinkTab.run = () -> {
- if (document.title.startsWith(pageTitle))
+ if (document.title.startsWith(pageTitle)) {
document.title = title;
- else document.title = getPageTitle();
+ } else {
+ document.title = getPageTitle();
+ }
}
onBlinkTab.run();
}
@@ -912,5 +930,4 @@ class Main {
public static inline function ge(id:String):Element {
return document.querySelector(id);
}
-
}
diff --git a/src/client/Player.hx b/src/client/Player.hx
index c9b379c..ac5c986 100644
--- a/src/client/Player.hx
+++ b/src/client/Player.hx
@@ -1,18 +1,18 @@
package client;
-import js.html.Element;
+import Types.VideoData;
+import Types.VideoDataRequest;
+import Types.VideoItem;
import client.Main.ge;
+import client.players.Iframe;
import client.players.Raw;
import client.players.Youtube;
-import client.players.Iframe;
-import Types.VideoDataRequest;
-import Types.VideoData;
-import Types.VideoItem;
-using StringTools;
+import js.html.Element;
+
using Lambda;
+using StringTools;
class Player {
-
final main:Main;
final players:Array<IPlayer>;
final iframePlayer:IPlayer;
@@ -44,21 +44,24 @@ class Player {
final i = Utils.getIndex(item.parentElement, item);
if (btn.classList.contains("qbtn-play")) {
main.send({
- type: PlayItem, playItem: {
+ type: PlayItem,
+ playItem: {
pos: i
}
});
}
if (btn.classList.contains("qbtn-next")) {
main.send({
- type: SetNextItem, setNextItem: {
+ type: SetNextItem,
+ setNextItem: {
pos: i
}
});
}
if (btn.classList.contains("qbtn-tmp")) {
main.send({
- type: ToggleItemType, toggleItemType: {
+ type: ToggleItemType,
+ toggleItemType: {
pos: i
}
});
@@ -94,7 +97,7 @@ class Player {
player = newPlayer;
}
- public function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void {
+ public function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
var player = players.find(player -> player.isSupportedLink(data.url));
if (player == null) player = rawPlayer;
player.getVideoData(data, callback);
@@ -104,7 +107,7 @@ class Player {
return !players.exists(player -> player.isSupportedLink(url));
}
- public function getIframeData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void {
+ public function getIframeData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
iframePlayer.getVideoData(data, callback);
}
@@ -167,7 +170,8 @@ class Player {
public function onPlay():Void {
if (!main.isLeader()) return;
main.send({
- type: Play, play: {
+ type: Play,
+ play: {
time: getTime()
}
});
@@ -184,7 +188,8 @@ class Player {
final name = event.setLeader.clientName;
if (name != main.getName()) return;
main.send({
- type: Pause, pause: {
+ type: Pause,
+ pause: {
time: getTime()
}
});
@@ -195,7 +200,8 @@ class Player {
}
if (!main.isLeader()) return;
main.send({
- type: Pause, pause: {
+ type: Pause,
+ pause: {
time: getTime()
}
});
@@ -208,7 +214,8 @@ class Player {
}
if (!main.isLeader()) return;
main.send({
- type: SetTime, setTime: {
+ type: SetTime,
+ setTime: {
time: getTime()
}
});
@@ -221,7 +228,8 @@ class Player {
}
if (!main.isLeader()) return;
main.send({
- type: SetRate, setRate: {
+ type: SetRate,
+ setRate: {
rate: getPlaybackRate()
}
});
@@ -307,7 +315,9 @@ class Player {
clearItems();
if (pos != null) itemPos = pos;
if (list.length == 0) return;
- for (video in list) addVideoItem(video, true);
+ for (video in list) {
+ addVideoItem(video, true);
+ }
if (currentUrl != items[itemPos].url) setVideo(itemPos);
else videoItemsEl.children[itemPos].classList.add("queue_active");
}
@@ -417,5 +427,4 @@ class Player {
skipSetRate = isLocal;
player.setPlaybackRate(rate);
}
-
}
diff --git a/src/client/Settings.hx b/src/client/Settings.hx
index 47d67fc..2090829 100644
--- a/src/client/Settings.hx
+++ b/src/client/Settings.hx
@@ -1,14 +1,13 @@
package client;
import haxe.Json;
-import js.html.Storage;
import js.Browser;
+import js.html.Storage;
private typedef Vers = {version:Int};
-private typedef Updater = (data:Any, version:Int)->Any;
+private typedef Updater = (data:Any, version:Int) -> Any;
class Settings {
-
static var defaults:Null<Vers>;
static var updater:Null<Updater>;
static var storage:Storage;
@@ -61,5 +60,4 @@ class Settings {
if (defaults == null) throw "reset: default data is null";
write(defaults);
}
-
}
diff --git a/src/client/Utils.hx b/src/client/Utils.hx
index 00a26fe..de6b16c 100644
--- a/src/client/Utils.hx
+++ b/src/client/Utils.hx
@@ -1,11 +1,10 @@
package client;
-import js.html.Element;
import js.Browser.document;
import js.Browser.window;
+import js.html.Element;
class Utils {
-
public static function isTouch():Bool {
return js.Syntax.code("'ontouchstart' in window");
}
@@ -37,11 +36,8 @@ class Utils {
public static function hasFullscreen():Bool {
final doc:Dynamic = document;
- return (
- document.fullscreenElement != null
- || doc.mozFullScreenElement != null
- || doc.webkitFullscreenElement != null
- );
+ return (document.fullscreenElement != null || doc.mozFullScreenElement != null
+ || doc.webkitFullscreenElement != null);
}
public static function requestFullscreen(el:Element):Bool {
@@ -91,5 +87,4 @@ class Utils {
document.body.removeChild(textarea);
}
}
-
}
diff --git a/src/client/players/Iframe.hx b/src/client/players/Iframe.hx
index ae37c94..e07f814 100644
--- a/src/client/players/Iframe.hx
+++ b/src/client/players/Iframe.hx
@@ -1,14 +1,13 @@
package client.players;
-import js.html.Element;
-import js.Browser.document;
-import client.Main.ge;
-import Types.VideoDataRequest;
import Types.VideoData;
+import Types.VideoDataRequest;
import Types.VideoItem;
+import client.Main.ge;
+import js.Browser.document;
+import js.html.Element;
class Iframe implements IPlayer {
-
final main:Main;
final player:Player;
final playerEl:Element = ge("#ytapiplayer");
@@ -23,7 +22,7 @@ class Iframe implements IPlayer {
return true;
}
- public function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void {
+ public function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
final iframe = document.createDivElement();
iframe.innerHTML = data.url;
if (isValidIframe(iframe)) {
@@ -35,8 +34,7 @@ class Iframe implements IPlayer {
function isValidIframe(iframe:Element):Bool {
if (iframe.children.length != 1) return false;
- return (iframe.firstChild.nodeName == "IFRAME"
- || iframe.firstChild.nodeName == "OBJECT");
+ return (iframe.firstChild.nodeName == "IFRAME" || iframe.firstChild.nodeName == "OBJECT");
}
public function loadVideo(item:VideoItem):Void {
@@ -79,5 +77,4 @@ class Iframe implements IPlayer {
}
public function setPlaybackRate(rate:Float):Void {}
-
}
diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx
index cafe147..ea51e97 100644
--- a/src/client/players/Raw.hx
+++ b/src/client/players/Raw.hx
@@ -1,19 +1,19 @@
package client.players;
-import js.hlsjs.Hls;
+import Types.VideoData;
+import Types.VideoDataRequest;
+import Types.VideoItem;
+import client.Main.ge;
import haxe.Timer;
+import js.Browser.document;
+import js.hlsjs.Hls;
import js.html.Element;
import js.html.InputElement;
import js.html.VideoElement;
-import js.Browser.document;
-import client.Main.ge;
-import Types.VideoDataRequest;
-import Types.VideoData;
-import Types.VideoItem;
+
using StringTools;
class Raw implements IPlayer {
-
final main:Main;
final player:Player;
final playerEl:Element = ge("#ytapiplayer");
@@ -34,7 +34,7 @@ class Raw implements IPlayer {
return true;
}
- public function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void {
+ public function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
final url = data.url;
final decodedUrl = url.urlDecode();
@@ -77,7 +77,7 @@ class Raw implements IPlayer {
if (isHls) initHlsSource(video, url);
}
- function loadHlsPlugin(callback:()->Void):Void {
+ function loadHlsPlugin(callback:() -> Void):Void {
final url = "https://cdn.jsdelivr.net/npm/hls.js@latest";
JsApi.addScriptToHead(url, () -> {
isHlsLoaded = true;
@@ -177,5 +177,4 @@ class Raw implements IPlayer {
public function setPlaybackRate(rate:Float):Void {
video.playbackRate = rate;
}
-
}
diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx
index e63a095..d4db8ed 100644
--- a/src/client/players/Youtube.hx
+++ b/src/client/players/Youtube.hx
@@ -1,19 +1,19 @@
package client.players;
-import haxe.Json;
+import Types.VideoData;
+import Types.VideoDataRequest;
+import Types.VideoItem;
+import client.Main.ge;
import haxe.Http;
-import js.html.Element;
+import haxe.Json;
import js.Browser.document;
-import client.Main.ge;
+import js.html.Element;
import js.youtube.Youtube as YtInit;
import js.youtube.YoutubePlayer;
-import Types.VideoDataRequest;
-import Types.VideoData;
-import Types.VideoItem;
+
using StringTools;
class Youtube implements IPlayer {
-
final matchId = ~/youtube\.com.*v=([A-z0-9_-]+)/;
final matchShort = ~/youtu\.be\/([A-z0-9_-]+)/;
final matchEmbed = ~/youtube\.com\/embed\/([A-z0-9_-]+)/;
@@ -73,7 +73,7 @@ class Youtube implements IPlayer {
return total;
}
- public function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void {
+ public function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
final url = data.url;
if (apiKey == null) apiKey = main.getYoutubeApiKey();
final id = extractVideoId(url);
@@ -122,7 +122,7 @@ class Youtube implements IPlayer {
http.request();
}
- function getPlaylistVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void {
+ function getPlaylistVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
final url = data.url;
final id = extractPlaylistId(url);
var maxResults = main.getYoutubePlaylistLimit();
@@ -174,7 +174,7 @@ class Youtube implements IPlayer {
main.serverMessage(4, 'Error $code: $msg', false);
}
- function getRemoteDataFallback(url:String, callback:(data:VideoData)->Void):Void {
+ function getRemoteDataFallback(url:String, callback:(data:VideoData) -> Void):Void {
if (!YtInit.isLoadedAPI) {
YtInit.init(() -> getRemoteDataFallback(url, callback));
return;
@@ -292,5 +292,4 @@ class Youtube implements IPlayer {
public function setPlaybackRate(rate:Float):Void {
youtube.setPlaybackRate(rate);
}
-
}
diff --git a/src/server/ConsoleInput.hx b/src/server/ConsoleInput.hx
index 3c287af..9b8faf3 100644
--- a/src/server/ConsoleInput.hx
+++ b/src/server/ConsoleInput.hx
@@ -1,13 +1,14 @@
package server;
+import haxe.Json;
import haxe.extern.EitherType as Or;
import haxe.io.Path;
-import haxe.Json;
-import sys.FileSystem;
-import sys.io.File;
+import js.Node.process;
import js.html.Console;
import js.node.Readline;
-import js.Node.process;
+import sys.FileSystem;
+import sys.io.File;
+
using StringTools;
private typedef CommandData = {
@@ -23,7 +24,6 @@ private enum abstract Command(String) from String {
}
class ConsoleInput {
-
final main:Main;
final commands:Map<Command, CommandData> = [
AddAdmin => {
@@ -118,7 +118,9 @@ class ConsoleInput {
Utils.ensureDir(main.logsDir);
final names = FileSystem.readDirectory(main.logsDir)
.filter(s -> s.endsWith(".json"));
- for (name in names) trace(Path.withoutExtension(name));
+ for (name in names) {
+ trace(Path.withoutExtension(name));
+ }
case Exit:
main.exit();
@@ -150,5 +152,4 @@ class ConsoleInput {
final desc = list.join("\n");
trace('Unknown command "$line". List:\n$desc');
}
-
}
diff --git a/src/server/HttpServer.hx b/src/server/HttpServer.hx
index 46540a3..64962dc 100644
--- a/src/server/HttpServer.hx
+++ b/src/server/HttpServer.hx
@@ -1,20 +1,20 @@
package server;
-import sys.FileSystem;
-import js.node.Buffer;
import haxe.io.Path;
+import js.node.Buffer;
import js.node.Fs;
-import js.node.Https;
import js.node.Http;
-import js.node.url.URL;
+import js.node.Https;
+import js.node.Path as JsPath;
+import js.node.http.ClientRequest;
import js.node.http.IncomingMessage;
import js.node.http.ServerResponse;
-import js.node.http.ClientRequest;
-import js.node.Path as JsPath;
+import js.node.url.URL;
+import sys.FileSystem;
+
using StringTools;
class HttpServer {
-
static final mimeTypes = [
"html" => "text/html",
"js" => "text/javascript",
@@ -58,7 +58,8 @@ class HttpServer {
res.setHeader("Accept-Ranges", "bytes");
res.setHeader("Content-Type", getMimeType(ext));
- if (allowLocalRequests && req.connection.remoteAddress == req.connection.localAddress
+ if (allowLocalRequests
+ && req.connection.remoteAddress == req.connection.localAddress
|| allowedLocalFiles[url]) {
if (isMediaExtension(ext)) {
allowedLocalFiles[url] = true;
@@ -176,7 +177,7 @@ class HttpServer {
static function proxyRequest(
url:String, req:IncomingMessage, res:ServerResponse,
- fn:(req:IncomingMessage)->Bool
+ fn:(req:IncomingMessage) -> Bool
):Null<ClientRequest> {
final url = try {
new URL(js.Node.global.decodeURI(url));
@@ -211,5 +212,4 @@ class HttpServer {
if (contentType == null) return "application/octet-stream";
return contentType;
}
-
}
diff --git a/src/server/Logger.hx b/src/server/Logger.hx
index 9ff4c34..cd96d1b 100644
--- a/src/server/Logger.hx
+++ b/src/server/Logger.hx
@@ -1,14 +1,14 @@
package server;
-import haxe.io.Path;
-import sys.io.File;
import haxe.Json;
+import haxe.io.Path;
import sys.FileSystem;
-using StringTools;
+import sys.io.File;
+
using Lambda;
+using StringTools;
class Logger {
-
final folder:String;
final maxCount:Int;
final verbose:Bool;
@@ -65,5 +65,4 @@ class Logger {
final s = '${d[0]}-${d[1]}-${d[2]} ${t[0]}:${t[1]}:${t[2]}';
return Date.fromString(s);
}
-
}
diff --git a/src/server/Main.hx b/src/server/Main.hx
index d93c2e5..ea1e40b 100644
--- a/src/server/Main.hx
+++ b/src/server/Main.hx
@@ -1,41 +1,44 @@
package server;
-import haxe.crypto.Sha256;
-import sys.FileSystem;
-import sys.io.File;
-import haxe.Timer;
-import haxe.Json;
-import js.Node.process;
-import js.Node.__dirname;
-import js.npm.ws.Server as WSServer;
-import js.npm.ws.WebSocket;
-import js.node.http.IncomingMessage;
-import js.node.Http;
-import json2object.JsonParser;
-import json2object.ErrorUtils;
import Client.ClientData;
import Types.Config;
+import Types.Message;
import Types.Permission;
import Types.UserList;
-import Types.Message;
import Types.WsEvent;
-using StringTools;
+import haxe.Json;
+import haxe.Timer;
+import haxe.crypto.Sha256;
+import js.Node.__dirname;
+import js.Node.process;
+import js.node.Http;
+import js.node.http.IncomingMessage;
+import js.npm.ws.Server as WSServer;
+import js.npm.ws.WebSocket;
+import json2object.ErrorUtils;
+import json2object.JsonParser;
+import sys.FileSystem;
+import sys.io.File;
+
using ClientTools;
using Lambda;
+using StringTools;
class Main {
-
static inline var VIDEO_START_MAX_DELAY = 3000;
static inline var VIDEO_SKIP_DELAY = 1000;
+
final rootDir = '$__dirname/..';
+
public final logsDir:String;
+ public final config:Config;
+
final verbose:Bool;
final statePath:String;
var wss:WSServer;
final localIp:String;
var globalIp:String;
var port:Int;
- public final config:Config;
final userList:UserList;
final clients:Array<Client> = [];
final freeIds:Array<Int> = [];
@@ -48,7 +51,9 @@ class Main {
var isPlaylistOpen = true;
var itemPos = 0;
- static function main():Void new Main();
+ static function main():Void {
+ new Main();
+ }
function new() {
verbose = Sys.args().has("--verbose");
@@ -87,8 +92,8 @@ class Main {
var attempts = 5;
function preparePort():Void {
- Utils.isPortFree(port, free -> {
- if (!free && attempts > 0) {
+ Utils.isPortFree(port, isFree -> {
+ if (!isFree && attempts > 0) {
trace('Warning: port $port is already in use. Changed to ${port + 1}');
attempts--;
port++;
@@ -138,8 +143,9 @@ class Main {
}
function generateConfigSalt():String {
- if (userList.salt == null)
+ if (userList.salt == null) {
userList.salt = Sha256.encode('${Math.random()}');
+ }
return userList.salt;
}
@@ -155,7 +161,9 @@ class Main {
if (type == field) continue;
if (group.indexOf(type) == -1) continue;
group.remove(type);
- for (item in getPermissions(type)) group.push(item);
+ for (item in getPermissions(type)) {
+ group.push(item);
+ }
}
}
return config;
@@ -167,7 +175,9 @@ class Main {
if (!FileSystem.exists(customPath)) return config;
final customConfig:Config = Json.parse(File.getContent(customPath));
for (field in Reflect.fields(customConfig)) {
- if (Reflect.field(config, field) == null) trace('Warning: config field "$field" is unknown');
+ if (Reflect.field(config, field) == null) {
+ trace('Warning: config field "$field" is unknown');
+ }
Reflect.setField(config, field, Reflect.field(customConfig, field));
}
final emoteCopies:Map<String, Bool> = [];
@@ -175,7 +185,9 @@ class Main {
if (emoteCopies[emote.name]) trace('Warning: emote name "${emote.name}" has copy');
emoteCopies[emote.name] = true;
if (!verbose) continue;
- if (emoteCopies[emote.image]) trace('Warning: emote url of name "${emote.name}" has copy');
+ if (emoteCopies[emote.image]) {
+ trace('Warning: emote url of name "${emote.name}" has copy');
+ }
emoteCopies[emote.image] = true;
}
return config;
@@ -218,10 +230,14 @@ class Main {
final data:ServerState = Json.parse(File.getContent(statePath));
videoList.resize(0);
messages.resize(0);
- for (item in data.videoList) videoList.push(item);
+ for (item in data.videoList) {
+ videoList.push(item);
+ }
isPlaylistOpen = data.isPlaylistOpen;
itemPos = data.itemPos;
- for (message in data.messages) messages.push(message);
+ for (message in data.messages) {
+ messages.push(message);
+ }
videoTimer.start();
videoTimer.setTime(data.timer.time);
videoTimer.pause();
@@ -346,8 +362,9 @@ class Main {
switch (data.type) {
case Connected:
if (!internal) return;
- if (clients.length == 1 && videoList.length > 0)
+ if (clients.length == 1 && videoList.length > 0) {
if (videoTimer.isPaused()) videoTimer.play();
+ }
send(client, {
type: Connected,
@@ -381,7 +398,8 @@ class Main {
Timer.delay(() -> {
if (clients.exists(i -> i.name == client.name)) return;
broadcast({
- type: ServerMessage, serverMessage: {
+ type: ServerMessage,
+ serverMessage: {
textId: '${client.name} has left'
}
});
@@ -405,8 +423,9 @@ class Main {
}
} else {
if (userList.admins.exists(
- a -> a.name.toLowerCase() == lcName && a.hash == hash
- )) client.isAdmin = true;
+ a -> a.name.toLowerCase() == lcName && a.hash == hash)) {
+ client.isAdmin = true;
+ }
else {
serverMessage(client, "passwordMatchError");
send(client, {type: LoginError});
@@ -462,8 +481,7 @@ class Main {
if (!isPlaylistOpen) {
if (!checkPermission(client, LockPlaylistPerm)) return;
}
- if (config.totalVideoLimit != 0
- && videoList.length >= config.totalVideoLimit) {
+ if (config.totalVideoLimit != 0 && videoList.length >= config.totalVideoLimit) {
serverMessage(client, "totalVideoLimitError");
return;
}
@@ -540,7 +558,8 @@ class Main {
if (videoList.length != currentLength) return;
if (itemPos != currentPos) return;
skipVideo({
- type: SkipVideo, skipVideo: {
+ type: SkipVideo,
+ skipVideo: {
url: videoList[itemPos].url
}
});
@@ -548,7 +567,8 @@ class Main {
return;
}
final obj:WsEvent = {
- type: GetTime, getTime: {
+ type: GetTime,
+ getTime: {
time: videoTimer.getTime()
}
};
@@ -588,7 +608,8 @@ class Main {
}
clients.setLeader(clientName);
broadcast({
- type: SetLeader, setLeader: {
+ type: SetLeader,
+ setLeader: {
clientName: clientName
}
});
@@ -597,7 +618,8 @@ class Main {
if (videoTimer.isPaused()) videoTimer.play();
videoTimer.setRate(1);
broadcast({
- type: Play, play: {
+ type: Play,
+ play: {
time: videoTimer.getTime()
}
});
@@ -643,15 +665,17 @@ class Main {
broadcast({
type: UpdatePlaylist,
updatePlaylist: {
- videoList: videoList
- }});
+ videoList: videoList
+ }
+ });
case UpdatePlaylist:
broadcast({
type: UpdatePlaylist,
updatePlaylist: {
- videoList: videoList
- }});
+ videoList: videoList
+ }
+ });
case TogglePlaylistLock:
if (!checkPermission(client, LockPlaylistPerm)) return;
@@ -691,7 +715,8 @@ class Main {
function serverMessage(client:Client, textId:String):Void {
send(client, {
- type: ServerMessage, serverMessage: {
+ type: ServerMessage,
+ serverMessage: {
textId: textId
}
});
@@ -703,7 +728,8 @@ class Main {
function broadcast(data:WsEvent):Void {
final json = Json.stringify(data);
- for (client in clients) client.ws.send(json, null);
+ for (client in clients)
+ client.ws.send(json, null);
}
function broadcastExcept(skipped:Client, data:WsEvent):Void {
@@ -726,7 +752,8 @@ class Main {
function checkPermission(client:Client, perm:Permission):Bool {
final state = client.hasPermission(perm, config.permissions);
if (!state) send(client, {
- type: ServerMessage, serverMessage: {
+ type: ServerMessage,
+ serverMessage: {
textId: "accessError"
}
});
@@ -767,5 +794,4 @@ class Main {
broadcast({type: VideoLoaded});
videoTimer.start();
}
-
}
diff --git a/src/server/ServerState.hx b/src/server/ServerState.hx
index 9c8d751..4ccdd44 100644
--- a/src/server/ServerState.hx
+++ b/src/server/ServerState.hx
@@ -9,7 +9,6 @@ typedef ServerState = {
itemPos:Int,
messages:Array<Message>,
timer:{
- time:Float,
- paused:Bool
+ time:Float, paused:Bool
}
}
diff --git a/src/server/Utils.hx b/src/server/Utils.hx
index bab6300..9aa0d66 100644
--- a/src/server/Utils.hx
+++ b/src/server/Utils.hx
@@ -1,18 +1,17 @@
package server;
-import js.node.url.URL;
-import js.node.Https;
import js.node.Http;
+import js.node.Https;
import js.node.Os;
+import js.node.url.URL;
import sys.FileSystem;
class Utils {
-
public static function ensureDir(path:String):Void {
if (!FileSystem.exists(path)) FileSystem.createDirectory(path);
}
- public static function isPortFree(port:Int, callback:(free:Bool)->Void):Void {
+ public static function isPortFree(port:Int, callback:(isFree:Bool) -> Void):Void {
final server = Http.createServer();
final timeout = 1000;
var status = false;
@@ -22,7 +21,7 @@ class Utils {
status = false;
server.close();
});
- server.once("timeout", function () {
+ server.once("timeout", function() {
status = false;
trace('Timeout (${timeout}ms) occurred waiting for port $port to be available');
server.close();
@@ -35,7 +34,7 @@ class Utils {
server.listen(port);
}
- public static function getGlobalIp(callback:(ip:String)->Void):Void {
+ public static function getGlobalIp(callback:(ip:String) -> Void):Void {
function onError(e):Void {
trace("Warning: connection error, server is local.");
callback("127.0.0.1");
@@ -51,8 +50,7 @@ class Utils {
final data = new StringBuf();
r.on("data", chunk -> data.add(chunk));
r.on("end", _ -> callback(data.toString()));
- }).on("error", onError)
- .on("timeout", onError);
+ }).on("error", onError).on("timeout", onError);
}
public static function getLocalIp():String {
@@ -89,5 +87,4 @@ class Utils {
arr[n] = a;
}
}
-
}
diff --git a/src/server/VideoTimer.hx b/src/server/VideoTimer.hx
index 53d4e28..2dd6720 100644
--- a/src/server/VideoTimer.hx
+++ b/src/server/VideoTimer.hx
@@ -3,8 +3,8 @@ package server;
import haxe.Timer.stamp;
class VideoTimer {
-
public var isStarted(default, null) = false;
+
var startTime = 0.0;
var pauseStartTime = 0.0;
var rateStartTime = 0.0;
@@ -75,5 +75,4 @@ class VideoTimer {
if (rateStartTime == 0) return 0;
return stamp() - rateStartTime - pauseTime();
}
-
}
diff --git a/test/Main.hx b/test/Main.hx
index d2ea286..f212eba 100644
--- a/test/Main.hx
+++ b/test/Main.hx
@@ -4,12 +4,10 @@ import utest.Runner;
import utest.ui.Report;
class Main {
-
static function main() {
final runner = new Runner();
runner.addCases(test.tests);
Report.create(runner);
runner.run();
}
-
}
diff --git a/test/tests/TestTimer.hx b/test/tests/TestTimer.hx
index cbc71d2..337da3e 100644
--- a/test/tests/TestTimer.hx
+++ b/test/tests/TestTimer.hx
@@ -1,14 +1,13 @@
package test.tests;
import haxe.PosInfos;
-import utest.Assert;
-import utest.Test;
-import utest.Async;
import haxe.Timer;
import server.VideoTimer;
+import utest.Assert;
+import utest.Async;
+import utest.Test;
class TestTimer extends Test {
-
@:timeout(500)
function testMain(async:Async) {
final timer = new VideoTimer();
@@ -168,5 +167,4 @@ class TestTimer extends Test {
function almostEq(a:Float, b:Float, ?p:PosInfos):Void {
Assert.equals(Math.round(a * 10) / 10, Math.round(b * 10) / 10, p);
}
-
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage