From bc187c99f50dd4e5ddbb9b7a7f383a844baa400e Mon Sep 17 00:00:00 2001 From: calzoneman Date: Sat, 16 Mar 2013 16:49:58 -0500 Subject: [PATCH] Implement polls --- channel.js | 23 +++++++++++++++++ chatcommand.js | 15 +++++++++++ poll.js | 37 +++++++++++++++++++++++++++ rank.js | 1 + user.js | 16 ++++++++++++ www/assets/css/ytsync.css | 4 +++ www/assets/js/callbacks.js | 20 +++++++++++++++ www/assets/js/functions.js | 52 ++++++++++++++++++++++++++++++++++++++ www/index.html | 4 +++ 9 files changed, 172 insertions(+) create mode 100644 poll.js diff --git a/channel.js b/channel.js index 94ba72b5..cf834d86 100644 --- a/channel.js +++ b/channel.js @@ -26,6 +26,7 @@ var Channel = function(name) { this.leader = null; this.recentChat = []; this.qlocked = true; + this.poll = false; this.loadMysql(); }; @@ -215,6 +216,9 @@ Channel.prototype.userJoin = function(user) { user.socket.emit('queueLock', {locked: this.qlocked}); this.sendUserlist(user); this.sendRecentChat(user); + if(this.poll) { + user.socket.emit('newPoll', this.poll.packUpdate()); + } if(user.playerReady) this.sendMediaUpdate(user); console.log(user.ip + " joined channel " + this.name); @@ -222,6 +226,13 @@ Channel.prototype.userJoin = function(user) { // Called when a user leaves the channel Channel.prototype.userLeave = function(user) { + if(this.poll) { + this.poll.unvote(user.ip); + this.broadcastPollUpdate(); + } + if(this.leader == user) { + this.changeLeader(""); + } this.users.splice(this.users.indexOf(user), 1); this.updateUsercount(); if(user.name != "") { @@ -564,6 +575,18 @@ Channel.prototype.broadcastRankUpdate = function(user) { }); } +Channel.prototype.broadcastPoll = function() { + this.sendAll('newPoll', this.poll.packUpdate()); +} + +Channel.prototype.broadcastPollUpdate = function() { + this.sendAll('updatePoll', this.poll.packUpdate()); +} + +Channel.prototype.broadcastPollClose = function() { + this.sendAll('closePoll'); +} + // Send to ALL the clients! Channel.prototype.sendAll = function(message, data) { for(var i = 0; i < this.users.length; i++) { diff --git a/chatcommand.js b/chatcommand.js index 9b1d3683..50d96dea 100644 --- a/chatcommand.js +++ b/chatcommand.js @@ -1,4 +1,5 @@ var Rank = require('./rank.js'); +var Poll = require('./poll.js').Poll; function handle(chan, user, msg) { if(msg.indexOf("/me ") == 0) @@ -8,6 +9,9 @@ function handle(chan, user, msg) { else if(msg.indexOf("/kick ") == 0) { handleKick(chan, user, msg.substring(6).split(' ')); } + else if(msg.indexOf("/poll ") == 0) { + handlePoll(chan, user, msg.substring(6)); + } } function handleKick(chan, user, args) { @@ -26,5 +30,16 @@ function handleKick(chan, user, args) { } } +function handlePoll(chan, user, msg) { + if(Rank.hasPermission(user, "poll")) { + var args = msg.split(','); + var title = args[0]; + args.splice(0, 1); + var poll = new Poll(title, args); + chan.poll = poll; + chan.broadcastPoll(); + } +} + exports.handle = handle; diff --git a/poll.js b/poll.js new file mode 100644 index 00000000..ded3e7ce --- /dev/null +++ b/poll.js @@ -0,0 +1,37 @@ + +var Poll = function(title, options) { + this.title = title; + this.options = options; + this.counts = new Array(options.length); + for(var i = 0; i < this.counts.length; i++) { + this.counts[i] = 0; + } + this.votes = {}; +} + +Poll.prototype.vote = function(ip, option) { + if(!(ip in this.votes) || this.votes[ip] == null) { + this.votes[ip] = option; + this.counts[option]++; + } + console.log(this.votes); +} + +Poll.prototype.unvote = function(ip) { + console.log('unvote ' + ip + this.votes[ip]); + if(ip in this.votes && this.votes[ip] != null) { + this.counts[this.votes[ip]]--; + this.votes[ip] = null; + } + console.log(this.votes); +} + +Poll.prototype.packUpdate = function() { + return { + title: this.title, + options: this.options, + counts: this.counts + } +} + +exports.Poll = Poll; diff --git a/rank.js b/rank.js index 82583df2..6f4ace93 100644 --- a/rank.js +++ b/rank.js @@ -19,6 +19,7 @@ var permissions = { kick: exports.Moderator, promote: exports.Moderator, qlock: exports.Moderator, + poll: exports.Moderator, search: exports.Guest, chat: exports.Guest, }; diff --git a/user.js b/user.js index 8b83c3ab..d42c450b 100644 --- a/user.js +++ b/user.js @@ -149,6 +149,22 @@ User.prototype.initCallbacks = function() { } }.bind(this)); + this.socket.on('closePoll', function() { + if(Rank.hasPermission(this, "poll")) { + if(this.channel != null && this.channel.poll) { + this.channel.poll = null; + this.channel.broadcastPollClose(); + } + } + }.bind(this)); + + this.socket.on('vote', function(data) { + if(this.channel != null && this.channel.poll) { + this.channel.poll.vote(this.ip, data.option); + this.channel.broadcastPollUpdate(); + } + }.bind(this)); + this.socket.on('adm', function(data) { if(Rank.hasPermission(this, "acp")) { this.handleAdm(data); diff --git a/www/assets/css/ytsync.css b/www/assets/css/ytsync.css index c8c9731b..9846e2b8 100644 --- a/www/assets/css/ytsync.css +++ b/www/assets/css/ytsync.css @@ -91,3 +91,7 @@ .greentext { color: #789922; /* Color value directly from 4chan */ } + +.option button { + margin-right: 15px; +} diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js index 0826d6b4..7518703d 100644 --- a/www/assets/js/callbacks.js +++ b/www/assets/js/callbacks.js @@ -19,6 +19,14 @@ function initCallbacks() { if(data.rank >= Rank.Moderator) { $('#playlist_controls').css("display", "block"); $('#qlockbtn').css("display", "block"); + var poll = $('#pollcontainer .active'); + if(poll.length > 0) { + $('