diff options
| author | RblSb <msrblsb@gmail.com> | 2021-09-27 20:48:29 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2021-09-27 20:49:05 +0300 |
| commit | 98c1f6fa4ec7537ec979a1ae8d68cb6ec11c3fbf (patch) | |
| tree | cf16a26097b00226c8f9fedbb9c1a5ecfb2211a3 | |
| parent | 1dc2722d509e578b243bfda1a675dcfdb6003941 (diff) | |
Rework videolist structure
| -rw-r--r-- | build/server.js | 287 | ||||
| -rw-r--r-- | res/client.js | 229 | ||||
| -rw-r--r-- | src/VideoList.hx | 119 | ||||
| -rw-r--r-- | src/client/JsApi.hx | 2 | ||||
| -rw-r--r-- | src/client/Player.hx | 107 | ||||
| -rw-r--r-- | src/client/players/Raw.hx | 1 | ||||
| -rw-r--r-- | src/server/Main.hx | 62 |
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); } |
