diff options
| author | RblSb <msrblsb@gmail.com> | 2020-03-02 12:51:20 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2020-03-02 12:51:20 +0300 |
| commit | 298197a07496a762c415d0a7c77e0307243504b8 (patch) | |
| tree | 0f8d90e2b175fd72a13f394ab7e7257ef03943b2 | |
| parent | 8a277e9ca3a64d7b298b7c9333153f5512aa176d (diff) | |
Playlist lock toggler
| -rw-r--r-- | build/server.js | 76 | ||||
| -rw-r--r-- | res/client.js | 88 | ||||
| -rw-r--r-- | res/index.html | 2 | ||||
| -rw-r--r-- | src/Types.hx | 5 | ||||
| -rw-r--r-- | src/client/Buttons.hx | 4 | ||||
| -rw-r--r-- | src/client/Main.hx | 26 | ||||
| -rw-r--r-- | src/server/Main.hx | 15 | ||||
| -rw-r--r-- | src/server/ServerState.hx | 1 |
8 files changed, 156 insertions, 61 deletions
diff --git a/build/server.js b/build/server.js index e642155..5a6037d 100644 --- a/build/server.js +++ b/build/server.js @@ -183,6 +183,25 @@ Lambda.exists = function(it,f) { } return false; }; +var haxe_ds_StringMap = function() { + this.h = { }; +}; +haxe_ds_StringMap.__name__ = true; +haxe_ds_StringMap.prototype = { + setReserved: function(key,value) { + if(this.rh == null) { + this.rh = { }; + } + this.rh["$" + key] = value; + } + ,getReserved: function(key) { + if(this.rh == null) { + return null; + } else { + return this.rh["$" + key]; + } + } +}; var Lang = function() { }; Lang.__name__ = true; Lang.request = function(path,callback) { @@ -538,25 +557,6 @@ haxe_crypto_Sha256.prototype = { return str.toLowerCase(); } }; -var haxe_ds_StringMap = function() { - this.h = { }; -}; -haxe_ds_StringMap.__name__ = true; -haxe_ds_StringMap.prototype = { - setReserved: function(key,value) { - if(this.rh == null) { - this.rh = { }; - } - this.rh["$" + key] = value; - } - ,getReserved: function(key) { - if(this.rh == null) { - return null; - } else { - return this.rh["$" + key]; - } - } -}; var haxe_io_Bytes = function(data) { this.length = data.byteLength; this.b = new Uint8Array(data); @@ -932,6 +932,7 @@ var server_Main = function(port,wsPort) { this.loadedClientsCount = 0; this.htmlChars = new EReg("[&^<>'\"]",""); this.itemPos = 0; + this.isPlaylistOpen = true; this.messages = []; this.videoTimer = new server_VideoTimer(); this.videoList = _$VideoList_VideoList_$Impl_$._new(); @@ -970,8 +971,8 @@ var server_Main = function(port,wsPort) { this.port = port; server_Utils.getGlobalIp(function(ip) { _gthis.globalIp = ip; - haxe_Log.trace("Local: http://" + _gthis.localIp + ":" + port,{ fileName : "src/server/Main.hx", lineNumber : 74, className : "server.Main", methodName : "new"}); - haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + port,{ fileName : "src/server/Main.hx", lineNumber : 75, className : "server.Main", methodName : "new"}); + haxe_Log.trace("Local: http://" + _gthis.localIp + ":" + port,{ fileName : "src/server/Main.hx", lineNumber : 75, className : "server.Main", methodName : "new"}); + haxe_Log.trace("Global: http://" + _gthis.globalIp + ":" + port,{ fileName : "src/server/Main.hx", lineNumber : 76, className : "server.Main", methodName : "new"}); return; }); var dir = "" + this.rootDir + "/res"; @@ -1014,7 +1015,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 : 107, className : "server.Main", methodName : "loadUserConfig"}); + haxe_Log.trace("Warning: config field \"" + field + "\" is unknown",{ fileName : "src/server/Main.hx", lineNumber : 108, className : "server.Main", methodName : "loadUserConfig"}); } config[field] = Reflect.field(customConfig,field); } @@ -1035,21 +1036,22 @@ server_Main.prototype = { js_node_Fs.writeFileSync("" + folder + "/users.json",JSON.stringify(users,null,"\t")); } ,saveState: function() { - haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 131, className : "server.Main", methodName : "saveState"}); - var json = JSON.stringify({ videoList : this.videoList, itemPos : this.itemPos, messages : this.messages, timer : { time : this.videoTimer.getTime(), paused : this.videoTimer.isPaused()}},null,"\t"); + haxe_Log.trace("Saving state...",{ fileName : "src/server/Main.hx", lineNumber : 132, className : "server.Main", methodName : "saveState"}); + var json = JSON.stringify({ videoList : this.videoList, isPlaylistOpen : this.isPlaylistOpen, itemPos : this.itemPos, messages : this.messages, timer : { time : this.videoTimer.getTime(), paused : this.videoTimer.isPaused()}},null,"\t"); js_node_Fs.writeFileSync(this.statePath,json); } ,loadState: function() { if(!sys_FileSystem.exists(this.statePath)) { return; } - haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 147, className : "server.Main", methodName : "loadState"}); + haxe_Log.trace("Loading state...",{ fileName : "src/server/Main.hx", lineNumber : 149, className : "server.Main", methodName : "loadState"}); var data = JSON.parse(js_node_Fs.readFileSync(this.statePath,{ encoding : "utf8"})); this.videoList.length = 0; this.messages.length = 0; var _g = 0; var _g1 = data.videoList; while(_g < _g1.length) this.videoList.push(_g1[_g++]); + this.isPlaylistOpen = data.isPlaylistOpen; this.itemPos = data.itemPos; var _g2 = 0; var _g3 = data.messages; @@ -1059,7 +1061,7 @@ server_Main.prototype = { this.videoTimer.pause(); } ,logError: function(type,data) { - haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 160, className : "server.Main", methodName : "logError", customParams : [data]}); + haxe_Log.trace(type,{ fileName : "src/server/Main.hx", lineNumber : 163, className : "server.Main", methodName : "logError", customParams : [data]}); var crashesFolder = "" + this.rootDir + "/user/crashes"; var name = new Date().toISOString() + "-" + type; if(!sys_FileSystem.exists(crashesFolder)) { @@ -1075,7 +1077,7 @@ server_Main.prototype = { return; } var url = "http://" + process.env["APP_URL"]; - haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 174, className : "server.Main", methodName : "initIntergationHandlers"}); + haxe_Log.trace("Ping " + url,{ fileName : "src/server/Main.hx", lineNumber : 177, className : "server.Main", methodName : "initIntergationHandlers"}); js_node_Http.get(url,function(r) { return; }); @@ -1090,14 +1092,14 @@ server_Main.prototype = { } this.userList.admins.push({ name : name, hash : hash}); this.writeUsers(this.userList); - haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 189, className : "server.Main", methodName : "addAdmin"}); + haxe_Log.trace("Admin " + name + " added.",{ fileName : "src/server/Main.hx", lineNumber : 192, className : "server.Main", methodName : "addAdmin"}); } ,onConnect: function(ws,req) { var _gthis = this; var ip = req.connection.remoteAddress; var id = this.freeIds.length > 0 ? this.freeIds.shift() : this.clients.length; var name = "Guest " + (id + 1); - haxe_Log.trace("" + name + " connected (" + ip + ")",{ fileName : "src/server/Main.hx", lineNumber : 196, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace("" + name + " connected (" + ip + ")",{ fileName : "src/server/Main.hx", lineNumber : 199, className : "server.Main", methodName : "onConnect"}); var client = new Client(ws,req,id,name,0); client.setGroupFlag(ClientGroup.Admin,req.connection.localAddress == ip); this.clients.push(client); @@ -1113,7 +1115,7 @@ server_Main.prototype = { var _g1 = 0; var _g2 = this.clients; while(_g1 < _g2.length) _g.push(_g2[_g1++].getData()); - this.send(client,{ type : "Connected", connected : { config : tmp, history : tmp1, isUnknownClient : true, clientName : client1, clients : _g, videoList : this.videoList, itemPos : this.itemPos, globalIp : this.globalIp}}); + this.send(client,{ type : "Connected", connected : { config : tmp, history : tmp1, isUnknownClient : true, clientName : client1, clients : _g, videoList : this.videoList, isPlaylistOpen : this.isPlaylistOpen, itemPos : this.itemPos, globalIp : this.globalIp}}); this.sendClientList(); ws.on("message",function(data) { var tmp2 = JSON.parse(data); @@ -1121,7 +1123,7 @@ server_Main.prototype = { return; }); ws.on("close",function(err) { - haxe_Log.trace("Client " + client.name + " disconnected",{ fileName : "src/server/Main.hx", lineNumber : 225, className : "server.Main", methodName : "onConnect"}); + haxe_Log.trace("Client " + client.name + " disconnected",{ fileName : "src/server/Main.hx", lineNumber : 229, className : "server.Main", methodName : "onConnect"}); server_Utils.sortedPush(_gthis.freeIds,client.id); HxOverrides.remove(_gthis.clients,client); _gthis.sendClientList(); @@ -1142,6 +1144,9 @@ server_Main.prototype = { ,onMessage: function(client,data) { switch(data.type) { case "AddVideo": + if((client.group & 4) == 0 && !this.isPlaylistOpen) { + return; + } var item = data.addVideo.item; item.author = client.name; var local = "" + this.localIp + ":" + this.port; @@ -1357,6 +1362,13 @@ server_Main.prototype = { _$VideoList_VideoList_$Impl_$.toggleItemType(this.videoList,data.toggleItemType.pos); this.broadcast(data); break; + case "TogglePlaylistLock": + if((client.group & 4) == 0) { + return; + } + this.isPlaylistOpen = !this.isPlaylistOpen; + this.broadcast({ type : "TogglePlaylistLock", togglePlaylistLock : { isOpen : this.isPlaylistOpen}}); + break; case "UpdateClients": this.sendClientList(); break; @@ -1568,9 +1580,9 @@ sys_FileSystem.createDirectory = function(path) { function $getIterator(o) { if( o instanceof Array ) return HxOverrides.iter(o); else return o.iterator(); } function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $global.$haxeUID++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = m.bind(o); o.hx__closures__[m.__id__] = f; } return f; } $global.$haxeUID |= 0; +var __map_reserved = {}; String.__name__ = true; Array.__name__ = true; -var __map_reserved = {}; Object.defineProperty(js__$Boot_HaxeError.prototype,"message",{ get : function() { return String(this.val); }}); diff --git a/res/client.js b/res/client.js index 14feb83..e4c084c 100644 --- a/res/client.js +++ b/res/client.js @@ -118,6 +118,25 @@ Lambda.exists = function(it,f) { } return false; }; +var haxe_ds_StringMap = function() { + this.h = { }; +}; +haxe_ds_StringMap.__name__ = true; +haxe_ds_StringMap.prototype = { + setReserved: function(key,value) { + if(this.rh == null) { + this.rh = { }; + } + this.rh["$" + key] = value; + } + ,getReserved: function(key) { + if(this.rh == null) { + return null; + } else { + return this.rh["$" + key]; + } + } +}; var Lang = function() { }; Lang.__name__ = true; Lang.request = function(path,callback) { @@ -440,15 +459,21 @@ client_Buttons.init = function(main) { extendPlayer.classList.toggle("active"); return window.dispatchEvent(new Event("resize")); }; - window.document.querySelector("#mediarefresh").onclick = function(e5) { + window.document.querySelector("#togglesynch").onclick = function(e5) { + if(!window.confirm(Lang.get("toggleSynchConfirm"))) { + return; + } + return; + }; + window.document.querySelector("#mediarefresh").onclick = function(e6) { main.refreshPlayer(); return; }; - window.document.querySelector("#fullscreenbtn").onclick = function(e6) { + window.document.querySelector("#fullscreenbtn").onclick = function(e7) { return client_Utils.toggleFullScreen(window.document.querySelector("#ytapiplayer")); }; var getPlaylist = window.document.querySelector("#getplaylist"); - getPlaylist.onclick = function(e7) { + getPlaylist.onclick = function(e8) { client_Utils.copyToClipboard(main.getPlaylistLinks().join(",")); var icon = getPlaylist.firstElementChild; icon.classList.remove("glyphicon-link"); @@ -459,21 +484,27 @@ client_Buttons.init = function(main) { return; },2000); }; - window.document.querySelector("#clearplaylist").onclick = function(e8) { + window.document.querySelector("#clearplaylist").onclick = function(e9) { if(!window.confirm(Lang.get("clearPlaylistConfirm"))) { return; } main.send({ type : "ClearPlaylist"}); return; }; - window.document.querySelector("#shuffleplaylist").onclick = function(e9) { + window.document.querySelector("#shuffleplaylist").onclick = function(e10) { if(!window.confirm(Lang.get("shufflePlaylistConfirm"))) { return; } main.send({ type : "ShufflePlaylist"}); return; }; - window.document.querySelector("#showmediaurl").onclick = function(e10) { + window.document.querySelector("#lockplaylist").onclick = function(e11) { + if((main.personal.group & 4) != 0) { + main.send({ type : "TogglePlaylistLock"}); + } + return; + }; + window.document.querySelector("#showmediaurl").onclick = function(e12) { window.document.querySelector("#showmediaurl").classList.toggle("collapsed"); window.document.querySelector("#showmediaurl").classList.toggle("active"); return window.document.querySelector("#addfromurl").classList.toggle("collapse"); @@ -936,6 +967,9 @@ client_Main.prototype = { case "ToggleItemType": this.player.toggleItemType(data.toggleItemType.pos); break; + case "TogglePlaylistLock": + this.setPlaylistLock(data.togglePlaylistLock.isOpen); + break; case "UpdateClients": this.updateClients(data.updateClients.clients); this.personal = ClientTools.getByName(this.clients,this.personal.name,this.personal); @@ -967,6 +1001,7 @@ client_Main.prototype = { } else { this.guestLogin(guestName.value); } + this.setPlaylistLock(connected.isPlaylistOpen); this.clearChat(); this.serverMessage(1); var _g = 0; @@ -1018,8 +1053,9 @@ client_Main.prototype = { } var smilesWrap = window.document.querySelector("#smileswrap"); smilesWrap.onclick = function(e) { + var el = e.target; var form = window.document.querySelector("#chatline"); - form.value += " " + e.target.title; + form.value += " " + el.title; form.focus(); return; }; @@ -1200,6 +1236,23 @@ client_Main.prototype = { leaderBtn.classList.remove("label-success"); } } + ,setPlaylistLock: function(isOpen) { + var lockPlaylist = window.document.querySelector("#lockplaylist"); + var icon = lockPlaylist.firstElementChild; + if(isOpen) { + lockPlaylist.title = Lang.get("playlistOpen"); + lockPlaylist.classList.add("btn-success"); + lockPlaylist.classList.remove("btn-danger"); + icon.classList.add("glyphicon-ok"); + icon.classList.remove("glyphicon-lock"); + } else { + lockPlaylist.title = Lang.get("playlistLocked"); + lockPlaylist.classList.add("btn-danger"); + lockPlaylist.classList.remove("btn-success"); + icon.classList.add("glyphicon-lock"); + icon.classList.remove("glyphicon-ok"); + } + } ,escapeRegExp: function(regex) { var _this_r = new RegExp("([.*+?^${}()|[\\]\\\\])","g".split("u").join("")); return regex.replace(_this_r,"\\$1"); @@ -2009,25 +2062,6 @@ haxe_crypto_Sha256.prototype = { return str.toLowerCase(); } }; -var haxe_ds_StringMap = function() { - this.h = { }; -}; -haxe_ds_StringMap.__name__ = true; -haxe_ds_StringMap.prototype = { - setReserved: function(key,value) { - if(this.rh == null) { - this.rh = { }; - } - this.rh["$" + key] = value; - } - ,getReserved: function(key) { - if(this.rh == null) { - return null; - } else { - return this.rh["$" + key]; - } - } -}; var haxe_http_HttpBase = function(url) { this.url = url; this.headers = []; @@ -2464,10 +2498,10 @@ js_youtube_Youtube.init = function(onAPIReady) { function $getIterator(o) { if( o instanceof Array ) return HxOverrides.iter(o); else return o.iterator(); } function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $global.$haxeUID++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = m.bind(o); o.hx__closures__[m.__id__] = f; } return f; } $global.$haxeUID |= 0; +var __map_reserved = {}; if( String.fromCodePoint == null ) String.fromCodePoint = function(c) { return c < 0x10000 ? String.fromCharCode(c) : String.fromCharCode((c>>10)+0xD7C0)+String.fromCharCode((c&0x3FF)+0xDC00); } String.__name__ = true; Array.__name__ = true; -var __map_reserved = {}; Object.defineProperty(js__$Boot_HaxeError.prototype,"message",{ get : function() { return String(this.val); }}); diff --git a/res/index.html b/res/index.html index 049600f..ca6c679 100644 --- a/res/index.html +++ b/res/index.html @@ -94,7 +94,7 @@ <button class="btn btn-sm btn-default collapsed" id="showcustomembed" title="${embedCustomFrame}" data-toggle="collapse" data-target="#customembed" aria-expanded="false"><span class="glyphicon glyphicon-th-large"></span></button> <button class="btn btn-sm btn-default" id="clearplaylist" title="${clearPlaylist}"><span class="glyphicon glyphicon-trash"></span></button> <button class="btn btn-sm btn-default" id="shuffleplaylist" title="${shufflePlaylist}"><span class="glyphicon glyphicon-sort"></span></button> - <button class="btn btn-sm btn-danger" id="qlockbtn" title="${playlistLocked}"><span class="glyphicon glyphicon-lock"></span></button> + <button class="btn btn-sm btn-success" id="lockplaylist" title="${playlistOpen}"><span class="glyphicon glyphicon-ok"></span></button> </div> <div class="btn-group pull-right" id="videocontrols"> <button class="btn btn-sm btn-default" id="extendplayer" title="${expandPlayer}"><span class="glyphicon glyphicon-sound-stereo"></span></button> diff --git a/src/Types.hx b/src/Types.hx index 49e93e4..50e38c3 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -64,6 +64,7 @@ typedef WsEvent = { isUnknownClient:Bool, clientName:String, videoList:Array<VideoItem>, + isPlaylistOpen:Bool, itemPos:Int, globalIp:String }, @@ -125,6 +126,9 @@ typedef WsEvent = { }, ?updatePlaylist:{ videoList:Array<VideoItem> + }, + ?togglePlaylistLock:{ + isOpen:Bool } } @@ -155,4 +159,5 @@ enum abstract WsEventType(String) { var ClearPlaylist; var ShufflePlaylist; var UpdatePlaylist; + var TogglePlaylistLock; } diff --git a/src/client/Buttons.hx b/src/client/Buttons.hx index e567331..d50773d 100644 --- a/src/client/Buttons.hx +++ b/src/client/Buttons.hx @@ -109,6 +109,10 @@ class Buttons { if (!window.confirm(Lang.get("shufflePlaylistConfirm"))) return; main.send({type: ShufflePlaylist}); } + final lockPlaylist = ge("#lockplaylist"); + lockPlaylist.onclick = e -> { + if (main.isAdmin()) main.send({type: TogglePlaylistLock}); + } final showMediaUrl = ge("#showmediaurl"); showMediaUrl.onclick = e -> { diff --git a/src/client/Main.hx b/src/client/Main.hx index 9d383bc..bb3a738 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -314,6 +314,9 @@ class Main { case ShufflePlaylist: // server-only case UpdatePlaylist: player.setItems(data.updatePlaylist.videoList); + + case TogglePlaylistLock: + setPlaylistLock(data.togglePlaylistLock.isOpen); } } @@ -335,6 +338,7 @@ class Main { } else { guestLogin(guestName.value); } + setPlaylistLock(connected.isPlaylistOpen); clearChat(); serverMessage(1); for (message in connected.history) { @@ -560,7 +564,27 @@ class Main { final leaderBtn = ge("#leader_btn"); if (isLeader()) { leaderBtn.classList.add("label-success"); - } else leaderBtn.classList.remove("label-success"); + } else { + leaderBtn.classList.remove("label-success"); + } + } + + function setPlaylistLock(isOpen:Bool):Void { + final lockPlaylist = ge("#lockplaylist"); + final icon = lockPlaylist.firstElementChild; + if (isOpen) { + lockPlaylist.title = Lang.get("playlistOpen"); + lockPlaylist.classList.add("btn-success"); + lockPlaylist.classList.remove("btn-danger"); + icon.classList.add("glyphicon-ok"); + icon.classList.remove("glyphicon-lock"); + } else { + lockPlaylist.title = Lang.get("playlistLocked"); + lockPlaylist.classList.add("btn-danger"); + lockPlaylist.classList.remove("btn-success"); + icon.classList.add("glyphicon-lock"); + icon.classList.remove("glyphicon-ok"); + } } function escapeRegExp(regex:String):String { diff --git a/src/server/Main.hx b/src/server/Main.hx index 424f22f..4ecc25a 100644 --- a/src/server/Main.hx +++ b/src/server/Main.hx @@ -34,6 +34,7 @@ class Main { final videoList = new VideoList(); final videoTimer = new VideoTimer(); final messages:Array<Message> = []; + var isPlaylistOpen = true; var itemPos = 0; static function main():Void new Main(); @@ -131,6 +132,7 @@ class Main { trace("Saving state..."); final data:ServerState = { videoList: videoList, + isPlaylistOpen: isPlaylistOpen, itemPos: itemPos, messages: messages, timer: { @@ -149,6 +151,7 @@ class Main { videoList.resize(0); messages.resize(0); for (item in data.videoList) videoList.push(item); + isPlaylistOpen = data.isPlaylistOpen; itemPos = data.itemPos; for (message in data.messages) messages.push(message); videoTimer.start(); @@ -212,6 +215,7 @@ class Main { for (client in clients) client.getData() ], videoList: videoList, + isPlaylistOpen: isPlaylistOpen, itemPos: itemPos, globalIp: globalIp } @@ -307,6 +311,7 @@ class Main { broadcast(data); case AddVideo: + if (!client.isAdmin && !isPlaylistOpen) return; final item = data.addVideo.item; item.author = client.name; final local = '$localIp:$port'; @@ -448,6 +453,16 @@ class Main { videoList: videoList }}); case UpdatePlaylist: // client-only + + case TogglePlaylistLock: + if (!client.isAdmin) return; + isPlaylistOpen = !isPlaylistOpen; + broadcast({ + type: TogglePlaylistLock, + togglePlaylistLock: { + isOpen: isPlaylistOpen + } + }); } } diff --git a/src/server/ServerState.hx b/src/server/ServerState.hx index 02cdc40..9c8d751 100644 --- a/src/server/ServerState.hx +++ b/src/server/ServerState.hx @@ -5,6 +5,7 @@ import Types.VideoItem; typedef ServerState = { videoList:Array<VideoItem>, + isPlaylistOpen:Bool, itemPos:Int, messages:Array<Message>, timer:{ |
