Add poll notification, channel options (don't save to db yet)

This commit is contained in:
calzoneman 2013-03-22 15:04:04 -05:00
parent bbfa4ba53d
commit bf72733086
10 changed files with 178 additions and 25 deletions

View file

@ -28,6 +28,14 @@ var Channel = function(name) {
this.recentChat = []; this.recentChat = [];
this.qlocked = true; this.qlocked = true;
this.poll = false; this.poll = false;
this.opts = {
qopen_allow_qnext: false,
qopen_allow_move: false,
qopen_allow_playnext: false,
qopen_allow_delete: false,
pagetitle: "Sync",
bgimage: ""
};
// Autolead stuff // Autolead stuff
// Accumulator // Accumulator
@ -289,6 +297,7 @@ Channel.prototype.userJoin = function(user) {
if(this.poll) { if(this.poll) {
user.socket.emit('newPoll', this.poll.packUpdate()); user.socket.emit('newPoll', this.poll.packUpdate());
} }
user.socket.emit('channelOpts', this.opts);
if(user.playerReady) if(user.playerReady)
this.sendMediaUpdate(user); this.sendMediaUpdate(user);
console.log("/" + user.ip + " joined channel " + this.name); console.log("/" + user.ip + " joined channel " + this.name);
@ -682,6 +691,10 @@ Channel.prototype.broadcastPollClose = function() {
this.sendAll('closePoll'); this.sendAll('closePoll');
} }
Channel.prototype.broadcastOpts = function() {
this.sendAll('channelOpts', this.opts);
}
// Send to ALL the clients! // Send to ALL the clients!
Channel.prototype.sendAll = function(message, data) { Channel.prototype.sendAll = function(message, data) {
io.sockets.in(this.name).emit(message, data); io.sockets.in(this.name).emit(message, data);

View file

@ -40,7 +40,7 @@ function handlePoll(chan, user, msg) {
var args = msg.split(','); var args = msg.split(',');
var title = args[0]; var title = args[0];
args.splice(0, 1); args.splice(0, 1);
var poll = new Poll(title, args); var poll = new Poll(user.name, title, args);
chan.poll = poll; chan.poll = poll;
chan.broadcastPoll(); chan.broadcastPoll();
} }

View file

@ -1,5 +1,6 @@
var Poll = function(title, options) { var Poll = function(initiator, title, options) {
this.initiator = initiator;
this.title = title; this.title = title;
this.options = options; this.options = options;
this.counts = new Array(options.length); this.counts = new Array(options.length);
@ -30,7 +31,8 @@ Poll.prototype.packUpdate = function() {
return { return {
title: this.title, title: this.title,
options: this.options, options: this.options,
counts: this.counts counts: this.counts,
initiator: this.initiator
} }
} }

View file

@ -23,6 +23,7 @@ var permissions = {
qlock : exports.Moderator, qlock : exports.Moderator,
poll : exports.Moderator, poll : exports.Moderator,
shout : exports.Moderator, shout : exports.Moderator,
channelOpts : exports.Moderator,
search : exports.Guest, search : exports.Guest,
chat : exports.Guest, chat : exports.Guest,
}; };

37
user.js
View file

@ -99,30 +99,46 @@ User.prototype.initCallbacks = function() {
}.bind(this)); }.bind(this));
this.socket.on('queue', function(data) { this.socket.on('queue', function(data) {
if(this.channel == null)
return;
if(Rank.hasPermission(this, "queue") || if(Rank.hasPermission(this, "queue") ||
(this.channel != null && !this.channel.qlocked)) { this.channel.leader == this ||
if(this.channel != null) !this.channel.qlocked) {
if(data.pos == "next" &&
!this.channel.qopts_allow_qnext &&
this.channel.leader != this &&
!Rank.hasPermission(this, "queue"))
return;
this.channel.enqueue(data); this.channel.enqueue(data);
} }
}.bind(this)); }.bind(this));
this.socket.on('unqueue', function(data) { this.socket.on('unqueue', function(data) {
if(Rank.hasPermission(this, "queue")) { if(this.channel == null)
if(this.channel != null) return;
if(Rank.hasPermission(this, "queue") ||
this.channel.leader == this ||
this.channel.opts.qopen_allow_delete && !this.channel.qlocked) {
this.channel.unqueue(data); this.channel.unqueue(data);
} }
}.bind(this)); }.bind(this));
this.socket.on('moveMedia', function(data) { this.socket.on('moveMedia', function(data) {
if(Rank.hasPermission(this, "queue")) { if(this.channel == null)
if(this.channel != null) return;
if(Rank.hasPermission(this, "queue") ||
this.channel.leader == this ||
this.channel.opts.qopen_allow_move && !this.channel.qlocked ) {
this.channel.moveMedia(data); this.channel.moveMedia(data);
} }
}.bind(this)); }.bind(this));
this.socket.on('playNext', function() { this.socket.on('playNext', function() {
if(this.channel == null)
return;
if(Rank.hasPermission(this, "queue") || if(Rank.hasPermission(this, "queue") ||
(this.channel != null && this.channel.leader == this)) { this.channel.leader == this ||
this.channel.opts.qopen_allow_playnext && !this.channel.qlocked) {
if(this.channel.currentPosition + 1 >= this.channel.queue.length) { if(this.channel.currentPosition + 1 >= this.channel.queue.length) {
this.channel.currentPosition = -1; this.channel.currentPosition = -1;
} }
@ -197,6 +213,13 @@ User.prototype.initCallbacks = function() {
} }
} }
}.bind(this)); }.bind(this));
this.socket.on('channelOpts', function(data) {
if(Rank.hasPermission(this, "channelOpts") && this.channel != null) {
this.channel.opts = data;
this.channel.broadcastOpts();
}
}.bind(this));
} }
// Handle administration // Handle administration

View file

@ -106,6 +106,12 @@
font-size: 18pt; font-size: 18pt;
} }
.poll-notify {
color: #0000aa;
font-weight: bold;
font-size: 14pt;
}
.option button { .option button {
margin-right: 15px; margin-right: 15px;
} }

View file

@ -35,6 +35,9 @@ function initCallbacks() {
socket.on('rank', function(data) { socket.on('rank', function(data) {
if(data.rank >= Rank.Moderator) { if(data.rank >= Rank.Moderator) {
$('#playlist_controls').css("display", "block"); $('#playlist_controls').css("display", "block");
$('#playlist_controls button').each(function() {
$(this).attr('disabled', false);
});
$('#qlockbtn').css("display", "block"); $('#qlockbtn').css("display", "block");
var poll = $('#pollcontainer .active'); var poll = $('#pollcontainer .active');
if(poll.length > 0) { if(poll.length > 0) {
@ -48,6 +51,8 @@ function initCallbacks() {
for(var i = 0; i < users.length; i++) { for(var i = 0; i < users.length; i++) {
addUserDropdown(users[i], users[i].children[1].innerHTML); addUserDropdown(users[i], users[i].children[1].innerHTML);
} }
$('#chancontrols').show();
} }
RANK = data.rank; RANK = data.rank;
}); });
@ -73,6 +78,24 @@ function initCallbacks() {
} }
}); });
socket.on('channelOpts', function(opts) {
$('#opt_qopen_allow_qnext').prop('checked', opts.qopen_allow_qnext);
$('#opt_qopen_allow_move').prop('checked', opts.qopen_allow_move);
$('#opt_qopen_allow_delete').prop('checked', opts.qopen_allow_delete);
$('#opt_qopen_allow_playnext').prop('checked', opts.qopen_allow_playnext);
$('#opt_pagetitle').attr('placeholder', opts.pagetitle);
document.title = opts.pagetitle;
$('#opt_bgimage').attr('placeholder', opts.bgimage);
if(opts.bgimage != "")
$('body').css("background", "url('" + opts.bgimage + "') no-repeat fixed");
CHANNELOPTS = opts;
if(opts.qopen_allow_qnext)
$('#queue_next').attr('disabled', false);
if(opts.qopen_allow_playnext)
$('#play_next').attr('disabled', false);
rebuildPlaylist();
});
socket.on('usercount', function(data) { socket.on('usercount', function(data) {
$('#usercount').text(data.count + " connected users"); $('#usercount').text(data.count + " connected users");
}); });
@ -134,12 +157,16 @@ function initCallbacks() {
$('#playlist_controls').css('display', ''); $('#playlist_controls').css('display', '');
if(RANK < Rank.Moderator) { if(RANK < Rank.Moderator) {
$('#qlockbtn').css('display', 'none'); $('#qlockbtn').css('display', 'none');
rebuildPlaylist();
if(!CHANNELOPTS.qopen_allow_qnext)
$('#queue_next').attr('disabled', true);
if(!CHANNELOPTS.qopen_allow_playnext)
$('#play_next').attr('disabled', true);
} }
} }
else if(RANK < Rank.Moderator) { else if(RANK < Rank.Moderator) {
$('#playlist_controls').css('display', 'none'); $('#playlist_controls').css('display', 'none');
} }
if(RANK >= Rank.Moderator) {
if(OPENQUEUE) { if(OPENQUEUE) {
$('#qlockbtn').removeClass('btn-danger') $('#qlockbtn').removeClass('btn-danger')
.addClass('btn-success') .addClass('btn-success')
@ -150,7 +177,6 @@ function initCallbacks() {
.addClass('btn-danger') .addClass('btn-danger')
.text('Unlock Queue'); .text('Unlock Queue');
} }
}
}); });
socket.on('updatePlaylistIdx', function(data) { socket.on('updatePlaylistIdx', function(data) {

View file

@ -13,6 +13,7 @@ var MEDIATYPE = "yt";
var POSITION = -1; var POSITION = -1;
var RANK = 0; var RANK = 0;
var OPENQUEUE = false; var OPENQUEUE = false;
var CHANNELOPTS = {};
var uname = readCookie('sync_uname'); var uname = readCookie('sync_uname');
var pw = readCookie('sync_pw'); var pw = readCookie('sync_pw');
@ -207,6 +208,24 @@ $('#chatline').keydown(function(ev) {
} }
}); });
$('#opt_submit').click(function() {
var ptitle = $('#opt_pagetitle').val();
if(ptitle == '')
ptitle = $('#opt_pagetitle').attr('placeholder')
var bgimage = $('#opt_bgimage').val();
if(bgimage == '')
bgimage = $('#opt_bgimage').attr('placeholder')
opts = {
qopen_allow_qnext: $('#opt_qopen_allow_qnext').prop('checked'),
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'),
pagetitle: ptitle,
bgimage: $('#opt_bgimage').val()
};
socket.emit('channelOpts', opts);
});
function searchLibrary() { function searchLibrary() {
socket.emit('searchLibrary', { socket.emit('searchLibrary', {

View file

@ -198,6 +198,25 @@ function addQueueButtons(li) {
dest: dest dest: dest
}); });
}); });
if(RANK < Rank.Moderator && !LEADER) {
if(!CHANNELOPTS.qopen_allow_delete)
$(btnRemove).attr('disabled', true);
if(!CHANNELOPTS.qopen_allow_move) {
$(btnUp).attr('disabled', true);
$(btnDown).attr('disabled', true);
}
if(!CHANNELOPTS.qopen_allow_qnext)
$(btnNext).attr('disabled', true);
}
}
function rebuildPlaylist() {
$('#queue li').each(function() {
$(this).find('.btn-group').remove();
if(RANK >= Rank.Moderator || LEADER || OPENQUEUE)
addQueueButtons(this);
});
} }
// Add buttons to a list entry for the library search results // Add buttons to a list entry for the library search results
@ -466,6 +485,9 @@ function closePoll() {
function addPoll(data) { function addPoll(data) {
closePoll(); closePoll();
var pollMsg = $('<div/>').addClass('poll-notify')
.text(data.initiator + ' opened a poll: "' + data.title + '"')
.appendTo($('#messagebuffer'));
var poll = $('<div/>').addClass('well active').prependTo($('#pollcontainer')); var poll = $('<div/>').addClass('well active').prependTo($('#pollcontainer'));
$('<button/>').addClass('close pull-right').text('×') $('<button/>').addClass('close pull-right').text('×')
.appendTo(poll) .appendTo(poll)

View file

@ -93,6 +93,47 @@
</ul> </ul>
</div> </div>
</div> </div>
<div class="row" style="margin-top: 20px; display: none" id="chancontrols">
<div class="span10 offset1 well">
<form action="javascript:void(0)">
<fieldset>
<legend>Channel Options</legend>
<div class="span4">
<label>When the queue is open:</label>
<label class="checkbox">
<input type="checkbox" id="opt_qopen_allow_qnext">
Allow anyone to Queue Next
</label>
<label class="checkbox">
<input type="checkbox" id="opt_qopen_allow_move">
Allow anyone to move videos
</label>
<label class="checkbox">
<input type="checkbox" id="opt_qopen_allow_delete">
Allow anyone to delete videos
</label>
<label class="checkbox">
<input type="checkbox" id="opt_qopen_allow_playnext">
Allow anyone to skip to next video
</label>
</div>
<div class="span5">
<label>Page Title
<input type="text" id="opt_pagetitle" placeholder="Sync" class="pull-right">
</label>
<br>
<label>Background Image<sup class="text-warning">BETA</sup>
<input type="text" id="opt_bgimage" class="pull-right">
</label>
</div>
<div class="span10">
<button class="btn btn-primary" id="opt_submit">Save</button>
</div>
</fieldset>
</form>
</div>
</div>
</div> <!-- /container --> </div> <!-- /container -->
<script src="https://w.soundcloud.com/player/api.js"></script> <script src="https://w.soundcloud.com/player/api.js"></script>