aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build/server.js287
-rw-r--r--res/client.js229
-rw-r--r--src/VideoList.hx119
-rw-r--r--src/client/JsApi.hx2
-rw-r--r--src/client/Player.hx107
-rw-r--r--src/client/players/Raw.hx1
-rw-r--r--src/server/Main.hx62
7 files changed, 457 insertions, 350 deletions
diff --git a/build/server.js b/build/server.js
index ef9654b..8000342 100644
--- a/build/server.js
+++ b/build/server.js
@@ -2296,69 +2296,103 @@ StringTools.hex = function(n,digits) {
}
return s;
};
-var VideoList = {};
-VideoList._new = function() {
- return [];
+var VideoList = function() {
+ this.items = [];
+ this.isOpen = true;
+ this.pos = 0;
};
-VideoList.findIndex = function(this1,f) {
- var i = 0;
- var _g = 0;
- while(_g < this1.length) {
- if(f(this1[_g++])) {
- return i;
+VideoList.__name__ = true;
+VideoList.prototype = {
+ setItems: function(items) {
+ this.items.length = 0;
+ this.pos = 0;
+ var _g = 0;
+ while(_g < items.length) this.items.push(items[_g++]);
+ }
+ ,setPos: function(i) {
+ if(i < 0 || i > this.items.length - 1) {
+ i = 0;
}
- ++i;
+ this.pos = i;
}
- return -1;
-};
-VideoList.addItem = function(this1,item,atEnd,itemPos) {
- if(atEnd) {
- this1.push(item);
- } else {
- this1.splice(itemPos + 1,0,item);
+ ,exists: function(f) {
+ return Lambda.exists(this.items,f);
}
-};
-VideoList.setNextItem = function(this1,pos,itemPos) {
- var next = this1[pos];
- HxOverrides.remove(this1,next);
- if(pos < itemPos) {
- --itemPos;
+ ,findIndex: function(f) {
+ var i = 0;
+ var _g = 0;
+ var _g1 = this.items;
+ while(_g < _g1.length) {
+ if(f(_g1[_g++])) {
+ return i;
+ }
+ ++i;
+ }
+ return -1;
}
- this1.splice(itemPos + 1,0,next);
- return itemPos;
-};
-VideoList.toggleItemType = function(this1,pos) {
- this1[pos].isTemp = !this1[pos].isTemp;
-};
-VideoList.removeItem = function(this1,index,itemPos) {
- if(index < itemPos) {
- --itemPos;
+ ,addItem: function(item,atEnd) {
+ if(atEnd) {
+ this.items.push(item);
+ } else {
+ this.items.splice(this.pos + 1,0,item);
+ }
}
- HxOverrides.remove(this1,this1[index]);
- if(itemPos >= this1.length) {
- itemPos = 0;
+ ,setNextItem: function(nextPos) {
+ var next = this.items[nextPos];
+ HxOverrides.remove(this.items,next);
+ if(nextPos < this.pos) {
+ this.pos--;
+ }
+ this.items.splice(this.pos + 1,0,next);
}
- return itemPos;
-};
-VideoList.skipItem = function(this1,itemPos) {
- var item = this1[itemPos];
- if(!item.isTemp) {
- ++itemPos;
- } else {
- HxOverrides.remove(this1,item);
+ ,toggleItemType: function(pos) {
+ this.items[pos].isTemp = !this.items[pos].isTemp;
}
- if(itemPos >= this1.length) {
- itemPos = 0;
+ ,removeItem: function(index) {
+ if(index < this.pos) {
+ this.pos--;
+ }
+ HxOverrides.remove(this.items,this.items[index]);
+ if(this.pos >= this.items.length) {
+ this.pos = 0;
+ }
}
- return itemPos;
-};
-VideoList.itemsByUser = function(this1,client) {
- var i = 0;
- var _g = 0;
- while(_g < this1.length) if(this1[_g++].author == client.name) {
- ++i;
+ ,skipItem: function() {
+ var item = this.items[this.pos];
+ if(!item.isTemp) {
+ this.pos++;
+ } else {
+ HxOverrides.remove(this.items,item);
+ }
+ if(this.pos >= this.items.length) {
+ this.pos = 0;
+ }
}
- return i;
+ ,itemsByUser: function(client) {
+ var i = 0;
+ var _g = 0;
+ var _g1 = this.items;
+ while(_g < _g1.length) if(_g1[_g++].author == client.name) {
+ ++i;
+ }
+ return i;
+ }
+ ,shuffle: function() {
+ var current = this.items[this.pos];
+ HxOverrides.remove(this.items,current);
+ this.shuffleArray(this.items);
+ this.items.splice(this.pos,0,current);
+ }
+ ,shuffleArray: function(arr) {
+ var _g_current = 0;
+ while(_g_current < arr.length) {
+ var _g1_value = arr[_g_current++];
+ var n = Std.random(arr.length);
+ arr[_g_current - 1] = arr[n];
+ arr[n] = _g1_value;
+ }
+ }
+ ,__class__: VideoList
};
var haxe_Exception = function(message,previous,native) {
Error.call(this,message);
@@ -3908,11 +3942,9 @@ var server_Main = function(opts) {
this.matchGuestName = new EReg("guest [0-9]+","");
this.matchHtmlChars = new EReg("[&^<>'\"]","");
this.isHeroku = false;
- this.itemPos = 0;
- this.isPlaylistOpen = true;
this.messages = [];
this.videoTimer = new server_VideoTimer();
- this.videoList = VideoList._new();
+ this.videoList = new VideoList();
this.wsEventParser = new JsonParser_$1();
this.freeIds = [];
this.clients = [];
@@ -3955,7 +3987,7 @@ var server_Main = function(opts) {
preparePort = function() {
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 : 106, className : "server.Main", methodName : "new"});
+ haxe_Log.trace("Warning: port " + _gthis.port + " is already in use. Changed to " + (_gthis.port + 1),{ fileName : "src/server/Main.hx", lineNumber : 104, className : "server.Main", methodName : "new"});
attempts -= 1;
_gthis.port++;
preparePort();
@@ -3973,11 +4005,11 @@ 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 : 119, className : "server.Main", methodName : "runServer"});
+ haxe_Log.trace("Local: http://" + this.localIp + ":" + this.port,{ fileName : "src/server/Main.hx", lineNumber : 117, className : "server.Main", methodName : "runServer"});
if(!this.isNoState) {
server_Utils.getGlobalIp(function(ip) {
_gthis.globalIp = ip;
- haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 122, className : "server.Main", methodName : "runServer"});
+ haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + _gthis.port,{ fileName : "src/server/Main.hx", lineNumber : 120, className : "server.Main", methodName : "runServer"});
});
}
var dir = "" + this.rootDir + "/res";
@@ -4060,7 +4092,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 : 191, className : "server.Main", methodName : "getUserConfig"});
+ haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 189, className : "server.Main", methodName : "getUserConfig"});
}
config[field] = Reflect.field(customConfig,field);
}
@@ -4071,14 +4103,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 : 197, className : "server.Main", methodName : "getUserConfig"});
+ haxe_Log.trace("Warning: emote name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 195, 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 : 201, className : "server.Main", methodName : "getUserConfig"});
+ haxe_Log.trace("Warning: emote url of name \"" + emote.name + "\" has copy",{ fileName : "src/server/Main.hx", lineNumber : 199, className : "server.Main", methodName : "getUserConfig"});
}
emoteCopies_h[emote.image] = true;
}
@@ -4120,13 +4152,13 @@ server_Main.prototype = {
js_node_Fs.writeFileSync("" + folder + "/users.json",JSON.stringify({ admins : users1, bans : _g, salt : users.salt},null,"\t"));
}
,saveState: function() {
- haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 240, className : "server.Main", methodName : "saveState"});
+ haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 238, className : "server.Main", methodName : "saveState"});
var json = JSON.stringify(this.getCurrentState(),null,"\t");
js_node_Fs.writeFileSync(this.statePath,json);
this.writeUsers(this.userList);
}
,getCurrentState: function() {
- return { videoList : this.videoList, isPlaylistOpen : this.isPlaylistOpen, itemPos : this.itemPos, messages : this.messages, timer : { time : this.videoTimer.getTime(), paused : this.videoTimer.isPaused()}};
+ return { videoList : this.videoList.items, isPlaylistOpen : this.videoList.isOpen, itemPos : this.videoList.pos, messages : this.messages, timer : { time : this.videoTimer.getTime(), paused : this.videoTimer.isPaused()}};
}
,loadState: function() {
if(this.isNoState) {
@@ -4135,15 +4167,12 @@ server_Main.prototype = {
if(!sys_FileSystem.exists(this.statePath)) {
return;
}
- haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 262, className : "server.Main", methodName : "loadState"});
+ haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 260, className : "server.Main", methodName : "loadState"});
var data = JSON.parse(js_node_Fs.readFileSync(this.statePath,{ encoding : "utf8"}));
- this.videoList.length = 0;
+ this.videoList.setItems(data.videoList);
this.messages.length = 0;
- var _g = 0;
- var _g1 = data.videoList;
- while(_g < _g1.length) this.videoList.push(_g1[_g++]);
- this.isPlaylistOpen = data.isPlaylistOpen;
- this.itemPos = data.itemPos;
+ this.videoList.isOpen = data.isPlaylistOpen;
+ this.videoList.setPos(data.itemPos);
var _g = 0;
var _g1 = data.messages;
while(_g < _g1.length) this.messages.push(_g1[_g++]);
@@ -4152,7 +4181,7 @@ server_Main.prototype = {
this.videoTimer.pause();
}
,logError: function(type,data) {
- haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 280, className : "server.Main", methodName : "logError", customParams : [data]});
+ haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 275, 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"));
@@ -4169,7 +4198,7 @@ server_Main.prototype = {
if(_gthis.clients.length == 0) {
return;
}
- haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 297, className : "server.Main", methodName : "initIntergationHandlers"});
+ haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 292, className : "server.Main", methodName : "initIntergationHandlers"});
js_node_Http.get(url,null,function(r) {
});
};
@@ -4189,13 +4218,13 @@ server_Main.prototype = {
password += this.config.salt;
var hash = haxe_crypto_Sha256.encode(password);
this.userList.admins.push({ name : name, hash : hash});
- haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 320, className : "server.Main", methodName : "addAdmin"});
+ haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 315, className : "server.Main", methodName : "addAdmin"});
}
,removeAdmin: function(name) {
HxOverrides.remove(this.userList.admins,Lambda.find(this.userList.admins,function(item) {
return item.name == name;
}));
- haxe_Log.trace("Admin " + name + " removed.",{ fileName : "src/server/Main.hx", lineNumber : 327, className : "server.Main", methodName : "removeAdmin"});
+ haxe_Log.trace("Admin " + name + " removed.",{ fileName : "src/server/Main.hx", lineNumber : 322, className : "server.Main", methodName : "removeAdmin"});
}
,replayLog: function(events) {
var _gthis = this;
@@ -4239,7 +4268,7 @@ server_Main.prototype = {
var ip = this.clientIp(req);
var id = this.freeIds.length > 0 ? this.freeIds.shift() : this.clients.length;
var name = "Guest " + (id + 1);
- haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 365, className : "server.Main", methodName : "onConnect", customParams : ["" + name + " connected (" + ip + ")"]});
+ haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 360, className : "server.Main", methodName : "onConnect", customParams : ["" + name + " connected (" + ip + ")"]});
var client = new Client(ws,req,id,name,0);
client.setGroupFlag(ClientGroup.Admin,this.config.localAdmins && req.socket.localAddress == ip);
this.clients.push(client);
@@ -4251,7 +4280,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 : 381, className : "server.Main", methodName : "onConnect"});
+ haxe_Log.trace(errors,{ fileName : "src/server/Main.hx", lineNumber : 376, className : "server.Main", methodName : "onConnect"});
_gthis.serverMessage(client,errors);
return;
}
@@ -4291,16 +4320,16 @@ server_Main.prototype = {
if(!this.checkPermission(client,"addVideo")) {
return;
}
- if(!this.isPlaylistOpen) {
+ if(!this.videoList.isOpen) {
if(!this.checkPermission(client,"lockPlaylist")) {
return;
}
}
- if(this.config.totalVideoLimit != 0 && this.videoList.length >= this.config.totalVideoLimit) {
+ if(this.config.totalVideoLimit != 0 && this.videoList.items.length >= this.config.totalVideoLimit) {
this.serverMessage(client,"totalVideoLimitError");
return;
}
- if(this.config.userVideoLimit != 0 && VideoList.itemsByUser(this.videoList,client) >= this.config.userVideoLimit) {
+ if(this.config.userVideoLimit != 0 && this.videoList.itemsByUser(client) >= this.config.userVideoLimit) {
this.serverMessage(client,"videoLimitPerUserError");
return;
}
@@ -4313,15 +4342,15 @@ server_Main.prototype = {
if(item.url.indexOf(local) != -1) {
item.url = StringTools.replace(item.url,local,"" + this.globalIp + ":" + this.port);
}
- if(Lambda.exists(this.videoList,function(i) {
+ if(this.videoList.exists(function(i) {
return i.url == item.url;
})) {
this.serverMessage(client,"videoAlreadyExistsError");
return;
}
- VideoList.addItem(this.videoList,item,data.addVideo.atEnd,this.itemPos);
+ this.videoList.addItem(item,data.addVideo.atEnd);
this.broadcast(data);
- if(this.videoList.length == 1) {
+ if(this.videoList.items.length == 1) {
this.restartWaitTimer();
}
break;
@@ -4369,28 +4398,29 @@ server_Main.prototype = {
return;
}
this.videoTimer.stop();
- this.videoList.length = 0;
- this.itemPos = 0;
+ var _this = this.videoList;
+ _this.items.length = 0;
+ _this.pos = 0;
this.broadcast(data);
break;
case "Connected":
if(!internal) {
return;
}
- if(this.clients.length == 1 && this.videoList.length > 0) {
+ if(this.clients.length == 1 && this.videoList.items.length > 0) {
if(this.videoTimer.isPaused()) {
this.videoTimer.play();
}
}
this.checkBan(client);
- this.send(client,{ type : "Connected", connected : { config : this.config, history : this.messages, isUnknownClient : true, clientName : client.name, clients : this.clientList(), videoList : this.videoList, isPlaylistOpen : this.isPlaylistOpen, itemPos : this.itemPos, globalIp : this.globalIp}});
+ this.send(client,{ type : "Connected", connected : { config : this.config, history : this.messages, isUnknownClient : true, clientName : client.name, clients : this.clientList(), videoList : this.videoList.items, isPlaylistOpen : this.videoList.isOpen, itemPos : this.videoList.pos, globalIp : this.globalIp}});
this.sendClientListExcept(client);
break;
case "Disconnected":
if(!internal) {
return;
}
- haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 441, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " disconnected"]});
+ haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 436, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " disconnected"]});
server_Utils.sortedPush(this.freeIds,client.id);
HxOverrides.remove(this.clients,client);
this.sendClientList();
@@ -4435,21 +4465,23 @@ server_Main.prototype = {
if(!this.checkPermission(client,"rewind")) {
return;
}
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
this.loadFlashbackTime();
this.broadcast({ type : "Rewind", rewind : { time : this.videoTimer.getTime()}});
break;
case "GetTime":
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
- var maxTime = this.videoList[this.itemPos].duration - 0.01;
+ var _this = this.videoList;
+ var maxTime = _this.items[_this.pos].duration - 0.01;
if(this.videoTimer.getTime() > maxTime) {
this.videoTimer.pause();
this.videoTimer.setTime(maxTime);
- var skipUrl = this.videoList[this.itemPos].url;
+ var _this = this.videoList;
+ var skipUrl = _this.items[_this.pos].url;
haxe_Timer.delay(function() {
_gthis.skipVideo({ type : "SkipVideo", skipVideo : { url : skipUrl}});
},1000);
@@ -4512,7 +4544,7 @@ server_Main.prototype = {
this.send(client,{ type : "LoginError"});
return;
}
- haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 528, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " logged as " + name]});
+ haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 523, className : "server.Main", methodName : "onMessage", customParams : ["Client " + client.name + " logged as " + name]});
client.name = name;
client.setGroupFlag(ClientGroup.User,true);
this.checkBan(client);
@@ -4525,7 +4557,7 @@ server_Main.prototype = {
var oldName = client.name;
client.name = "Guest " + (this.clients.indexOf(client) + 1);
client.setGroupFlag(ClientGroup.User,false);
- haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 549, className : "server.Main", methodName : "onMessage", customParams : ["Client " + oldName + " logout to " + client.name]});
+ haxe_Log.trace(HxOverrides.dateStr(new Date()),{ fileName : "src/server/Main.hx", lineNumber : 544, className : "server.Main", methodName : "onMessage", customParams : ["Client " + oldName + " logout to " + client.name]});
this.send(client,{ type : data.type, logout : { oldClientName : oldName, clientName : client.name, clients : this.clientList()}});
this.sendClientListExcept(client);
break;
@@ -4552,7 +4584,7 @@ server_Main.prototype = {
case "PasswordRequest":
break;
case "Pause":
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
if((client.group & 4) == 0) {
@@ -4566,7 +4598,7 @@ server_Main.prototype = {
this.broadcast({ type : data.type, pause : data.pause});
break;
case "Play":
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
if((client.group & 4) == 0) {
@@ -4583,7 +4615,8 @@ server_Main.prototype = {
if(!this.checkPermission(client,"changeOrder")) {
return;
}
- this.itemPos = data.playItem.pos;
+ this.videoList.setPos(data.playItem.pos);
+ data.playItem.pos = this.videoList.pos;
this.restartWaitTimer();
this.broadcast(data);
break;
@@ -4591,19 +4624,20 @@ server_Main.prototype = {
if(!this.checkPermission(client,"removeVideo")) {
return;
}
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
var url = data.removeVideo.url;
- var index = VideoList.findIndex(this.videoList,function(item) {
+ var index = this.videoList.findIndex(function(item) {
return item.url == url;
});
if(index == -1) {
return;
}
- var isCurrent = this.videoList[this.itemPos].url == url;
- this.itemPos = VideoList.removeItem(this.videoList,index,this.itemPos);
- if(isCurrent && this.videoList.length > 0) {
+ var _this = this.videoList;
+ var isCurrent = _this.items[_this.pos].url == url;
+ this.videoList.removeItem(index);
+ if(isCurrent && this.videoList.items.length > 0) {
this.broadcast(data);
this.restartWaitTimer();
} else {
@@ -4614,7 +4648,7 @@ server_Main.prototype = {
if(!this.checkPermission(client,"rewind")) {
return;
}
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
data.rewind.time += this.videoTimer.getTime();
@@ -4640,7 +4674,7 @@ server_Main.prototype = {
}
ClientTools.setLeader(this.clients,clientName);
this.broadcast({ type : "SetLeader", setLeader : { clientName : clientName}});
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
if(!ClientTools.hasLeader(this.clients)) {
@@ -4656,14 +4690,14 @@ server_Main.prototype = {
return;
}
var pos = data.setNextItem.pos;
- if(pos == this.itemPos || pos == this.itemPos + 1) {
+ if(pos == this.videoList.pos || pos == this.videoList.pos + 1) {
return;
}
- this.itemPos = VideoList.setNextItem(this.videoList,pos,this.itemPos);
+ this.videoList.setNextItem(pos);
this.broadcast(data);
break;
case "SetRate":
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
if((client.group & 4) == 0) {
@@ -4673,7 +4707,7 @@ server_Main.prototype = {
this.broadcastExcept(client,{ type : data.type, setRate : data.setRate});
break;
case "SetTime":
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
if((client.group & 4) == 0) {
@@ -4689,14 +4723,11 @@ server_Main.prototype = {
if(!this.checkPermission(client,"changeOrder")) {
return;
}
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
- var current = this.videoList[this.itemPos];
- HxOverrides.remove(this.videoList,current);
- server_Utils.shuffle(this.videoList);
- this.videoList.splice(this.itemPos,0,current);
- this.broadcast({ type : "UpdatePlaylist", updatePlaylist : { videoList : this.videoList}});
+ this.videoList.shuffle();
+ this.broadcast({ type : "UpdatePlaylist", updatePlaylist : { videoList : this.videoList.items}});
break;
case "SkipVideo":
if(!this.checkPermission(client,"removeVideo")) {
@@ -4705,21 +4736,21 @@ server_Main.prototype = {
this.skipVideo(data);
break;
case "ToggleItemType":
- VideoList.toggleItemType(this.videoList,data.toggleItemType.pos);
+ this.videoList.toggleItemType(data.toggleItemType.pos);
this.broadcast(data);
break;
case "TogglePlaylistLock":
if(!this.checkPermission(client,"lockPlaylist")) {
return;
}
- this.isPlaylistOpen = !this.isPlaylistOpen;
- this.broadcast({ type : "TogglePlaylistLock", togglePlaylistLock : { isOpen : this.isPlaylistOpen}});
+ this.videoList.isOpen = !this.videoList.isOpen;
+ this.broadcast({ type : "TogglePlaylistLock", togglePlaylistLock : { isOpen : this.videoList.isOpen}});
break;
case "UpdateClients":
this.sendClientList();
break;
case "UpdatePlaylist":
- this.broadcast({ type : "UpdatePlaylist", updatePlaylist : { videoList : this.videoList}});
+ this.broadcast({ type : "UpdatePlaylist", updatePlaylist : { videoList : this.videoList.items}});
break;
case "VideoLoaded":
this.prepareVideoPlayback();
@@ -4765,14 +4796,15 @@ server_Main.prototype = {
}
}
,skipVideo: function(data) {
- if(this.videoList.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
- if(this.videoList[this.itemPos].url != data.skipVideo.url) {
+ var _this = this.videoList;
+ if(_this.items[_this.pos].url != data.skipVideo.url) {
return;
}
- this.itemPos = VideoList.skipItem(this.videoList,this.itemPos);
- if(this.videoList.length > 0) {
+ this.videoList.skipItem();
+ if(this.videoList.items.length > 0) {
this.restartWaitTimer();
}
this.broadcast(data);
@@ -4806,7 +4838,7 @@ server_Main.prototype = {
client.setGroupFlag(ClientGroup.Banned,!isOutdated);
if(isOutdated) {
HxOverrides.remove(this.userList.bans,ban);
- haxe_Log.trace("" + client.name + " ban removed",{ fileName : "src/server/Main.hx", lineNumber : 931, className : "server.Main", methodName : "checkBan"});
+ haxe_Log.trace("" + client.name + " ban removed",{ fileName : "src/server/Main.hx", lineNumber : 923, className : "server.Main", methodName : "checkBan"});
this.sendClientList();
}
break;
@@ -4956,15 +4988,6 @@ server_Utils.sortedPush = function(ids,id) {
}
ids.push(id);
};
-server_Utils.shuffle = function(arr) {
- var _g_current = 0;
- while(_g_current < arr.length) {
- var _g1_value = arr[_g_current++];
- var n = Std.random(arr.length);
- arr[_g_current - 1] = arr[n];
- arr[n] = _g1_value;
- }
-};
var server_VideoTimer = function() {
this.rate = 1.0;
this.rateStartTime = 0.0;
diff --git a/res/client.js b/res/client.js
index 9abfe25..8e36477 100644
--- a/res/client.js
+++ b/res/client.js
@@ -438,61 +438,68 @@ StringTools.hex = function(n,digits) {
}
return s;
};
-var VideoList = {};
-VideoList._new = function() {
- return [];
+var VideoList = function() {
+ this.items = [];
+ this.pos = 0;
};
-VideoList.findIndex = function(this1,f) {
- var i = 0;
- var _g = 0;
- while(_g < this1.length) {
- if(f(this1[_g++])) {
- return i;
+VideoList.__name__ = true;
+VideoList.prototype = {
+ setPos: function(i) {
+ if(i < 0 || i > this.items.length - 1) {
+ i = 0;
}
- ++i;
+ this.pos = i;
}
- return -1;
-};
-VideoList.addItem = function(this1,item,atEnd,itemPos) {
- if(atEnd) {
- this1.push(item);
- } else {
- this1.splice(itemPos + 1,0,item);
+ ,findIndex: function(f) {
+ var i = 0;
+ var _g = 0;
+ var _g1 = this.items;
+ while(_g < _g1.length) {
+ if(f(_g1[_g++])) {
+ return i;
+ }
+ ++i;
+ }
+ return -1;
}
-};
-VideoList.setNextItem = function(this1,pos,itemPos) {
- var next = this1[pos];
- HxOverrides.remove(this1,next);
- if(pos < itemPos) {
- --itemPos;
+ ,addItem: function(item,atEnd) {
+ if(atEnd) {
+ this.items.push(item);
+ } else {
+ this.items.splice(this.pos + 1,0,item);
+ }
}
- this1.splice(itemPos + 1,0,next);
- return itemPos;
-};
-VideoList.toggleItemType = function(this1,pos) {
- this1[pos].isTemp = !this1[pos].isTemp;
-};
-VideoList.removeItem = function(this1,index,itemPos) {
- if(index < itemPos) {
- --itemPos;
+ ,setNextItem: function(nextPos) {
+ var next = this.items[nextPos];
+ HxOverrides.remove(this.items,next);
+ if(nextPos < this.pos) {
+ this.pos--;
+ }
+ this.items.splice(this.pos + 1,0,next);
}
- HxOverrides.remove(this1,this1[index]);
- if(itemPos >= this1.length) {
- itemPos = 0;
+ ,toggleItemType: function(pos) {
+ this.items[pos].isTemp = !this.items[pos].isTemp;
}
- return itemPos;
-};
-VideoList.skipItem = function(this1,itemPos) {
- var item = this1[itemPos];
- if(!item.isTemp) {
- ++itemPos;
- } else {
- HxOverrides.remove(this1,item);
+ ,removeItem: function(index) {
+ if(index < this.pos) {
+ this.pos--;
+ }
+ HxOverrides.remove(this.items,this.items[index]);
+ if(this.pos >= this.items.length) {
+ this.pos = 0;
+ }
}
- if(itemPos >= this1.length) {
- itemPos = 0;
+ ,skipItem: function() {
+ var item = this.items[this.pos];
+ if(!item.isTemp) {
+ this.pos++;
+ } else {
+ HxOverrides.remove(this.items,item);
+ }
+ if(this.pos >= this.items.length) {
+ this.pos = 0;
+ }
}
- return itemPos;
};
var client_Buttons = function() { };
client_Buttons.__name__ = true;
@@ -1028,10 +1035,10 @@ client_JsApi.hasScriptInHead = $hx_exports["client"]["JsApi"]["hasScriptInHead"]
return false;
};
client_JsApi.getVideoItems = $hx_exports["client"]["JsApi"]["getVideoItems"] = function() {
+ var items = client_JsApi.player.getItems();
var _g = [];
var _g1 = 0;
- var _g2 = client_JsApi.player.getItems();
- while(_g1 < _g2.length) _g.push(Reflect.copy(_g2[_g1++]));
+ while(_g1 < items.length) _g.push(Reflect.copy(items[_g1++]));
return _g;
};
client_JsApi.addVideoItem = $hx_exports["client"]["JsApi"]["addVideoItem"] = function(url,atEnd,isTemp,callback) {
@@ -1440,10 +1447,10 @@ client_Main.prototype = {
this.player.refresh();
}
,getPlaylistLinks: function() {
+ var items = this.player.getItems();
var _g = [];
var _g1 = 0;
- var _g2 = this.player.getItems();
- while(_g1 < _g2.length) _g.push(_g2[_g1++].url);
+ while(_g1 < items.length) _g.push(items[_g1++].url);
return _g;
}
,tryLocalIp: function(url) {
@@ -2079,10 +2086,9 @@ var client_Player = function(main) {
this.skipSetRate = false;
this.skipSetTime = false;
this.isLoaded = false;
- this.itemPos = 0;
this.playerEl = window.document.querySelector("#ytapiplayer");
this.videoItemsEl = window.document.querySelector("#queue");
- this.items = VideoList._new();
+ this.videoList = new VideoList();
this.main = main;
this.players = [new client_players_Youtube(main,this)];
this.iframePlayer = new client_players_Iframe(main,this);
@@ -2112,19 +2118,20 @@ client_Player.prototype = {
};
}
,setNextItem: function(pos) {
- this.itemPos = VideoList.setNextItem(this.items,pos,this.itemPos);
+ this.videoList.setNextItem(pos);
var next = this.videoItemsEl.children[pos];
this.videoItemsEl.removeChild(next);
- client_Utils.insertAtIndex(this.videoItemsEl,next,this.itemPos + 1);
+ client_Utils.insertAtIndex(this.videoItemsEl,next,this.videoList.pos + 1);
}
,toggleItemType: function(pos) {
- VideoList.toggleItemType(this.items,pos);
- this.setItemElementType(this.videoItemsEl.children[pos],this.items[pos].isTemp);
+ this.videoList.toggleItemType(pos);
+ this.setItemElementType(this.videoItemsEl.children[pos],this.videoList.items[this.videoList.pos].isTemp);
}
,setPlayer: function(newPlayer) {
if(this.player != newPlayer) {
if(this.player != null) {
- client_JsApi.fireVideoRemoveEvents(this.items[this.itemPos]);
+ var _this = this.videoList;
+ client_JsApi.fireVideoRemoveEvents(_this.items[_this.pos]);
this.player.removeVideo();
}
this.main.blinkTabWithTitle("*Video*");
@@ -2152,7 +2159,7 @@ client_Player.prototype = {
if(!this.main.isSyncActive) {
return;
}
- var item = this.items[i];
+ var item = this.videoList.items[i];
var currentPlayer = Lambda.find(this.players,function(p) {
return p.isSupportedLink(item.url);
});
@@ -2163,12 +2170,9 @@ client_Player.prototype = {
} else {
this.setPlayer(this.rawPlayer);
}
- var childs = this.videoItemsEl.children;
- if(childs[this.itemPos] != null) {
- childs[this.itemPos].classList.remove("queue_active");
- }
- this.itemPos = i;
- childs[this.itemPos].classList.add("queue_active");
+ this.removeActiveLabel(this.videoList.pos);
+ this.videoList.setPos(i);
+ this.addActiveLabel(this.videoList.pos);
this.isLoaded = false;
this.player.loadVideo(item);
client_JsApi.fireVideoChangeEvents(item);
@@ -2178,14 +2182,16 @@ client_Player.prototype = {
if(this.player == null) {
return;
}
- var item = this.items[this.itemPos];
+ var _this = this.videoList;
+ var item = _this.items[_this.pos];
if(item == null) {
return;
}
this.player.loadVideo({ url : src, title : item.title, author : item.author, duration : item.duration, subs : item.subs, isTemp : item.isTemp, isIframe : item.isIframe});
}
,removeVideo: function() {
- client_JsApi.fireVideoRemoveEvents(this.items[this.itemPos]);
+ var _this = this.videoList;
+ client_JsApi.fireVideoRemoveEvents(_this.items[_this.pos]);
this.player.removeVideo();
window.document.querySelector("#currenttitle").textContent = Lang.get("nothingPlaying");
this.setPauseIndicator(true);
@@ -2212,7 +2218,7 @@ client_Player.prototype = {
return;
}
this.main.send({ type : "Play", play : { time : this.getTime()}});
- if(this.main.hasLeaderOnPauseRequest() && this.items.length > 0) {
+ if(this.main.hasLeaderOnPauseRequest() && this.videoList.items.length > 0) {
if(this.main.hasPermission((this.main.personal.group & 8) != 0 ? ClientGroup.Admin : ClientGroup.User,"requestLeader")) {
this.main.toggleLeader();
}
@@ -2220,7 +2226,7 @@ client_Player.prototype = {
}
,onPause: function() {
var _gthis = this;
- if(this.main.hasLeaderOnPauseRequest() && this.items.length > 0 && this.getTime() > 1 && !this.main.hasLeader()) {
+ if(this.main.hasLeaderOnPauseRequest() && this.videoList.items.length > 0 && this.getTime() > 1 && !this.main.hasLeader()) {
client_JsApi.once("SetLeader",function(event) {
if(event.setLeader.clientName != _gthis.main.personal.name) {
return;
@@ -2260,12 +2266,12 @@ client_Player.prototype = {
var url = StringTools.htmlEscape(item.url,true);
var duration = item.isIframe ? "" : this.duration(item.duration);
var itemEl = client_Utils.nodeFromString("<li class=\"queue_entry info\" title=\"" + Lang.get("addedBy") + ": " + item.author + "\">\n\t\t\t\t<header>\n\t\t\t\t\t<span class=\"qe_time\">" + duration + "</span>\n\t\t\t\t\t<h4><a class=\"qe_title\" href=\"" + url + "\" target=\"_blank\">" + StringTools.htmlEscape(item.title) + "</a></h4>\n\t\t\t\t</header>\n\t\t\t\t<span class=\"controls\">\n\t\t\t\t\t<button class=\"qbtn-play\" title=\"" + Lang.get("play") + "\"><ion-icon name=\"play\"></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-next\" title=\"" + Lang.get("setNext") + "\"><ion-icon name=\"arrow-up\"></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-tmp\"><ion-icon></ion-icon></button>\n\t\t\t\t\t<button class=\"qbtn-delete\" title=\"" + Lang.get("delete") + "\"><ion-icon name=\"close\"></ion-icon></button>\n\t\t\t\t</span>\n\t\t\t</li>");
- VideoList.addItem(this.items,item,atEnd,this.itemPos);
+ this.videoList.addItem(item,atEnd);
this.setItemElementType(itemEl,item.isTemp);
if(atEnd) {
this.videoItemsEl.appendChild(itemEl);
} else {
- client_Utils.insertAtIndex(this.videoItemsEl,itemEl,this.itemPos + 1);
+ client_Utils.insertAtIndex(this.videoItemsEl,itemEl,this.videoList.pos + 1);
}
this.updateCounters();
}
@@ -2281,17 +2287,18 @@ client_Player.prototype = {
}
,removeItem: function(url) {
this.removeElementItem(url);
- var index = VideoList.findIndex(this.items,function(item) {
+ var index = this.videoList.findIndex(function(item) {
return item.url == url;
});
if(index == -1) {
return;
}
- var isCurrent = this.items[this.itemPos].url == url;
- this.itemPos = VideoList.removeItem(this.items,index,this.itemPos);
+ var _this = this.videoList;
+ var isCurrent = _this.items[_this.pos].url == url;
+ this.videoList.removeItem(index);
this.updateCounters();
- if(isCurrent && this.items.length > 0) {
- this.setVideo(this.itemPos);
+ if(isCurrent && this.videoList.items.length > 0) {
+ this.setVideo(this.videoList.pos);
}
}
,removeElementItem: function(url) {
@@ -2307,60 +2314,84 @@ client_Player.prototype = {
}
}
,skipItem: function(url) {
- var index = VideoList.findIndex(this.items,function(item) {
+ var pos = this.videoList.findIndex(function(item) {
return item.url == url;
});
- if(index == -1) {
+ if(pos == -1) {
return;
}
- if(this.items[index].isTemp) {
+ this.removeActiveLabel(this.videoList.pos);
+ this.videoList.setPos(pos);
+ var _this = this.videoList;
+ if(_this.items[_this.pos].isTemp) {
this.removeElementItem(url);
}
- index = VideoList.skipItem(this.items,index);
+ this.videoList.skipItem();
this.updateCounters();
- if(this.items.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
- this.setVideo(index);
+ this.setVideo(this.videoList.pos);
+ }
+ ,addActiveLabel: function(pos) {
+ var childs = this.videoItemsEl.children;
+ if(childs[this.videoList.pos] != null) {
+ childs[this.videoList.pos].classList.add("queue_active");
+ }
+ }
+ ,removeActiveLabel: function(pos) {
+ var childs = this.videoItemsEl.children;
+ if(childs[this.videoList.pos] != null) {
+ childs[this.videoList.pos].classList.remove("queue_active");
+ }
}
,updateCounters: function() {
- var tmp = "" + this.items.length + " ";
+ var tmp = "" + this.videoList.items.length + " ";
var tmp1 = Lang.get("videos");
window.document.querySelector("#plcount").textContent = tmp + tmp1;
window.document.querySelector("#pllength").textContent = this.totalDuration();
}
,getItems: function() {
- return this.items;
+ return this.videoList.items;
}
,setItems: function(list,pos) {
- var currentUrl = this.itemPos >= this.items.length ? "" : this.items[this.itemPos].url;
+ var currentUrl;
+ if(this.videoList.pos >= this.videoList.items.length) {
+ currentUrl = "";
+ } else {
+ var _this = this.videoList;
+ currentUrl = _this.items[_this.pos].url;
+ }
this.clearItems();
if(pos != null) {
- this.itemPos = pos;
+ this.videoList.setPos(pos);
}
if(list.length == 0) {
return;
}
var _g = 0;
while(_g < list.length) this.addVideoItem(list[_g++],true);
- if(currentUrl != this.items[this.itemPos].url) {
- this.setVideo(this.itemPos);
+ var _this = this.videoList;
+ if(currentUrl != _this.items[_this.pos].url) {
+ this.setVideo(this.videoList.pos);
} else {
- this.videoItemsEl.children[this.itemPos].classList.add("queue_active");
+ this.addActiveLabel(this.videoList.pos);
}
}
,clearItems: function() {
- this.items.length = 0;
+ var _this = this.videoList;
+ _this.items.length = 0;
+ _this.pos = 0;
this.videoItemsEl.textContent = "";
this.updateCounters();
}
,refresh: function() {
- if(this.items.length == 0) {
+ if(this.videoList.items.length == 0) {
return;
}
var time = this.getTime();
this.removeVideo();
- this.setVideo(this.itemPos);
+ this.setVideo(this.videoList.pos);
if((this.main.personal.group & 4) != 0) {
this.setTime(time);
this.main.forceSyncNextTick = true;
@@ -2386,7 +2417,7 @@ client_Player.prototype = {
,totalDuration: function() {
var time = 0.0;
var _g = 0;
- var _g1 = this.items;
+ var _g1 = this.videoList.items;
while(_g < _g1.length) {
var item = _g1[_g];
++_g;
@@ -2398,22 +2429,23 @@ client_Player.prototype = {
return this.duration(time);
}
,isListEmpty: function() {
- return this.items.length == 0;
+ return this.videoList.items.length == 0;
}
,itemsLength: function() {
- return this.items.length;
+ return this.videoList.items.length;
}
,getItemPos: function() {
- return this.itemPos;
+ return this.videoList.pos;
}
,hasVideo: function() {
return this.playerEl.children.length != 0;
}
,getDuration: function() {
- if(this.itemPos >= this.items.length) {
+ if(this.videoList.pos >= this.videoList.items.length) {
return 0;
}
- return this.items[this.itemPos].duration;
+ var _this = this.videoList;
+ return _this.items[_this.pos].duration;
}
,isVideoLoaded: function() {
return this.player.isVideoLoaded();
@@ -2863,6 +2895,9 @@ client_players_Raw.prototype = {
this.controlsHider.stop();
}
this.controlsHider = haxe_Timer.delay(function() {
+ if(_gthis.video == null) {
+ return;
+ }
_gthis.video.controls = false;
},3000);
this.video.onmousemove = function(e) {
diff --git a/src/VideoList.hx b/src/VideoList.hx
index ef1d113..2ed1d8f 100644
--- a/src/VideoList.hx
+++ b/src/VideoList.hx
@@ -2,73 +2,116 @@ package;
import Types.VideoItem;
-// TODO move itemPos to abstract
-// typedef VideoListData = {
-// items:Array<VideoItem>,
-// itemPos:Int
-// }
-@:forward
-abstract VideoList(Array<VideoItem>) from Array<VideoItem> to Array<VideoItem> {
- public function new() {
- this = [];
+using Lambda;
+
+class VideoList {
+ public var length(get, never):Int;
+ public var pos(default, null) = 0;
+ public var isOpen = true;
+
+ final items:Array<VideoItem> = [];
+
+ public function new() {}
+
+ inline function get_length():Int {
+ return items.length;
+ }
+
+ public inline function getCurrentItem():VideoItem {
+ return items[pos];
}
- @:arrayAccess
- public inline function get(i:Int):VideoItem {
- return this[i];
+ public inline function getItem(i:Int):VideoItem {
+ return items[i];
}
- @:arrayAccess
- public inline function set(k:Int, v:VideoItem):VideoItem {
- return this[k] = v;
+ public inline function setItem(i:Int, item:VideoItem):Void {
+ items[i] = item;
+ }
+
+ public inline function getItems():Array<VideoItem> {
+ return items;
+ }
+
+ public function setItems(items:Array<VideoItem>):Void {
+ clear();
+ for (item in items)
+ this.items.push(item);
+ }
+
+ public function setPos(i:Int):Void {
+ if (i < 0 || i > length - 1) i = 0;
+ pos = i;
+ }
+
+ public function exists(f:(item:VideoItem) -> Bool):Bool {
+ return items.exists(f);
}
public function findIndex(f:(item:VideoItem) -> Bool):Int {
var i = 0;
- for (v in this) {
+ for (v in items) {
if (f(v)) return i;
i++;
}
return -1;
}
- public function addItem(item:VideoItem, atEnd:Bool, itemPos:Int):Void {
- if (atEnd) this.push(item);
- else this.insert(itemPos + 1, item);
+ public function addItem(item:VideoItem, atEnd:Bool):Void {
+ if (atEnd) items.push(item);
+ else items.insert(pos + 1, item);
}
- public function setNextItem(pos:Int, itemPos:Int):Int {
- final next = this[pos];
- this.remove(next);
- if (pos < itemPos) itemPos--;
- this.insert(itemPos + 1, next);
- return itemPos;
+ public function setNextItem(nextPos:Int):Void {
+ final next = items[nextPos];
+ items.remove(next);
+ if (nextPos < pos) pos--;
+ items.insert(pos + 1, next);
}
public function toggleItemType(pos:Int):Void {
- this[pos].isTemp = !this[pos].isTemp;
+ items[pos].isTemp = !items[pos].isTemp;
}
- public function removeItem(index:Int, itemPos:Int):Int {
- if (index < itemPos) itemPos--;
- this.remove(this[index]);
- if (itemPos >= this.length) itemPos = 0;
- return itemPos;
+ public function removeItem(index:Int):Void {
+ if (index < pos) pos--;
+ items.remove(items[index]);
+ if (pos >= items.length) pos = 0;
}
- public function skipItem(itemPos:Int):Int {
- final item = this[itemPos];
- if (!item.isTemp) itemPos++;
- else this.remove(item);
- if (itemPos >= this.length) itemPos = 0;
- return itemPos;
+ public function skipItem():Void {
+ final item = items[pos];
+ if (!item.isTemp) pos++;
+ else items.remove(item);
+ if (pos >= items.length) pos = 0;
}
public function itemsByUser(client:Client):Int {
var i = 0;
- for (item in this) {
+ for (item in items) {
if (item.author == client.name) i++;
}
return i;
}
+
+ public inline function clear():Void {
+ items.resize(0);
+ pos = 0;
+ }
+
+ public function shuffle() {
+ final current = items[pos];
+ items.remove(current);
+ shuffleArray(items);
+ items.insert(pos, current);
+ }
+
+ function shuffleArray<T>(arr:Array<T>):Void {
+ for (i => a in arr) {
+ final n = Std.random(arr.length);
+ final b = arr[n];
+ arr[i] = b;
+ arr[n] = a;
+ }
+ }
}
diff --git a/src/client/JsApi.hx b/src/client/JsApi.hx
index d9e6f02..63b98c5 100644
--- a/src/client/JsApi.hx
+++ b/src/client/JsApi.hx
@@ -66,7 +66,7 @@ class JsApi {
}
@:expose
- static function getVideoItems():VideoList {
+ static function getVideoItems():Array<VideoItem> {
final items = player.getItems();
return [
for (item in items) Reflect.copy(item)
diff --git a/src/client/Player.hx b/src/client/Player.hx
index 4d70526..496c355 100644
--- a/src/client/Player.hx
+++ b/src/client/Player.hx
@@ -17,11 +17,10 @@ class Player {
final players:Array<IPlayer>;
final iframePlayer:IPlayer;
final rawPlayer:IPlayer;
- final items = new VideoList();
+ final videoList = new VideoList();
final videoItemsEl = ge("#queue");
final playerEl:Element = ge("#ytapiplayer");
var player:Null<IPlayer>;
- var itemPos = 0;
var isLoaded = false;
var skipSetTime = false;
var skipSetRate = false;
@@ -73,23 +72,23 @@ class Player {
}
public function setNextItem(pos:Int):Void {
- itemPos = items.setNextItem(pos, itemPos);
+ videoList.setNextItem(pos);
final next = videoItemsEl.children[pos];
videoItemsEl.removeChild(next);
- Utils.insertAtIndex(videoItemsEl, next, itemPos + 1);
+ Utils.insertAtIndex(videoItemsEl, next, videoList.pos + 1);
}
public function toggleItemType(pos:Int):Void {
- items.toggleItemType(pos);
+ videoList.toggleItemType(pos);
final el = videoItemsEl.children[pos];
- setItemElementType(el, items[pos].isTemp);
+ setItemElementType(el, videoList.getItem(videoList.pos).isTemp);
}
function setPlayer(newPlayer:IPlayer):Void {
if (player != newPlayer) {
if (player != null) {
- JsApi.fireVideoRemoveEvents(items[itemPos]);
+ JsApi.fireVideoRemoveEvents(videoList.getCurrentItem());
player.removeVideo();
}
main.blinkTabWithTitle("*Video*");
@@ -113,18 +112,15 @@ class Player {
public function setVideo(i:Int):Void {
if (!main.isSyncActive) return;
- final item = items[i];
+ final item = videoList.getItem(i);
var currentPlayer = players.find(p -> p.isSupportedLink(item.url));
if (currentPlayer != null) setPlayer(currentPlayer);
else if (item.isIframe) setPlayer(iframePlayer);
else setPlayer(rawPlayer);
- final childs = videoItemsEl.children;
- if (childs[itemPos] != null) {
- childs[itemPos].classList.remove("queue_active");
- }
- itemPos = i;
- childs[itemPos].classList.add("queue_active");
+ removeActiveLabel(videoList.pos);
+ videoList.setPos(i);
+ addActiveLabel(videoList.pos);
isLoaded = false;
player.loadVideo(item);
@@ -134,7 +130,7 @@ class Player {
public function changeVideoSrc(src:String):Void {
if (player == null) return;
- final item = items[itemPos];
+ final item = videoList.getCurrentItem();
if (item == null) return;
player.loadVideo({
url: src,
@@ -148,7 +144,7 @@ class Player {
}
public function removeVideo():Void {
- JsApi.fireVideoRemoveEvents(items[itemPos]);
+ JsApi.fireVideoRemoveEvents(videoList.getCurrentItem());
player.removeVideo();
ge("#currenttitle").textContent = Lang.get("nothingPlaying");
setPauseIndicator(true);
@@ -175,7 +171,7 @@ class Player {
time: getTime()
}
});
- final hasAutoPause = main.hasLeaderOnPauseRequest() && items.length > 0;
+ final hasAutoPause = main.hasLeaderOnPauseRequest() && videoList.length > 0;
if (hasAutoPause) {
// do not remove leader if user cannot request it back
final group:Client.ClientGroup = main.isAdmin() ? Admin : User;
@@ -184,7 +180,7 @@ class Player {
}
public function onPause():Void {
- final hasAutoPause = main.hasLeaderOnPauseRequest() && items.length > 0
+ final hasAutoPause = main.hasLeaderOnPauseRequest() && videoList.length > 0
&& getTime() > 1;
if (hasAutoPause && !main.hasLeader()) {
JsApi.once(SetLeader, event -> {
@@ -255,10 +251,10 @@ class Player {
</span>
</li>'
);
- items.addItem(item, atEnd, itemPos);
+ videoList.addItem(item, atEnd);
setItemElementType(itemEl, item.isTemp);
if (atEnd) videoItemsEl.appendChild(itemEl);
- else Utils.insertAtIndex(videoItemsEl, itemEl, itemPos + 1);
+ else Utils.insertAtIndex(videoItemsEl, itemEl, videoList.pos + 1);
updateCounters();
}
@@ -273,15 +269,15 @@ class Player {
public function removeItem(url:String):Void {
removeElementItem(url);
- var index = items.findIndex(item -> item.url == url);
+ var index = videoList.findIndex(item -> item.url == url);
if (index == -1) return;
- final isCurrent = items[itemPos].url == url;
- itemPos = items.removeItem(index, itemPos);
+ final isCurrent = videoList.getCurrentItem().url == url;
+ videoList.removeItem(index);
updateCounters();
- if (isCurrent && items.length > 0) {
- setVideo(itemPos);
+ if (isCurrent && videoList.length > 0) {
+ setVideo(videoList.pos);
}
}
@@ -295,47 +291,64 @@ class Player {
}
public function skipItem(url:String):Void {
- var index = items.findIndex(item -> item.url == url);
- if (index == -1) return;
- if (items[index].isTemp) removeElementItem(url);
- index = items.skipItem(index);
+ final pos = videoList.findIndex(item -> item.url == url);
+ if (pos == -1) return;
+ removeActiveLabel(videoList.pos);
+ videoList.setPos(pos);
+ if (videoList.getCurrentItem().isTemp) removeElementItem(url);
+ videoList.skipItem();
updateCounters();
- if (items.length == 0) return;
- setVideo(index);
+ if (videoList.length == 0) return;
+ setVideo(videoList.pos);
+ }
+
+ function addActiveLabel(pos:Int):Void {
+ final childs = videoItemsEl.children;
+ if (childs[videoList.pos] != null) {
+ childs[videoList.pos].classList.add("queue_active");
+ }
+ }
+
+ function removeActiveLabel(pos:Int):Void {
+ final childs = videoItemsEl.children;
+ if (childs[videoList.pos] != null) {
+ childs[videoList.pos].classList.remove("queue_active");
+ }
}
function updateCounters():Void {
- ge("#plcount").textContent = '${items.length} ${Lang.get("videos")}';
+ ge("#plcount").textContent = '${videoList.length} ${Lang.get("videos")}';
ge("#pllength").textContent = totalDuration();
}
- public function getItems():VideoList {
- return items;
+ public function getItems():Array<VideoItem> {
+ return videoList.getItems();
}
public function setItems(list:Array<VideoItem>, ?pos:Int):Void {
- final currentUrl = itemPos >= items.length ? "" : items[itemPos].url;
+ final currentUrl = videoList.pos >= videoList.length ? "" : videoList.getCurrentItem()
+ .url;
clearItems();
- if (pos != null) itemPos = pos;
+ if (pos != null) videoList.setPos(pos);
if (list.length == 0) return;
for (video in list) {
addVideoItem(video, true);
}
- if (currentUrl != items[itemPos].url) setVideo(itemPos);
- else videoItemsEl.children[itemPos].classList.add("queue_active");
+ if (currentUrl != videoList.getCurrentItem().url) setVideo(videoList.pos);
+ else addActiveLabel(videoList.pos);
}
public function clearItems():Void {
- items.resize(0);
+ videoList.clear();
videoItemsEl.textContent = "";
updateCounters();
}
public function refresh():Void {
- if (items.length == 0) return;
+ if (videoList.length == 0) return;
final time = getTime();
removeVideo();
- setVideo(itemPos);
+ setVideo(videoList.pos);
// restore server time for leader with next GetTime
if (main.isLeader()) {
setTime(time);
@@ -357,7 +370,7 @@ class Player {
function totalDuration():String {
var time = 0.0;
- for (item in items) {
+ for (item in videoList.getItems()) {
if (item.isIframe) continue;
time += item.duration;
}
@@ -365,15 +378,15 @@ class Player {
}
public function isListEmpty():Bool {
- return items.length == 0;
+ return videoList.length == 0;
}
public function itemsLength():Int {
- return items.length;
+ return videoList.length;
}
public function getItemPos():Int {
- return itemPos;
+ return videoList.pos;
}
public function hasVideo():Bool {
@@ -381,8 +394,8 @@ class Player {
}
public function getDuration():Float {
- if (itemPos >= items.length) return 0;
- return items[itemPos].duration;
+ if (videoList.pos >= videoList.length) return 0;
+ return videoList.getCurrentItem().duration;
}
public function isVideoLoaded():Bool {
diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx
index 4b78b0f..dc3aed5 100644
--- a/src/client/players/Raw.hx
+++ b/src/client/players/Raw.hx
@@ -127,6 +127,7 @@ class Raw implements IPlayer {
if (Utils.isTouch()) return;
if (controlsHider != null) controlsHider.stop();
controlsHider = Timer.delay(() -> {
+ if (video == null) return;
video.controls = false;
}, 3000);
video.onmousemove = e -> {
diff --git a/src/server/Main.hx b/src/server/Main.hx
index 748c513..3ab0621 100644
--- a/src/server/Main.hx
+++ b/src/server/Main.hx
@@ -54,8 +54,6 @@ class Main {
final videoTimer = new VideoTimer();
final messages:Array<Message> = [];
final logger:Logger;
- var isPlaylistOpen = true;
- var itemPos = 0;
static function main():Void {
new Main({
@@ -245,9 +243,9 @@ class Main {
function getCurrentState():ServerState {
return {
- videoList: videoList,
- isPlaylistOpen: isPlaylistOpen,
- itemPos: itemPos,
+ videoList: videoList.getItems(),
+ isPlaylistOpen: videoList.isOpen,
+ itemPos: videoList.pos,
messages: messages,
timer: {
time: videoTimer.getTime(),
@@ -261,13 +259,10 @@ class Main {
if (!FileSystem.exists(statePath)) return;
trace("Loading state...");
final data:ServerState = Json.parse(File.getContent(statePath));
- videoList.resize(0);
+ videoList.setItems(data.videoList);
messages.resize(0);
- for (item in data.videoList) {
- videoList.push(item);
- }
- isPlaylistOpen = data.isPlaylistOpen;
- itemPos = data.itemPos;
+ videoList.isOpen = data.isPlaylistOpen;
+ videoList.setPos(data.itemPos);
for (message in data.messages) {
messages.push(message);
}
@@ -428,9 +423,9 @@ class Main {
isUnknownClient: true,
clientName: client.name,
clients: clientList(),
- videoList: videoList,
- isPlaylistOpen: isPlaylistOpen,
- itemPos: itemPos,
+ videoList: videoList.getItems(),
+ isPlaylistOpen: videoList.isOpen,
+ itemPos: videoList.pos,
globalIp: globalIp
}
});
@@ -574,7 +569,7 @@ class Main {
case ServerMessage:
case AddVideo:
if (!checkPermission(client, AddVideoPerm)) return;
- if (!isPlaylistOpen) {
+ if (!videoList.isOpen) {
if (!checkPermission(client, LockPlaylistPerm)) return;
}
if (config.totalVideoLimit != 0 && videoList.length >= config.totalVideoLimit) {
@@ -599,7 +594,7 @@ class Main {
serverMessage(client, "videoAlreadyExistsError");
return;
}
- videoList.addItem(item, data.addVideo.atEnd, itemPos);
+ videoList.addItem(item, data.addVideo.atEnd);
broadcast(data);
// Initial timer start if VideoLoaded is not happen
if (videoList.length == 1) restartWaitTimer();
@@ -615,8 +610,8 @@ class Main {
var index = videoList.findIndex(item -> item.url == url);
if (index == -1) return;
- final isCurrent = videoList[itemPos].url == url;
- itemPos = videoList.removeItem(index, itemPos);
+ final isCurrent = videoList.getCurrentItem().url == url;
+ videoList.removeItem(index);
if (isCurrent && videoList.length > 0) {
broadcast(data);
restartWaitTimer();
@@ -656,11 +651,11 @@ class Main {
case GetTime:
if (videoList.length == 0) return;
- final maxTime = videoList[itemPos].duration - 0.01;
+ final maxTime = videoList.getCurrentItem().duration - 0.01;
if (videoTimer.getTime() > maxTime) {
videoTimer.pause();
videoTimer.setTime(maxTime);
- final skipUrl = videoList[itemPos].url;
+ final skipUrl = videoList.getCurrentItem().url;
Timer.delay(() -> {
skipVideo({
type: SkipVideo,
@@ -756,15 +751,16 @@ class Main {
case PlayItem:
if (!checkPermission(client, ChangeOrderPerm)) return;
- itemPos = data.playItem.pos;
+ videoList.setPos(data.playItem.pos);
+ data.playItem.pos = videoList.pos;
restartWaitTimer();
broadcast(data);
case SetNextItem:
if (!checkPermission(client, ChangeOrderPerm)) return;
final pos = data.setNextItem.pos;
- if (pos == itemPos || pos == itemPos + 1) return;
- itemPos = videoList.setNextItem(pos, itemPos);
+ if (pos == videoList.pos || pos == videoList.pos + 1) return;
+ videoList.setNextItem(pos);
broadcast(data);
case ToggleItemType:
@@ -780,21 +776,17 @@ class Main {
case ClearPlaylist:
if (!checkPermission(client, RemoveVideoPerm)) return;
videoTimer.stop();
- videoList.resize(0);
- itemPos = 0;
+ videoList.clear();
broadcast(data);
case ShufflePlaylist:
if (!checkPermission(client, ChangeOrderPerm)) return;
if (videoList.length == 0) return;
- final current = videoList[itemPos];
- videoList.remove(current);
- Utils.shuffle(videoList);
- videoList.insert(itemPos, current);
+ videoList.shuffle();
broadcast({
type: UpdatePlaylist,
updatePlaylist: {
- videoList: videoList
+ videoList: videoList.getItems()
}
});
@@ -802,17 +794,17 @@ class Main {
broadcast({
type: UpdatePlaylist,
updatePlaylist: {
- videoList: videoList
+ videoList: videoList.getItems()
}
});
case TogglePlaylistLock:
if (!checkPermission(client, LockPlaylistPerm)) return;
- isPlaylistOpen = !isPlaylistOpen;
+ videoList.isOpen = !videoList.isOpen;
broadcast({
type: TogglePlaylistLock,
togglePlaylistLock: {
- isOpen: isPlaylistOpen
+ isOpen: videoList.isOpen
}
});
@@ -894,9 +886,9 @@ class Main {
function skipVideo(data:WsEvent):Void {
if (videoList.length == 0) return;
- final item = videoList[itemPos];
+ final item = videoList.getCurrentItem();
if (item.url != data.skipVideo.url) return;
- itemPos = videoList.skipItem(itemPos);
+ videoList.skipItem();
if (videoList.length > 0) restartWaitTimer();
broadcast(data);
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage