Implement polls
This commit is contained in:
parent
741fe8e21f
commit
bc187c99f5
23
channel.js
23
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++) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
37
poll.js
Normal file
37
poll.js
Normal file
|
@ -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;
|
1
rank.js
1
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,
|
||||
};
|
||||
|
|
16
user.js
16
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);
|
||||
|
|
|
@ -91,3 +91,7 @@
|
|||
.greentext {
|
||||
color: #789922; /* Color value directly from 4chan */
|
||||
}
|
||||
|
||||
.option button {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
$('<button/>').addClass('btn btn-danger pull-right').text('Close Poll')
|
||||
.insertAfter(poll.find('.close'))
|
||||
.click(function() {
|
||||
socket.emit('closePoll')
|
||||
});
|
||||
}
|
||||
}
|
||||
RANK = data.rank;
|
||||
});
|
||||
|
@ -232,4 +240,16 @@ function initCallbacks() {
|
|||
$(li).appendTo(ul);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('newPoll', function(data) {
|
||||
addPoll(data);
|
||||
});
|
||||
|
||||
socket.on('updatePoll', function(data) {
|
||||
updatePoll(data);
|
||||
});
|
||||
|
||||
socket.on('closePoll', function() {
|
||||
closePoll();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -420,5 +420,57 @@ function parseVimeo(url) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function closePoll() {
|
||||
if($('#pollcontainer .active').length != 0) {
|
||||
var poll = $('#pollcontainer .active');
|
||||
poll.removeClass("active").addClass("muted");
|
||||
poll.find('.option button').each(function() {
|
||||
$(this).attr('disabled', 'disabled');
|
||||
});
|
||||
poll.find('.btn-danger').each(function() {
|
||||
$(this).remove()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addPoll(data) {
|
||||
closePoll();
|
||||
var poll = $('<div/>').addClass('well active').prependTo($('#pollcontainer'));
|
||||
$('<button/>').addClass('close pull-right').text('×')
|
||||
.appendTo(poll)
|
||||
.click(function() { poll.remove(); });
|
||||
if(RANK >= Rank.Moderator) {
|
||||
$('<button/>').addClass('btn btn-danger pull-right').text('Close Poll')
|
||||
.appendTo(poll)
|
||||
.click(function() {
|
||||
socket.emit('closePoll')
|
||||
});
|
||||
}
|
||||
|
||||
$('<h3/>').text(data.title).appendTo(poll);
|
||||
for(var i = 0; i < data.options.length; i++) {
|
||||
var callback = (function(i) { return function() {
|
||||
console.log(i);
|
||||
socket.emit('vote', {
|
||||
option: i
|
||||
});
|
||||
poll.find('.option button').each(function() {
|
||||
$(this).attr('disabled', 'disabled');
|
||||
});
|
||||
} })(i);
|
||||
$('<button/>').addClass('btn').text(data.counts[i])
|
||||
.prependTo($('<div/>').addClass('option').text(data.options[i])
|
||||
.appendTo(poll))
|
||||
.click(callback);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function updatePoll(data) {
|
||||
var poll = $('#pollcontainer .active');
|
||||
var i = 0;
|
||||
poll.find('.option button').each(function() {
|
||||
$(this).text(data.counts[i]);
|
||||
i++;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -67,6 +67,10 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 50px;">
|
||||
<div class="span6" id="pollcontainer">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 50px;">
|
||||
<div class="span6">
|
||||
<div id="playlist_controls" style="display: none;">
|
||||
|
|
Loading…
Reference in a new issue