diff --git a/channel.js b/channel.js index 9350053e..13008196 100644 --- a/channel.js +++ b/channel.js @@ -208,13 +208,13 @@ Channel.prototype.loadDump = function() { if(f[0] != undefined) { var filt = new Filter("", f[0], "g", f[1]); filt.active = f[2]; - this.updateFilter(filt); + this.updateFilter(filt, false); } else { var filt = new Filter(f.name, f.source, f.flags, f.replace); filt.active = f.active; filt.filterlinks = f.filterlinks; - this.updateFilter(filt); + this.updateFilter(filt, false); } } this.broadcastChatFilters(); @@ -1186,15 +1186,35 @@ Channel.prototype.tryQueue = function(user, data) { } if(data.list) - this.enqueueList(data, user); + this.addMediaList(data, user); else this.addMedia(data, user); } -Channel.prototype.addMedia = function(data, user, callback) { - // TODO fix caching +Channel.prototype.addMedia = function(data, user) { + data.temp = isLive(data.type) || !this.hasPermission(user, "addnontemp"); + data.queueby = user ? user.name : ""; + var chan = this; if(data.id in this.library) { - data.type = this.library[data.id].type; + var m = this.library[data.id].dup(); + data.media = m; + this.playlist.addCachedMedia(data, function (err, item) { + if(err) { + if(err === true) + err = false; + if(user) + user.socket.emit("queueFail", err); + return; + } + else { + chan.sendAll("queue", { + item: item.pack(), + after: item.prev ? item.prev.uid : "prepend" + }); + chan.broadcastPlaylistMeta(); + chan.cacheMedia(item.media); + } + }); } if(isLive(data.type) && !this.hasPermission(user, "playlistaddlive")) { user.socket.emit("queueFail", "You don't have permission to queue livestreams"); @@ -1204,11 +1224,8 @@ Channel.prototype.addMedia = function(data, user, callback) { data.temp = isLive(data.type) || !this.hasPermission(user, "addnontemp"); data.queueby = user ? user.name : ""; - var chan = this; this.playlist.addMedia(data, function(err, item) { if(err) { - if(callback) - callback(false); if(err === true) err = false; if(user) @@ -1222,13 +1239,11 @@ Channel.prototype.addMedia = function(data, user, callback) { }); chan.broadcastPlaylistMeta(); chan.cacheMedia(item.media); - if(callback) - callback(true); } }); } -Channel.prototype.enqueueList = function(data, user) { +Channel.prototype.addMediaList = function(data, user) { var pl = data.list; var chan = this; this.playlist.addMediaList(data, function(err, item) { @@ -1266,7 +1281,7 @@ Channel.prototype.tryQueuePlaylist = function(user, data) { var pl = Database.loadUserPlaylist(user.name, data.name); data.list = pl; - this.enqueueList(data, user); + this.addMediaList(data, user); } Channel.prototype.setTemp = function(uid, temp) { @@ -1374,18 +1389,20 @@ Channel.prototype.tryClearqueue = function(user) { Channel.prototype.shufflequeue = function() { var n = []; - var pl = this.playlist.items.toArray(); - var current = pl.current; + var pl = this.playlist.items.toArray(false); + this.playlist.clear(); while(pl.length > 0) { var i = parseInt(Math.random() * pl.length); - n.push(pl[i]); + var item = this.playlist.makeItem(pl[i].media); + item.temp = pl[i].temp; + item.queueby = pl[i].queueby; + this.playlist.items.append(item); pl.splice(i, 1); } - // TODO fix - this.playlist.current = this.playlist.last; - this.playNext(); + this.playlist.current = this.playlist.items.first; this.sendAll("playlist", this.playlist.items.toArray()); this.sendAll("setPlaylistMeta", this.plmeta); + this.playlist.startPlayback(); } Channel.prototype.tryShufflequeue = function(user) { @@ -1551,7 +1568,7 @@ Channel.prototype.removeFilter = function(filter) { this.broadcastChatFilters(); } -Channel.prototype.updateFilter = function(filter) { +Channel.prototype.updateFilter = function(filter, emit) { if(filter.name == "") filter.name = filter.source; var found = false; @@ -1565,7 +1582,8 @@ Channel.prototype.updateFilter = function(filter) { if(!found) { this.filters.push(filter); } - this.broadcastChatFilters(); + if(emit !== false) + this.broadcastChatFilters(); } Channel.prototype.tryUpdateFilter = function(user, f) { diff --git a/playlist.js b/playlist.js index 1e0005d8..bc618203 100644 --- a/playlist.js +++ b/playlist.js @@ -1,4 +1,4 @@ -var ULList = require("./ullist").ULList; +ULList = require("./ullist").ULList; var Media = require("./media").Media; var InfoGetter = require("./get-info"); @@ -33,7 +33,7 @@ function Playlist(chan) { "remove": [], }; this.lock = false; - this.alter_queue = []; + this.action_queue = []; this._qaInterval = false; if(chan) { @@ -54,25 +54,23 @@ function Playlist(chan) { } Playlist.prototype.queueAction = function(data) { - this.alter_queue.push(data); + this.action_queue.push(data); if(this._qaInterval) return; var pl = this; this._qaInterval = setInterval(function() { - if(!pl.lock) { - var data = pl.alter_queue.shift(); - if(data.waiting) { - if(!("expire" in data)) - data.expire = Date.now() + 5000; - if(Date.now() < data.expire) - pl.alter_queue.unshift(data); - return; - } + var data = pl.action_queue.shift(); + if(data.waiting) { + if(!("expire" in data)) + data.expire = Date.now() + 10000; + if(Date.now() < data.expire) + pl.action_queue.unshift(data); + } + else data.fn(); - if(pl.alter_queue.length == 0) { - clearInterval(pl._qaInterval); - pl._qaInterval = false; - } + if(pl.action_queue.length == 0) { + clearInterval(pl._qaInterval); + pl._qaInterval = false; } }, 100); } @@ -159,6 +157,31 @@ Playlist.prototype.add = function(item, pos) { return success; } +Playlist.prototype.addCachedMedia = function(data, callback) { + var pos = "append"; + if(data.pos == "next") { + if(!this.current) + pos = "prepend"; + else + pos = this.current.uid; + } + + var it = this.makeItem(data.media); + it.temp = data.temp; + it.queueby = data.queueby; + + var pl = this; + + var action = { + fn: function() { + if(pl.add(it, pos)) + callback(false, it); + }, + waiting: false + }; + this.queueAction(action); +} + Playlist.prototype.addMedia = function(data, callback) { if(data.type == "yp") { @@ -178,8 +201,9 @@ Playlist.prototype.addMedia = function(data, callback) { var pl = this; var action = { fn: function() { - if(pl.add(it, pos)) + if(pl.add(it, pos)) { callback(false, it); + } }, waiting: true }; @@ -200,13 +224,30 @@ Playlist.prototype.addMedia = function(data, callback) { } Playlist.prototype.addMediaList = function(data, callback) { - if(data.pos == "next") + var start = false; + if(data.pos == "next") { data.list = data.list.reverse(); + start = data.list[data.list.length - 1]; + } var pl = this; data.list.forEach(function(x) { x.pos = data.pos; - pl.addMedia(x, callback); + if(start && x == start) { + pl.addMedia(x, function (err, item) { + if(err) { + callback(err, item); + } + else { + callback(err, item); + pl.current = item; + pl.startPlayback(); + } + }); + } + else { + pl.addMedia(x, callback); + } }); } @@ -333,7 +374,10 @@ Playlist.prototype.jump = function(uid) { } if(it.temp) { - this.remove(it.uid); + var pl = this; + this.remove(it.uid, function () { + pl.on("remove")(it); + }); } return this.current; @@ -342,6 +386,7 @@ Playlist.prototype.jump = function(uid) { Playlist.prototype.clear = function() { this.items.clear(); this.next_uid = 0; + this.current = null; clearInterval(this._leadInterval); } diff --git a/ullist.js b/ullist.js index 087114e9..1af00537 100644 --- a/ullist.js +++ b/ullist.js @@ -136,12 +136,12 @@ ULList.prototype.clear = function() { } /* Dump the contents of the list into an array */ -ULList.prototype.toArray = function() { +ULList.prototype.toArray = function(pack) { var arr = new Array(this.length); var item = this.first; var i = 0; while(item !== null) { - if(typeof item.pack == "function") + if(pack !== false && typeof item.pack == "function") arr[i++] = item.pack(); else arr[i++] = item; diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js index 1426b1d9..32d60c4c 100644 --- a/www/assets/js/callbacks.js +++ b/www/assets/js/callbacks.js @@ -749,9 +749,7 @@ Callbacks = { } li.addClass("queue_active"); - $("#queue").scrollTop(0); - var scroll = li.position().top - $("#queue").position().top; - $("#queue").scrollTop(scroll); + scrollQueue(); return true; }, can_wait: true diff --git a/www/assets/js/util.js b/www/assets/js/util.js index 3dac7085..85a5ff38 100644 --- a/www/assets/js/util.js +++ b/www/assets/js/util.js @@ -204,6 +204,17 @@ function addUserDropdown(entry, name) { /* queue stuff */ +function scrollQueue() { + var li = playlistFind(PL_CURRENT); + if(!li) + return; + + li = $(li); + $("#queue").scrollTop(0); + var scroll = li.position().top - $("#queue").position().top; + $("#queue").scrollTop(scroll); +} + function makeQueueEntry(item, addbtns) { var video = item.media; var li = $("
");