").appendTo(tbl);
var remove = $("").addClass("btn btn-mini btn-danger")
.appendTo($("
").appendTo(tr));
$("").addClass("icon-remove-circle").appendTo(remove);
var name = $("").text(f.name)
.appendTo($("
").appendTo(tr));
var regex = $("").text(f.source)
.appendTo($("
").appendTo(tr));
var flags = $("").text(f.flags)
.appendTo($("
").appendTo(tr));
var replace = $("").text(f.replace)
.appendTo($("
").appendTo(tr));
var activetd = $("
").appendTo(tr);
var active = $("").attr("type", "checkbox")
.prop("checked", f.active).appendTo(activetd);
var remcallback = (function(filter) { return function() {
socket.emit("chatFilter", {
cmd: "remove",
filter: filter
});
} })(f);
remove.click(remcallback);
var actcallback = (function(filter) { return function() {
// Apparently when you check a checkbox, its value is changed
// before this callback. When you uncheck it, its value is not
// changed before this callback
// [](/amgic)
var enabled = active.prop("checked");
filter.active = (filter.active == enabled) ? !enabled : enabled;
socket.emit("chatFilter", {
cmd: "update",
filter: filter
});
} })(f);
active.click(actcallback);
}
var newfilt = $("
").appendTo(tbl);
$("
").appendTo(newfilt);
var name = $("").attr("type", "text")
.appendTo($("
").appendTo(newfilt));
var regex = $("").attr("type", "text")
.appendTo($("
").appendTo(newfilt));
var flags = $("").attr("type", "text")
.val("g")
.appendTo($("
").appendTo(newfilt));
var replace = $("").attr("type", "text")
.appendTo($("
").appendTo(newfilt));
var add = $("").addClass("btn btn-primary")
.text("Add Filter")
.appendTo($("
").text(names[i]).appendTo(detail);
}
this.data("namesopen", true);
}.bind(tr));
}
},
acl: function(entries) {
entries.sort(function(a, b) {
var x = a.name.toLowerCase();
var y = b.name.toLowerCase();
return y == x ? 0 : (x < y ? -1 : 1);
});
var tbl = $("#channelranks table");
if(tbl.children().length > 1) {
$(tbl.children()[1]).remove();
}
for(var i = 0; i < entries.length; i++) {
var tr = $("
").appendTo(tbl);
var name = $("
").text(entries[i].name).appendTo(tr);
name.addClass(getNameColor(entries[i].rank));
var rank = $("
").text(entries[i].rank).appendTo(tr);
var control = $("
").appendTo(tr);
var up = $("").addClass("btn btn-mini btn-success")
.appendTo(control);
$("").addClass("icon-plus").appendTo(up);
var down = $("").addClass("btn btn-mini btn-danger")
.appendTo(control);
$("").addClass("icon-minus").appendTo(down);
if(entries[i].rank + 1 >= RANK) {
up.attr("disabled", true);
}
else {
up.click(function(name) { return function() {
socket.emit("promote", {
name: name
});
}}(entries[i].name));
}
if(entries[i].rank >= RANK) {
down.attr("disabled", true);
}
else {
down.click(function(name) { return function() {
socket.emit("demote", {
name: name
});
}}(entries[i].name));
}
}
},
voteskip: function(data) {
if(data.count > 0) {
$("#voteskip").text("Voteskip ("+data.count+"/"+data.need+")");
}
else {
$("#voteskip").text("Voteskip");
}
},
/* REGION Rank Stuff */
rank: function(data) {
RANK = data.rank;
handlePermissionChange();
},
register: function(data) {
if(data.error) {
alert(data.error);
}
},
login: function(data) {
if(!data.success) {
if(data.error != "Invalid session") {
alert(data.error);
}
}
else {
$("#welcome").text("Logged in as " + uname);
$("#loginform").css("display", "none");
$("#logoutform").css("display", "");
$("#loggedin").css("display", "");
session = data.session || "";
createCookie("sync_uname", uname, 7);
createCookie("sync_session", session, 7);
}
},
/* REGION Chat */
usercount: function(data) {
var text = data.count + " connected user";
if(data.count != 1) {
text += "s";
}
$("#usercount").text(text);
},
chatMsg: function(data) {
addChatMessage(data);
},
clearchat: function() {
$("#messagebuffer").html("");
},
userlist: function(data) {
$(".userlist_item").each(function() { $(this).remove(); });
for(var i = 0; i < data.length; i++) {
Callbacks.addUser(data[i]);
}
},
addUser: function(data) {
var div = $("").attr("class", "userlist_item");
var flair = $("").appendTo(div);
var nametag = $("").text(data.name).appendTo(div);
formatUserlistItem(div[0], data);
addUserDropdown(div, data.name);
var users = $("#userlist").children();
for(var i = 0; i < users.length; i++) {
var othername = users[i].children[1].innerHTML;
if(othername.toLowerCase() > data.name.toLowerCase()) {
div.insertBefore(users[i]);
return;
}
}
div.appendTo($("#userlist"));
if(data.name == uname) {
PROFILE.image = data.profile.image;
PROFILE.text = data.profile.text;
}
},
updateUser: function(data) {
if(data.name == uname) {
PROFILE.text = data.profile.text;
PROFILE.image = data.profile.image;
LEADER = data.leader;
RANK = data.rank;
handlePermissionChange();
if(LEADER) {
// I'm a leader! Set up sync function
sendVideoUpdate = function() {
PLAYER.getTime(function(seconds) {
socket.emit("mediaUpdate", {
id: PLAYER.id,
currentTime: seconds,
paused: PLAYER.paused,
type: PLAYER.type
});
});
};
}
// I'm not a leader. Don't send syncs to the server
else {
sendVideoUpdate = function() { }
}
}
var users = $("#userlist").children();
for(var i = 0; i < users.length; i++) {
var name = users[i].children[1].innerHTML;
// Reformat user
if(name == data.name) {
formatUserlistItem(users[i], data);
}
}
},
userLeave: function(data) {
var users = $("#userlist").children();
for(var i = 0; i < users.length; i++) {
var name = users[i].children[1].innerHTML;
if(name == data.name) {
$("#userlist")[0].removeChild(users[i]);
}
}
},
drinkCount: function(data) {
if(data.count != 0) {
var text = data.count + " drink";
if(data.count != 1) {
text += "s";
}
$("#drinkcount").text(text);
$("#drinkbar").show();
}
else {
$("#drinkbar").hide();
}
},
/* REGION Playlist Stuff */
playlist: function(data) {
// Clear the playlist first
var ul = $("#queue")[0];
var n = ul.children.length;
for(var i = 0; i < n; i++) {
ul.removeChild(ul.children[0]);
}
for(var i = 0; i < data.pl.length; i++) {
var li = makeQueueEntry(data.pl[i]);
if(RANK >= Rank.Moderator || OPENQUEUE || LEADER)
addQueueButtons(li);
$(li).attr("title", data.pl[i].queueby
? ("Added by: " + data.pl[i].queueby)
: "Added by: Unknown");
$(li).appendTo(ul);
}
},
updatePlaylistMeta: function(data) {
$("#plcount").text(data.count + " items");
$("#pllength").text(data.time);
},
queue: function(data) {
var li = makeQueueEntry(data.media);
if(RANK >= Rank.Moderator || OPENQUEUE || LEADER)
addQueueButtons(li);
$(li).css("display", "none");
var idx = data.pos;
var ul = $("#queue")[0];
$(li).attr("title", data.media.queueby
? ("Added by: " + data.media.queueby)
: "Added by: Unknown");
$(li).appendTo(ul);
if(idx < ul.children.length - 1)
moveVideo(ul.children.length - 1, idx);
$(li).show("blind");
},
queueFail: function() {
alert("Queue failed. Double check your link to make sure the video exists.");
},
setTemp: function(data) {
var li = $("#queue").children()[data.idx];
var buttons = $(li).find(".qe_btn");
if(buttons.length == 5) {
$(buttons[4]).removeClass("btn-danger btn-success");
$(buttons[4]).addClass(data.temp ? "btn-success" : "btn-danger");
}
if(data.temp) {
$(li).addClass("alert alert-error");
}
else {
$(li).removeClass("alert alert-error");
}
},
unqueue: function(data) {
var li = $("#queue").children()[data.pos];
$(li).remove();
},
moveVideo: function(data) {
// Not recursive
moveVideo(data.src, data.dest);
},
updatePlaylistIdx: function(data) {
if(data.old != undefined) {
var liold = $("#queue").children()[data.old];
$(liold).removeClass("alert alert-info");
}
var linew = $("#queue").children()[data.idx];
$(linew).addClass("alert alert-info");
$("#queue").scrollTop(0);
var scroll = $(linew).position().top - $("#queue").position().top;
$("#queue").scrollTop(scroll);
POSITION = data.idx;
if(CHANNELOPTS.allow_voteskip)
$("#voteskip").attr("disabled", false);
},
changeMedia: function(data) {
$("#currenttitle").text("Currently Playing: " + data.title);
if(data.type != "sc" && MEDIATYPE == "sc")
// [](/goddamnitmango)
fixSoundcloudShit();
if(data.type != MEDIATYPE) {
MEDIATYPE = data.type;
PLAYER = new Media(data);
}
if(PLAYER.update) {
PLAYER.update(data);
}
},
mediaUpdate: function(data) {
if(PLAYER.update) {
PLAYER.update(data);
}
},
queueLock: function(data) {
OPENQUEUE = !data.locked;
if(OPENQUEUE) {
$("#playlist_controls").css("display", "");
if(RANK < Rank.Moderator) {
$("#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 && !LEADER) {
$("#playlist_controls").css("display", "none");
rebuildPlaylist();
}
if(OPENQUEUE) {
$("#qlockbtn").removeClass("btn-danger")
.addClass("btn-success")
.text("Lock Queue");
}
else {
$("#qlockbtn").removeClass("btn-success")
.addClass("btn-danger")
.text("Unlock Queue");
}
},
librarySearchResults: function(data) {
var n = $("#library").children().length;
for(var i = 0; i < n; i++) {
$("#library")[0].removeChild($("#library").children()[0]);
}
var ul = $("#library")[0];
for(var i = 0; i < data.results.length; i++) {
var li = makeQueueEntry(data.results[i]);
if(RANK >= Rank.Moderator || OPENQUEUE || LEADER) {
if(data.results[i].thumb)
addLibraryButtons(li, data.results[i].id, true);
else
addLibraryButtons(li, data.results[i].id);
}
$(li).appendTo(ul);
}
},
/* REGION Polls */
newPoll: function(data) {
closePoll();
var pollMsg = $("").addClass("poll-notify")
.text(data.initiator + " opened a poll: \"" + data.title + "\"")
.appendTo($("#messagebuffer"));
$("#messagebuffer").scrollTop($("#messagebuffer").prop("scrollHeight"));
var poll = $("").addClass("well active").prependTo($("#pollcontainer"));
$("").addClass("close pull-right").text("×")
.appendTo(poll)
.click(function() { poll.remove(); });
if(RANK >= Rank.Moderator || LEADER) {
$("").addClass("btn btn-danger pull-right").text("End Poll")
.appendTo(poll)
.click(function() {
socket.emit("closePoll")
});
}
$("").text(data.title).appendTo(poll);
for(var i = 0; i < data.options.length; i++) {
var callback = (function(i) { return function() {
socket.emit("vote", {
option: i
});
poll.find(".option button").each(function() {
$(this).attr("disabled", "disabled");
});
} })(i);
$("").addClass("btn").text(data.counts[i])
.prependTo($("").addClass("option").text(data.options[i])
.appendTo(poll))
.click(callback);
}
},
updatePoll: function(data) {
var poll = $("#pollcontainer .active");
var i = 0;
poll.find(".option button").each(function() {
$(this).text(data.counts[i]);
i++;
});
},
closePoll: function() {
// Not recursive
closePoll();
}
}