diff --git a/channel.js b/channel.js index fa74831c..3fa8797f 100644 --- a/channel.js +++ b/channel.js @@ -20,6 +20,7 @@ var ChatCommand = require("./chatcommand.js"); var Server = require("./server.js"); var io = Server.io; var Logger = require("./logger.js"); +var Poll = require("./poll.js").Poll; var Channel = function(name) { Logger.syslog.log("Opening channel " + name); @@ -34,11 +35,13 @@ var Channel = function(name) { this.recentChat = []; this.qlocked = true; this.poll = false; + this.voteskip = false; this.opts = { qopen_allow_qnext: false, qopen_allow_move: false, qopen_allow_playnext: false, qopen_allow_delete: false, + allow_voteskip: true, pagetitle: "Sync", customcss: "" }; @@ -685,6 +688,7 @@ Channel.prototype.playNext = function() { if(this.queue.length == 0) return; var old = this.currentPosition; + this.voteskip = false; if(this.currentPosition + 1 >= this.queue.length) { this.currentPosition = -1; } @@ -709,6 +713,7 @@ Channel.prototype.jumpTo = function(pos) { return; if(pos >= this.queue.length || pos < 0) return; + this.voteskip = false; var old = this.currentPosition; this.currentPosition = pos; this.currentMedia = this.queue[this.currentPosition]; @@ -1064,6 +1069,16 @@ Channel.prototype.broadcastMotd = function() { this.sendAll("updateMotd", this.motd); } +Channel.prototype.handleVoteskip = function(user) { + if(!this.voteskip) { + this.voteskip = new Poll("voteskip", "voteskip", ["yes"]); + } + this.voteskip.vote(user.ip, 0); + if(this.voteskip.counts[0] > this.users.length / 2) { + this.playNext(); + } +} + // Send to ALL the clients! Channel.prototype.sendAll = function(message, data) { io.sockets.in(this.name).emit(message, data); diff --git a/user.js b/user.js index 4d13fee6..07a8cf6a 100644 --- a/user.js +++ b/user.js @@ -274,6 +274,12 @@ User.prototype.initCallbacks = function() { } } }.bind(this)); + + this.socket.on("voteskip", function(data) { + if(this.channel != null) { + this.channel.handleVoteskip(this); + } + }.bind(this)); } // Handle administration diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js index 2ad1edf6..6193c201 100644 --- a/www/assets/js/callbacks.js +++ b/www/assets/js/callbacks.js @@ -90,6 +90,7 @@ function initCallbacks() { .attr("id", "customCss") .insertAfter($("link[href='./assets/css/ytsync.css']")); } + $("#opt_allow_voteskip").prop("checked", opts.allow_voteskip); CHANNELOPTS = opts; if(opts.qopen_allow_qnext) @@ -98,6 +99,11 @@ function initCallbacks() { $("#play_next").attr("disabled", false); else if(RANK < Rank.Moderator && !LEADER) $("#play_next").attr("disabled", true); + + if(opts.allow_voteskip) + $("#voteskip").attr("disabled", false); + else + $("#voteskip").attr("disabled", true); rebuildPlaylist(); }); @@ -195,6 +201,7 @@ function initCallbacks() { var linew = $("#queue").children()[data.idx]; $(linew).addClass("alert alert-info"); POSITION = data.idx; + $("#voteskip").attr("disabled", false); }); socket.on("mediaUpdate", function(data) { diff --git a/www/assets/js/client.js b/www/assets/js/client.js index f67a345a..9d6bc0d0 100644 --- a/www/assets/js/client.js +++ b/www/assets/js/client.js @@ -157,6 +157,11 @@ $("#play_next").click(function() { socket.emit("playNext"); }); +$("#voteskip").click(function() { + socket.emit("voteskip"); + $("#voteskip").attr("disabled", true); +}); + $("#qlockbtn").click(function() { socket.emit("queueLock", { locked: OPENQUEUE @@ -272,6 +277,7 @@ $("#opt_submit").click(function() { qopen_allow_move: $("#opt_qopen_allow_move").prop("checked"), qopen_allow_delete: $("#opt_qopen_allow_delete").prop("checked"), qopen_allow_playnext: $("#opt_qopen_allow_playnext").prop("checked"), + allow_voteskip: $("#opt_allow_voteskip").prop("checked"), pagetitle: ptitle, customcss: css }; diff --git a/www/index.html b/www/index.html index 2882da0e..309ad6f2 100644 --- a/www/index.html +++ b/www/index.html @@ -80,8 +80,9 @@ - + +