2013-08-07 21:00:53 +00:00
|
|
|
/*
|
|
|
|
The MIT License (MIT)
|
|
|
|
Copyright (c) 2013 Calvin Montgomery
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
Callbacks = {
|
|
|
|
|
|
|
|
error: function (reason) {
|
2013-08-19 16:10:52 +00:00
|
|
|
// Don't show the error for when the server goes down
|
|
|
|
if(reason && reason.returnValue === true)
|
|
|
|
return;
|
|
|
|
|
2013-08-07 21:00:53 +00:00
|
|
|
var d = $("<div/>").addClass("alert alert-error span12")
|
|
|
|
.appendTo($("#announcements"));
|
|
|
|
$("<h3/>").text("Uh-oh!").appendTo(d);
|
|
|
|
$("<p/>").html("The socket.io connection failed."+
|
|
|
|
"Try going to the "+
|
|
|
|
"'Options' menu and enabling 'Alternate socket "+
|
|
|
|
" connection'. If that doesn't help, talk to "+
|
|
|
|
"someone on <a href='http://webchat.6irc.net/?"+
|
|
|
|
"channels=synchtube'>IRC</a>").appendTo(d);
|
|
|
|
var data = {
|
|
|
|
iourl: IO_URL,
|
|
|
|
weburl: WEB_URL,
|
|
|
|
transports: io.transports,
|
|
|
|
fallback: USEROPTS.altsocket,
|
|
|
|
reason: reason
|
|
|
|
};
|
|
|
|
|
|
|
|
var r = JSON.stringify(data);
|
|
|
|
$("<em/>").text("When asking for help, give the following "+
|
|
|
|
"information to an administrator:").appendTo(d);
|
|
|
|
$("<code/>").text(r).appendTo(d)
|
|
|
|
.css("white-space", "pre-wrap");
|
|
|
|
},
|
|
|
|
|
|
|
|
/* fired when socket connection completes */
|
|
|
|
connect: function() {
|
|
|
|
socket.emit("joinChannel", {
|
|
|
|
name: CHANNEL.name
|
|
|
|
});
|
2013-11-25 22:20:15 +00:00
|
|
|
if (CHANNEL.opts.password) {
|
|
|
|
socket.emit("channelPassword", CHANNEL.opts.password);
|
|
|
|
}
|
2013-08-07 21:00:53 +00:00
|
|
|
if(NAME && SESSION) {
|
|
|
|
socket.emit("login", {
|
|
|
|
name: NAME,
|
|
|
|
session: SESSION
|
|
|
|
});
|
|
|
|
}
|
|
|
|
// Guest auto-relogin
|
|
|
|
else if(CLIENT.name) {
|
|
|
|
socket.emit("login", {
|
|
|
|
name: CLIENT.name
|
|
|
|
});
|
|
|
|
}
|
|
|
|
$("<div/>").addClass("server-msg-reconnect")
|
|
|
|
.text("Connected")
|
|
|
|
.appendTo($("#messagebuffer"));
|
|
|
|
$("#messagebuffer").scrollTop($("#messagebuffer").prop("scrollHeight"));
|
|
|
|
},
|
|
|
|
|
|
|
|
disconnect: function() {
|
|
|
|
if(KICKED)
|
|
|
|
return;
|
|
|
|
$("<div/>")
|
|
|
|
.addClass("server-msg-disconnect")
|
|
|
|
.text("Disconnected from server. Attempting reconnection...")
|
|
|
|
.appendTo($("#messagebuffer"));
|
|
|
|
scrollChat();
|
|
|
|
},
|
|
|
|
|
|
|
|
errorMsg: function(data) {
|
2013-10-17 04:22:37 +00:00
|
|
|
errDialog(data.msg);
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
2013-08-18 23:35:49 +00:00
|
|
|
costanza: function (data) {
|
|
|
|
hidePlayer();
|
|
|
|
$("#costanza-modal").modal("hide");
|
|
|
|
var modal = $("<div/>").addClass("modal hide fade")
|
|
|
|
.attr("id", "costanza-modal")
|
|
|
|
.appendTo($("body"));
|
|
|
|
|
|
|
|
|
|
|
|
var body = $("<div/>").addClass("modal-body").appendTo(modal);
|
|
|
|
$("<button/>").addClass("close")
|
|
|
|
.attr("data-dismiss", "modal")
|
|
|
|
.attr("data-hidden", "true")
|
|
|
|
.html("×")
|
|
|
|
.appendTo(body);
|
|
|
|
$("<img/>").attr("src", "http://i0.kym-cdn.com/entries/icons/original/000/005/498/1300044776986.jpg")
|
|
|
|
.appendTo(body);
|
|
|
|
|
|
|
|
$("<strong/>").text(data.msg).appendTo(body);
|
|
|
|
|
|
|
|
modal.on("hidden", function () {
|
|
|
|
modal.remove();
|
|
|
|
unhidePlayer();
|
|
|
|
});
|
|
|
|
|
|
|
|
modal.modal();
|
|
|
|
},
|
|
|
|
|
2013-08-07 21:00:53 +00:00
|
|
|
announcement: function(data) {
|
|
|
|
$("#announcements").html("");
|
|
|
|
makeAlert(data.title, data.text)
|
|
|
|
.appendTo($("#announcements"));
|
|
|
|
},
|
|
|
|
|
|
|
|
kick: function(data) {
|
|
|
|
KICKED = true;
|
|
|
|
$("<div/>").addClass("server-msg-disconnect")
|
|
|
|
.text("Kicked: " + data.reason)
|
|
|
|
.appendTo($("#messagebuffer"));
|
|
|
|
scrollChat();
|
|
|
|
},
|
|
|
|
|
|
|
|
noflood: function(data) {
|
|
|
|
$("<div/>")
|
|
|
|
.addClass("server-msg-disconnect")
|
|
|
|
.text(data.action + ": " + data.msg)
|
|
|
|
.appendTo($("#messagebuffer"));
|
|
|
|
scrollChat();
|
|
|
|
},
|
|
|
|
|
2013-11-25 22:20:15 +00:00
|
|
|
needPassword: function (wrongpw) {
|
|
|
|
var div = $("<div/>");
|
|
|
|
$("<strong/>").text("Channel Password")
|
|
|
|
.appendTo(div);
|
|
|
|
if (wrongpw) {
|
|
|
|
$("<br/>").appendTo(div);
|
|
|
|
$("<span/>").addClass("text-error")
|
|
|
|
.text("Wrong Password")
|
|
|
|
.appendTo(div);
|
|
|
|
}
|
|
|
|
|
|
|
|
var pwbox = $("<input/>").addClass("input-block-level")
|
|
|
|
.attr("type", "password")
|
|
|
|
.appendTo(div);
|
|
|
|
var submit = $("<button/>").addClass("btn btn-mini btn-block")
|
|
|
|
.text("Submit")
|
|
|
|
.appendTo(div);
|
|
|
|
var parent = chatDialog(div);
|
|
|
|
parent.attr("id", "needpw");
|
|
|
|
var sendpw = function () {
|
|
|
|
socket.emit("channelPassword", pwbox.val());
|
|
|
|
parent.remove();
|
|
|
|
};
|
|
|
|
submit.click(sendpw);
|
|
|
|
pwbox.keydown(function (ev) {
|
|
|
|
if (ev.keyCode == 13) {
|
|
|
|
sendpw();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
pwbox.focus();
|
|
|
|
},
|
|
|
|
|
|
|
|
cancelNeedPassword: function () {
|
|
|
|
$("#needpw").remove();
|
|
|
|
},
|
|
|
|
|
2013-11-19 21:14:40 +00:00
|
|
|
chatCooldown: function (time) {
|
|
|
|
time = time + 200;
|
|
|
|
$("#chatline").css("color", "#ff0000");
|
|
|
|
if (CHATTHROTTLE && $("#chatline").data("throttle_timer")) {
|
|
|
|
clearTimeout($("#chatline").data("throttle_timer"));
|
|
|
|
}
|
|
|
|
CHATTHROTTLE = true;
|
|
|
|
$("#chatline").data("throttle_timer", setTimeout(function () {
|
|
|
|
CHATTHROTTLE = false;
|
|
|
|
$("#chatline").css("color", "");
|
|
|
|
}, time));
|
|
|
|
},
|
|
|
|
|
2013-08-07 21:00:53 +00:00
|
|
|
channelNotRegistered: function() {
|
|
|
|
var div = $("<div/>").addClass("alert alert-info")
|
|
|
|
.attr("id", "chregnotice")
|
|
|
|
.insertBefore($("#main"));
|
|
|
|
$("<button/>").addClass("close pull-right").html("×")
|
|
|
|
.appendTo(div)
|
|
|
|
.click(function() { div.remove(); });
|
|
|
|
$("<h3/>").text("This channel isn't registered").appendTo(div);
|
|
|
|
$("<button/>").addClass("btn btn-primary").text("Register it")
|
2013-09-06 03:54:30 +00:00
|
|
|
.attr("id", "chanregisterbtn")
|
2013-08-07 21:00:53 +00:00
|
|
|
.appendTo(div)
|
|
|
|
.click(function() {
|
2013-09-06 03:54:30 +00:00
|
|
|
$(this).attr("disabled", true)
|
|
|
|
.text("Registering...");
|
2013-08-07 21:00:53 +00:00
|
|
|
socket.emit("registerChannel");
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
registerChannel: function(data) {
|
2013-09-06 03:54:30 +00:00
|
|
|
if ($("#chanregisterbtn").length > 0) {
|
|
|
|
$("#chanregisterbtn").text("Register it")
|
|
|
|
.attr("disabled", false);
|
|
|
|
}
|
2013-08-07 21:00:53 +00:00
|
|
|
if(data.success) {
|
|
|
|
$("#chregnotice").remove();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
makeAlert("Error", data.error, "alert-error")
|
|
|
|
.insertAfter($("#chregnotice"));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
unregisterChannel: function(data) {
|
|
|
|
if(data.success) {
|
|
|
|
alert("Channel unregistered");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
alert(data.error);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
setMotd: function(data) {
|
|
|
|
CHANNEL.motd = data.html;
|
|
|
|
CHANNEL.motd_text = data.motd;
|
2013-11-14 04:36:43 +00:00
|
|
|
if ($("#motdwrap").find(".motdeditor").length > 0) {
|
|
|
|
$("#motdwrap .motdeditor").val(CHANNEL.motd_text);
|
|
|
|
} else {
|
|
|
|
$("#motd").html(CHANNEL.motd);
|
|
|
|
}
|
2013-08-07 21:00:53 +00:00
|
|
|
$("#motdtext").val(CHANNEL.motd_text);
|
2013-10-03 03:26:28 +00:00
|
|
|
if(data.motd != "") {
|
|
|
|
$("#motdwrap").show();
|
2013-08-07 21:00:53 +00:00
|
|
|
$("#motd").show();
|
2013-10-03 03:26:28 +00:00
|
|
|
$("#togglemotd").find(".icon-plus")
|
|
|
|
.removeClass("icon-plus")
|
|
|
|
.addClass("icon-minus");
|
|
|
|
}
|
2013-08-07 21:00:53 +00:00
|
|
|
else
|
2013-10-03 03:26:28 +00:00
|
|
|
$("#motdwrap").hide();
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
chatFilters: function(entries) {
|
|
|
|
var tbl = $("#filteredit table");
|
|
|
|
if(!tbl.hasClass("table")) {
|
|
|
|
setTimeout(function() {
|
|
|
|
Callbacks.chatFilters(entries);
|
|
|
|
}, 100);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
tbl.find(".filter-row").remove();
|
|
|
|
for(var i = 0; i < entries.length; i++) {
|
|
|
|
var f = entries[i];
|
|
|
|
var tr = $("<tr/>").appendTo(tbl).addClass("filter-row");
|
|
|
|
var remove = $("<button/>").addClass("btn btn-mini btn-danger")
|
|
|
|
.appendTo($("<td/>").appendTo(tr));
|
|
|
|
$("<i/>").addClass("icon-trash").appendTo(remove);
|
|
|
|
var name = $("<code/>").text(f.name)
|
|
|
|
.appendTo($("<td/>").appendTo(tr));
|
|
|
|
var regex = $("<code/>").text(f.source)
|
|
|
|
.appendTo($("<td/>").appendTo(tr));
|
|
|
|
var flags = $("<code/>").text(f.flags)
|
|
|
|
.appendTo($("<td/>").appendTo(tr));
|
|
|
|
var replace = $("<code/>").text(f.replace)
|
|
|
|
.appendTo($("<td/>").appendTo(tr));
|
|
|
|
var linktd = $("<td/>").appendTo(tr);
|
|
|
|
var link = $("<input/>").attr("type", "checkbox")
|
|
|
|
.prop("checked", f.filterlinks).appendTo(linktd);
|
|
|
|
var activetd = $("<td/>").appendTo(tr);
|
|
|
|
var active = $("<input/>").attr("type", "checkbox")
|
|
|
|
.prop("checked", f.active).appendTo(activetd);
|
|
|
|
(function(f) {
|
|
|
|
regex.click(function() {
|
|
|
|
if(this.find(".filter-regex-edit").length > 0)
|
|
|
|
return;
|
|
|
|
var r = this.text();
|
|
|
|
this.text("");
|
|
|
|
var edit = $("<input/>").attr("type", "text")
|
|
|
|
.css("font-family", "Monospace")
|
|
|
|
.attr("placeholder", r)
|
|
|
|
.val(r)
|
|
|
|
.addClass("filter-regex-edit")
|
|
|
|
.appendTo(this)
|
|
|
|
.focus();
|
|
|
|
|
|
|
|
function save() {
|
|
|
|
var r = this.val();
|
|
|
|
var r2 = r;
|
|
|
|
if(r.trim() == "")
|
|
|
|
r = this.attr("placeholder");
|
|
|
|
this.parent().text(r);
|
|
|
|
f.source = r;
|
|
|
|
socket.emit("updateFilter", f);
|
|
|
|
}
|
|
|
|
edit.blur(save.bind(edit));
|
|
|
|
edit.keydown(function(ev) {
|
|
|
|
if(ev.keyCode == 13)
|
|
|
|
save.bind(edit)();
|
|
|
|
});
|
|
|
|
}.bind(regex));
|
|
|
|
flags.click(function() {
|
|
|
|
if(this.find(".filter-flags-edit").length > 0)
|
|
|
|
return;
|
|
|
|
var r = this.text();
|
|
|
|
this.text("");
|
|
|
|
var edit = $("<input/>").attr("type", "text")
|
|
|
|
.css("font-family", "Monospace")
|
|
|
|
.attr("placeholder", r)
|
|
|
|
.val(r)
|
|
|
|
.addClass("filter-flags-edit")
|
|
|
|
.appendTo(this)
|
|
|
|
.focus();
|
|
|
|
|
|
|
|
function save() {
|
|
|
|
var r = this.val();
|
|
|
|
var r2 = r;
|
|
|
|
if(r.trim() == "")
|
|
|
|
r = this.attr("placeholder");
|
|
|
|
this.parent().text(r);
|
|
|
|
f.flags = r;
|
|
|
|
socket.emit("updateFilter", f);
|
|
|
|
}
|
|
|
|
edit.blur(save.bind(edit));
|
|
|
|
edit.keydown(function(ev) {
|
|
|
|
if(ev.keyCode == 13)
|
|
|
|
save.bind(edit)();
|
|
|
|
});
|
|
|
|
}.bind(flags));
|
|
|
|
replace.click(function() {
|
|
|
|
if(this.find(".filter-replace-edit").length > 0)
|
|
|
|
return;
|
|
|
|
var r = this.text();
|
|
|
|
this.text("");
|
|
|
|
var edit = $("<input/>").attr("type", "text")
|
|
|
|
.css("font-family", "Monospace")
|
|
|
|
.attr("placeholder", r)
|
|
|
|
.val(r)
|
|
|
|
.addClass("filter-replace-edit")
|
|
|
|
.appendTo(this)
|
|
|
|
.focus();
|
|
|
|
|
|
|
|
function save() {
|
|
|
|
var r = this.val();
|
|
|
|
var r2 = r;
|
|
|
|
if(r.trim() == "")
|
|
|
|
r = this.attr("placeholder");
|
|
|
|
this.parent().text(r);
|
|
|
|
f.replace = r;
|
|
|
|
socket.emit("updateFilter", f);
|
|
|
|
}
|
|
|
|
edit.blur(save.bind(edit));
|
|
|
|
edit.keydown(function(ev) {
|
|
|
|
if(ev.keyCode == 13)
|
|
|
|
save.bind(edit)();
|
|
|
|
});
|
|
|
|
}.bind(replace));
|
|
|
|
|
|
|
|
remove.click(function() {
|
|
|
|
socket.emit("removeFilter", f);
|
|
|
|
});
|
|
|
|
|
|
|
|
active.click(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");
|
|
|
|
f.active = (f.active == enabled) ? !enabled : enabled;
|
|
|
|
socket.emit("updateFilter", f);
|
|
|
|
});
|
|
|
|
link.click(function() {
|
|
|
|
var enabled = link.prop("checked");
|
|
|
|
f.filterlinks = (f.filterlinks == enabled) ? !enabled : enabled;
|
|
|
|
socket.emit("updateFilter", f);
|
|
|
|
});
|
|
|
|
})(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
$(tbl.children()[1]).sortable({
|
|
|
|
start: function(ev, ui) {
|
|
|
|
FILTER_FROM = ui.item.prevAll().length;
|
|
|
|
},
|
|
|
|
update: function(ev, ui) {
|
|
|
|
FILTER_TO = ui.item.prevAll().length;
|
|
|
|
if(FILTER_TO != FILTER_FROM) {
|
|
|
|
socket.emit("moveFilter", {
|
|
|
|
from: FILTER_FROM,
|
|
|
|
to: FILTER_TO
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
channelOpts: function(opts) {
|
|
|
|
document.title = opts.pagetitle;
|
|
|
|
PAGETITLE = opts.pagetitle;
|
|
|
|
$("#chanexternalcss").remove();
|
|
|
|
if(opts.externalcss.trim() != "" && !USEROPTS.ignore_channelcss) {
|
|
|
|
$("<link/>")
|
|
|
|
.attr("rel", "stylesheet")
|
|
|
|
.attr("href", opts.externalcss)
|
|
|
|
.attr("id", "chanexternalcss")
|
|
|
|
.appendTo($("head"));
|
|
|
|
}
|
|
|
|
if(opts.externaljs.trim() != "" && !USEROPTS.ignore_channeljs) {
|
|
|
|
if(opts.externaljs != CHANNEL.opts.externaljs) {
|
|
|
|
$.getScript(opts.externaljs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CHANNEL.opts = opts;
|
|
|
|
|
|
|
|
if(opts.allow_voteskip)
|
|
|
|
$("#voteskip").attr("disabled", false);
|
|
|
|
else
|
|
|
|
$("#voteskip").attr("disabled", true);
|
|
|
|
handlePermissionChange();
|
|
|
|
},
|
|
|
|
|
|
|
|
setPermissions: function(perms) {
|
|
|
|
CHANNEL.perms = perms;
|
|
|
|
if(CLIENT.rank >= Rank.Admin)
|
|
|
|
genPermissionsEditor();
|
|
|
|
handlePermissionChange();
|
|
|
|
},
|
|
|
|
|
|
|
|
channelCSSJS: function(data) {
|
|
|
|
$("#chancss").remove();
|
|
|
|
CHANNEL.css = data.css;
|
|
|
|
$("#csstext").val(data.css);
|
|
|
|
if(data.css && !USEROPTS.ignore_channelcss) {
|
|
|
|
$("<style/>").attr("type", "text/css")
|
|
|
|
.attr("id", "chancss")
|
|
|
|
.text(data.css)
|
|
|
|
.appendTo($("head"));
|
|
|
|
}
|
|
|
|
|
|
|
|
$("#chanjs").remove();
|
|
|
|
CHANNEL.js = data.js;
|
|
|
|
$("#jstext").val(data.js);
|
|
|
|
|
|
|
|
if(data.js && !USEROPTS.ignore_channeljs) {
|
|
|
|
$("<script/>").attr("type", "text/javascript")
|
|
|
|
.attr("id", "chanjs")
|
|
|
|
.text(data.js)
|
|
|
|
.appendTo($("body"));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
banlist: function(entries) {
|
|
|
|
var tbl = $("#banlist table");
|
|
|
|
// I originally added this check because of a race condition
|
|
|
|
// Now it seems to work without but I don't trust it
|
|
|
|
if(!tbl.hasClass("table")) {
|
|
|
|
setTimeout(function() {
|
|
|
|
Callbacks.banlist(entries);
|
|
|
|
}, 100);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(tbl.children().length > 1) {
|
|
|
|
$(tbl.children()[1]).remove();
|
|
|
|
}
|
|
|
|
for(var i = 0; i < entries.length; i++) {
|
|
|
|
var tr = document.createElement("tr");
|
|
|
|
var remove = $("<button/>").addClass("btn btn-mini btn-danger")
|
|
|
|
.appendTo($("<td/>").appendTo(tr));
|
|
|
|
$("<i/>").addClass("icon-remove-circle").appendTo(remove);
|
|
|
|
var ip = $("<td/>").text(entries[i].ip_displayed).appendTo(tr);
|
|
|
|
var name = $("<td/>").text(entries[i].name).appendTo(tr);
|
|
|
|
var aliases = $("<td/>").text(entries[i].aliases.join(", ")).appendTo(tr);
|
|
|
|
var banner = $("<td/>").text(entries[i].banner).appendTo(tr);
|
|
|
|
|
|
|
|
var callback = (function(ip_hidden, name) { return function() {
|
|
|
|
socket.emit("unban", {
|
|
|
|
ip_hidden: ip_hidden,
|
|
|
|
name: name
|
|
|
|
});
|
|
|
|
} })(entries[i].ip_hidden, entries[i].name);
|
|
|
|
remove.click(callback);
|
|
|
|
|
|
|
|
$(tr).appendTo(tbl);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
recentLogins: function(entries) {
|
|
|
|
var tbl = $("#loginhistory table");
|
|
|
|
// I originally added this check because of a race condition
|
|
|
|
// Now it seems to work without but I don't trust it
|
|
|
|
if(!tbl.hasClass("table")) {
|
|
|
|
setTimeout(function() {
|
|
|
|
Callbacks.recentLogins(entries);
|
|
|
|
}, 100);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(tbl.children().length > 1) {
|
|
|
|
$(tbl.children()[1]).remove();
|
|
|
|
}
|
|
|
|
for(var i = 0; i < entries.length; i++) {
|
|
|
|
var tr = document.createElement("tr");
|
|
|
|
var name = $("<td/>").text(entries[i].name).appendTo(tr);
|
|
|
|
var aliases = $("<td/>").text(entries[i].aliases.join(", ")).appendTo(tr);
|
|
|
|
var time = new Date(entries[i].time).toTimeString();
|
|
|
|
$("<td/>").text(time).appendTo(tr);
|
|
|
|
|
|
|
|
$(tr).appendTo(tbl);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
channelRanks: function(entries) {
|
|
|
|
var tbl = $("#channelranks table");
|
|
|
|
// I originally added this check because of a race condition
|
|
|
|
// Now it seems to work without but I don't trust it
|
|
|
|
if(!tbl.hasClass("table")) {
|
|
|
|
setTimeout(function() {
|
|
|
|
Callbacks.channelRanks(entries);
|
|
|
|
}, 100);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
entries.sort(function(a, b) {
|
|
|
|
var x = a.name.toLowerCase();
|
|
|
|
var y = b.name.toLowerCase();
|
|
|
|
return y == x ? 0 : (x < y ? -1 : 1);
|
|
|
|
});
|
|
|
|
$("#channelranks").data("entries", entries);
|
|
|
|
if(tbl.children().length > 1) {
|
|
|
|
$(tbl.children()[1]).remove();
|
|
|
|
}
|
|
|
|
var p = tbl.data("paginator");
|
|
|
|
if(p) {
|
|
|
|
p.items = entries;
|
|
|
|
p.loadPage(0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
var opts = {
|
|
|
|
preLoadPage: function (p) {
|
|
|
|
tbl.find("tbody").remove();
|
|
|
|
tbl.data("page", p);
|
|
|
|
},
|
|
|
|
generator: function (item, page, index) {
|
|
|
|
var tr = $("<tr/>").appendTo(tbl);
|
|
|
|
var name = $("<td/>").text(item.name).appendTo(tr);
|
|
|
|
name.addClass(getNameColor(item.rank));
|
|
|
|
var rank = $("<td/>").text(item.rank)
|
|
|
|
.css("min-width", "220px")
|
|
|
|
.appendTo(tr);
|
|
|
|
rank.click(function() {
|
|
|
|
if(this.find(".rank-edit").length > 0)
|
|
|
|
return;
|
|
|
|
var r = this.text();
|
|
|
|
this.text("");
|
|
|
|
var edit = $("<input/>").attr("type", "text")
|
|
|
|
.attr("placeholder", r)
|
|
|
|
.addClass("rank-edit")
|
|
|
|
.appendTo(this)
|
|
|
|
.focus();
|
|
|
|
if(parseInt(r) >= CLIENT.rank) {
|
|
|
|
edit.attr("disabled", true);
|
|
|
|
}
|
|
|
|
function save() {
|
|
|
|
var r = this.val();
|
|
|
|
var r2 = r;
|
|
|
|
if(r.trim() == "" || parseInt(r) >= CLIENT.rank || parseInt(r) < 1)
|
|
|
|
r = this.attr("placeholder");
|
|
|
|
r = parseInt(r) + "";
|
|
|
|
this.parent().text(r);
|
|
|
|
socket.emit("setChannelRank", {
|
|
|
|
user: item.name,
|
|
|
|
rank: parseInt(r)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
edit.blur(save.bind(edit));
|
|
|
|
edit.keydown(function(ev) {
|
|
|
|
if(ev.keyCode == 13)
|
|
|
|
save.bind(edit)();
|
|
|
|
});
|
|
|
|
}.bind(rank));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var p = Paginate(entries, opts);
|
|
|
|
p.paginator.insertBefore($("#channelranks table"));
|
|
|
|
tbl.data("paginator", p);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
setChannelRank: function(data) {
|
|
|
|
var ents = $("#channelranks").data("entries");
|
2013-11-15 16:24:43 +00:00
|
|
|
if(typeof ents === "undefined" || ents === null)
|
2013-08-07 21:00:53 +00:00
|
|
|
return;
|
|
|
|
for(var i = 0; i < ents.length; i++) {
|
|
|
|
if(ents[i].name == data.user) {
|
|
|
|
ents[i].rank = data.rank;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$("#channelranks").data("entries", ents);
|
|
|
|
$("#channelranks table").data("paginator").loadPage(
|
|
|
|
$("#channelranks table").data("page")
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
readChanLog: function (data) {
|
|
|
|
var log = $("#chanlog_contents");
|
|
|
|
if(log.length == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(data.success) {
|
2013-11-16 05:55:35 +00:00
|
|
|
log.data("log", data.data);
|
2013-08-07 21:00:53 +00:00
|
|
|
log.text(data.data);
|
2013-11-16 05:56:25 +00:00
|
|
|
filterChannelLog();
|
2013-08-07 21:00:53 +00:00
|
|
|
} else {
|
|
|
|
log.text("Error reading channel log");
|
|
|
|
}
|
|
|
|
log.scrollTop(log.prop("scrollHeight"));
|
|
|
|
},
|
|
|
|
|
|
|
|
voteskip: function(data) {
|
|
|
|
if(data.count > 0) {
|
|
|
|
$("#voteskip").text("Voteskip ("+data.count+"/"+data.need+")");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$("#voteskip").text("Voteskip");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/* REGION Rank Stuff */
|
|
|
|
|
|
|
|
rank: function(r) {
|
|
|
|
if(r >= 255)
|
|
|
|
SUPERADMIN = true;
|
|
|
|
CLIENT.rank = r;
|
|
|
|
handlePermissionChange();
|
|
|
|
if(SUPERADMIN && $("#setrank").length == 0) {
|
|
|
|
$("<a/>").attr("href", "/acp.html")
|
|
|
|
.attr("target", "_blank")
|
|
|
|
.text("ACP")
|
|
|
|
.appendTo($("<li/>").appendTo($(".nav")[0]));
|
|
|
|
var li = $("<li/>").addClass("dropdown")
|
|
|
|
.attr("id", "setrank")
|
|
|
|
.appendTo($(".nav")[0]);
|
|
|
|
$("<a/>").addClass("dropdown-toggle")
|
|
|
|
.attr("data-toggle", "dropdown")
|
|
|
|
.attr("href", "javascript:void(0)")
|
|
|
|
.html("Set Rank <b class='caret'></b>")
|
|
|
|
.appendTo(li);
|
|
|
|
var menu = $("<ul/>").addClass("dropdown-menu")
|
|
|
|
.appendTo(li);
|
|
|
|
|
|
|
|
function addRank(r, disp) {
|
|
|
|
var li = $("<li/>").appendTo(menu);
|
|
|
|
$("<a/>").attr("href", "javascript:void(0)")
|
|
|
|
.html(disp)
|
|
|
|
.click(function() {
|
|
|
|
socket.emit("borrow-rank", r);
|
|
|
|
})
|
|
|
|
.appendTo(li);
|
|
|
|
}
|
|
|
|
|
|
|
|
addRank(0, "<span class='userlist_guest'>Guest</span>");
|
|
|
|
addRank(1, "<span>Registered</span>");
|
|
|
|
addRank(2, "<span class='userlist_op'>Moderator</span>");
|
|
|
|
addRank(3, "<span class='userlist_owner'>Admin</span>");
|
|
|
|
addRank(255, "<span class='userlist_siteadmin'>Superadmin</span>");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/* should not be relevant since registration is on account.html */
|
|
|
|
register: function(data) {
|
|
|
|
if(data.error) {
|
|
|
|
alert(data.error);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
login: function(data) {
|
|
|
|
if(!data.success) {
|
2013-08-18 17:48:49 +00:00
|
|
|
if(data.error != "Session expired") {
|
2013-08-07 21:00:53 +00:00
|
|
|
alert(data.error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$("#welcome").text("Logged in as " + data.name);
|
|
|
|
$("#loginform").css("display", "none");
|
|
|
|
$("#logoutform").css("display", "");
|
|
|
|
$("#loggedin").css("display", "");
|
|
|
|
SESSION = data.session || "";
|
|
|
|
CLIENT.name = data.name;
|
|
|
|
CLIENT.logged_in = true;
|
|
|
|
if(SESSION) {
|
|
|
|
createCookie("cytube_uname", CLIENT.name, 7);
|
|
|
|
createCookie("cytube_session", SESSION, 7);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/* REGION Chat */
|
|
|
|
usercount: function(count) {
|
2013-09-04 22:47:24 +00:00
|
|
|
CHANNEL.usercount = count;
|
2013-08-07 21:00:53 +00:00
|
|
|
var text = count + " connected user";
|
|
|
|
if(count != 1) {
|
|
|
|
text += "s";
|
|
|
|
}
|
|
|
|
$("#usercount").text(text);
|
|
|
|
},
|
|
|
|
|
|
|
|
chatMsg: function(data) {
|
|
|
|
addChatMessage(data);
|
|
|
|
},
|
|
|
|
|
|
|
|
joinMessage: function(data) {
|
|
|
|
if(USEROPTS.joinmessage)
|
|
|
|
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) {
|
2013-08-22 00:20:26 +00:00
|
|
|
var user = findUserlistItem(data.name);
|
|
|
|
// Remove previous instance of user, if there was one
|
|
|
|
if(user !== null)
|
|
|
|
user.remove();
|
2013-08-07 21:00:53 +00:00
|
|
|
var div = $("<div/>")
|
2013-08-07 21:55:39 +00:00
|
|
|
.addClass("userlist_item");
|
2013-08-07 21:00:53 +00:00
|
|
|
var flair = $("<span/>").appendTo(div);
|
|
|
|
var nametag = $("<span/>").text(data.name).appendTo(div);
|
2013-11-09 04:12:17 +00:00
|
|
|
div.data("name", data.name);
|
|
|
|
div.data("rank", data.rank);
|
|
|
|
div.data("leader", false);
|
|
|
|
div.data("profile", data.profile);
|
2013-11-09 18:33:18 +00:00
|
|
|
div.data("icon", data.meta.icon);
|
2013-11-15 01:50:17 +00:00
|
|
|
div.data("afk", data.meta.afk);
|
2013-08-07 21:00:53 +00:00
|
|
|
formatUserlistItem(div, data);
|
|
|
|
addUserDropdown(div, data);
|
|
|
|
div.appendTo($("#userlist"));
|
2013-08-08 14:54:07 +00:00
|
|
|
sortUserlist();
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
2013-11-15 01:50:17 +00:00
|
|
|
setUserProfile: function (data) {
|
|
|
|
var user = findUserlistItem(data.name);
|
|
|
|
if (user === null)
|
|
|
|
return;
|
|
|
|
user.data("profile", data.profile);
|
|
|
|
formatUserlistItem(user);
|
|
|
|
},
|
|
|
|
|
2013-11-09 03:46:30 +00:00
|
|
|
setLeader: function (name) {
|
|
|
|
$(".userlist_item").each(function () {
|
|
|
|
$(this).find(".icon-star-empty").remove();
|
2013-11-09 04:12:17 +00:00
|
|
|
if ($(this).data("leader")) {
|
|
|
|
$(this).data("leader", false);
|
|
|
|
addUserDropdown($(this));
|
|
|
|
}
|
2013-11-09 03:46:30 +00:00
|
|
|
});
|
2013-11-15 04:23:33 +00:00
|
|
|
if (name === "") {
|
|
|
|
CLIENT.leader = false;
|
|
|
|
if(LEADTMR)
|
|
|
|
clearInterval(LEADTMR);
|
|
|
|
LEADTMR = false;
|
2013-11-09 03:46:30 +00:00
|
|
|
return;
|
2013-11-15 04:23:33 +00:00
|
|
|
}
|
2013-11-09 03:46:30 +00:00
|
|
|
var user = findUserlistItem(name);
|
|
|
|
if (user) {
|
2013-11-09 04:12:17 +00:00
|
|
|
user.data("leader", true);
|
|
|
|
formatUserlistItem(user);
|
|
|
|
addUserDropdown(user);
|
|
|
|
}
|
|
|
|
if (name === CLIENT.name) {
|
|
|
|
CLIENT.leader = true;
|
|
|
|
// I'm a leader! Set up sync function
|
|
|
|
if(LEADTMR)
|
|
|
|
clearInterval(LEADTMR);
|
|
|
|
LEADTMR = setInterval(sendVideoUpdate, 5000);
|
2013-11-15 16:24:43 +00:00
|
|
|
handlePermissionChange();
|
|
|
|
} else if (CLIENT.leader) {
|
2013-11-09 04:12:17 +00:00
|
|
|
CLIENT.leader = false;
|
2013-11-15 16:24:43 +00:00
|
|
|
handlePermissionChange();
|
2013-11-09 04:12:17 +00:00
|
|
|
if(LEADTMR)
|
|
|
|
clearInterval(LEADTMR);
|
|
|
|
LEADTMR = false;
|
2013-11-09 03:46:30 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-11-09 04:12:17 +00:00
|
|
|
setUserRank: function (data) {
|
|
|
|
var user = findUserlistItem(data.name);
|
|
|
|
if (user === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
user.data("rank", data.rank);
|
2013-11-15 16:24:43 +00:00
|
|
|
if (data.name === CLIENT.name) {
|
|
|
|
CLIENT.rank = data.rank;
|
|
|
|
handlePermissionChange();
|
|
|
|
}
|
2013-11-09 04:12:17 +00:00
|
|
|
formatUserlistItem(user);
|
|
|
|
addUserDropdown(user);
|
|
|
|
if(USEROPTS.sort_rank)
|
|
|
|
sortUserlist();
|
|
|
|
},
|
|
|
|
|
2013-11-09 18:33:18 +00:00
|
|
|
setUserIcon: function (data) {
|
|
|
|
var user = findUserlistItem(data.name);
|
|
|
|
if (user === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
user.data("icon", data.icon);
|
|
|
|
formatUserlistItem(user);
|
|
|
|
},
|
|
|
|
|
2013-11-15 01:50:17 +00:00
|
|
|
/* DEPRECATED
|
|
|
|
SEE:
|
|
|
|
- setUserIcon
|
|
|
|
- setAFK
|
|
|
|
- setLeader
|
|
|
|
- setUserProfile
|
2013-11-15 16:24:43 +00:00
|
|
|
- setUserRank
|
2013-11-15 01:50:17 +00:00
|
|
|
*/
|
2013-08-07 21:00:53 +00:00
|
|
|
updateUser: function(data) {
|
|
|
|
if(data.name == CLIENT.name) {
|
|
|
|
CLIENT.leader = data.leader;
|
|
|
|
CLIENT.rank = data.rank;
|
|
|
|
handlePermissionChange();
|
|
|
|
if(CLIENT.leader) {
|
|
|
|
// I'm a leader! Set up sync function
|
|
|
|
if(LEADTMR)
|
|
|
|
clearInterval(LEADTMR);
|
2013-08-09 03:23:19 +00:00
|
|
|
LEADTMR = setInterval(sendVideoUpdate, 5000);
|
2013-08-07 21:00:53 +00:00
|
|
|
}
|
|
|
|
// I'm not a leader. Don't send syncs to the server
|
|
|
|
else {
|
|
|
|
if(LEADTMR)
|
|
|
|
clearInterval(LEADTMR);
|
|
|
|
LEADTMR = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2013-08-07 21:55:39 +00:00
|
|
|
var user = findUserlistItem(data.name);
|
|
|
|
if(user !== null) {
|
2013-11-09 04:12:17 +00:00
|
|
|
user.data("rank", data.rank);
|
2013-08-07 21:55:39 +00:00
|
|
|
formatUserlistItem(user, data);
|
|
|
|
addUserDropdown(user, data);
|
2013-08-08 22:28:10 +00:00
|
|
|
if(USEROPTS.sort_rank)
|
|
|
|
sortUserlist();
|
2013-08-07 21:55:39 +00:00
|
|
|
}
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
setAFK: function (data) {
|
2013-08-07 21:55:39 +00:00
|
|
|
var user = findUserlistItem(data.name);
|
|
|
|
if(user === null)
|
|
|
|
return;
|
2013-11-15 01:50:17 +00:00
|
|
|
user.data("afk", data.afk);
|
|
|
|
formatUserlistItem(user);
|
2013-08-08 14:54:07 +00:00
|
|
|
if(USEROPTS.sort_afk)
|
|
|
|
sortUserlist();
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
userLeave: function(data) {
|
2013-08-07 21:55:39 +00:00
|
|
|
var user = findUserlistItem(data.name);
|
|
|
|
if(user !== null)
|
|
|
|
user.remove();
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
drinkCount: function(count) {
|
|
|
|
if(count != 0) {
|
|
|
|
var text = count + " drink";
|
|
|
|
if(count != 1) {
|
|
|
|
text += "s";
|
|
|
|
}
|
|
|
|
$("#drinkcount").text(text);
|
|
|
|
$("#drinkbar").show();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$("#drinkbar").hide();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/* REGION Playlist Stuff */
|
|
|
|
playlist: function(data) {
|
2013-08-12 04:24:48 +00:00
|
|
|
PL_QUEUED_ACTIONS = [];
|
2013-08-07 21:00:53 +00:00
|
|
|
// Clear the playlist first
|
|
|
|
var q = $("#queue");
|
|
|
|
q.html("");
|
|
|
|
|
|
|
|
for(var i = 0; i < data.length; i++) {
|
|
|
|
var li = makeQueueEntry(data[i], false);
|
|
|
|
li.attr("title", data[i].queueby
|
|
|
|
? ("Added by: " + data[i].queueby)
|
|
|
|
: "Added by: Unknown");
|
|
|
|
li.appendTo(q);
|
|
|
|
}
|
|
|
|
|
|
|
|
rebuildPlaylist();
|
|
|
|
},
|
|
|
|
|
|
|
|
setPlaylistMeta: function(data) {
|
|
|
|
var c = data.count + " item";
|
|
|
|
if(data.count != 1)
|
|
|
|
c += "s";
|
|
|
|
$("#plcount").text(c);
|
|
|
|
$("#pllength").text(data.time);
|
|
|
|
},
|
|
|
|
|
|
|
|
queue: function(data) {
|
2013-10-01 18:35:29 +00:00
|
|
|
PL_ACTION_QUEUE.queue(function (plq) {
|
|
|
|
var li = makeQueueEntry(data.item, true);
|
|
|
|
if (data.item.uid === PL_CURRENT)
|
|
|
|
li.addClass("queue_active");
|
|
|
|
li.hide();
|
|
|
|
var q = $("#queue");
|
|
|
|
li.attr("title", data.item.queueby
|
|
|
|
? ("Added by: " + data.item.queueby)
|
|
|
|
: "Added by: Unknown");
|
|
|
|
if (data.after === "prepend") {
|
|
|
|
li.prependTo(q);
|
|
|
|
li.show("blind", function () {
|
|
|
|
plq.release();
|
|
|
|
});
|
|
|
|
} else if (data.after === "append") {
|
|
|
|
li.appendTo(q);
|
|
|
|
li.show("blind", function () {
|
|
|
|
plq.release();
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
var liafter = playlistFind(data.after);
|
|
|
|
if (!liafter) {
|
|
|
|
plq.release();
|
|
|
|
return;
|
2013-08-07 21:00:53 +00:00
|
|
|
}
|
2013-10-01 18:35:29 +00:00
|
|
|
li.insertAfter(liafter);
|
|
|
|
li.show("blind", function () {
|
|
|
|
plq.release();
|
|
|
|
});
|
2013-08-07 21:00:53 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2013-11-11 04:26:30 +00:00
|
|
|
queueWarn: function (data) {
|
|
|
|
queueMessage(data, "alert-warning");
|
|
|
|
},
|
|
|
|
|
2013-10-06 06:43:25 +00:00
|
|
|
queueFail: function (data) {
|
2013-11-11 04:26:30 +00:00
|
|
|
queueMessage(data, "alert-error");
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
setTemp: function(data) {
|
|
|
|
var li = $(".pluid-" + data.uid);
|
|
|
|
if(li.length == 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if(data.temp)
|
|
|
|
li.addClass("queue_temp");
|
|
|
|
else
|
|
|
|
li.removeClass("queue_temp");
|
|
|
|
|
|
|
|
li.data("temp", data.temp);
|
|
|
|
var btn = li.find(".qbtn-tmp");
|
|
|
|
if(btn.length > 0) {
|
|
|
|
if(data.temp) {
|
|
|
|
btn.html(btn.html().replace("Make Temporary",
|
|
|
|
"Make Permanent"));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
btn.html(btn.html().replace("Make Permanent",
|
|
|
|
"Make Temporary"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
"delete": function(data) {
|
2013-10-01 18:35:29 +00:00
|
|
|
PL_ACTION_QUEUE.queue(function (plq) {
|
|
|
|
PL_WAIT_SCROLL = true;
|
|
|
|
var li = $(".pluid-" + data.uid);
|
|
|
|
li.hide("blind", function() {
|
|
|
|
li.remove();
|
|
|
|
plq.release();
|
|
|
|
PL_WAIT_SCROLL = false;
|
|
|
|
});
|
2013-08-07 21:00:53 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
moveVideo: function(data) {
|
2013-10-04 03:11:47 +00:00
|
|
|
PL_ACTION_QUEUE.queue(function (plq) {
|
|
|
|
playlistMove(data.from, data.after, function () {
|
|
|
|
plq.release();
|
2013-08-07 21:00:53 +00:00
|
|
|
});
|
2013-10-04 03:11:47 +00:00
|
|
|
});
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
setCurrent: function(uid) {
|
2013-10-01 18:25:05 +00:00
|
|
|
PL_CURRENT = uid;
|
|
|
|
$("#queue li").removeClass("queue_active");
|
|
|
|
var li = $(".pluid-" + uid);
|
|
|
|
if (li.length !== 0) {
|
|
|
|
li.addClass("queue_active");
|
|
|
|
var tmr = setInterval(function () {
|
|
|
|
if (!PL_WAIT_SCROLL) {
|
|
|
|
scrollQueue();
|
|
|
|
clearInterval(tmr);
|
2013-08-07 21:00:53 +00:00
|
|
|
}
|
2013-10-01 18:25:05 +00:00
|
|
|
}, 100);
|
|
|
|
}
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
changeMedia: function(data) {
|
2013-12-31 16:09:30 +00:00
|
|
|
if (PLAYER) {
|
|
|
|
PLAYER.getVolume(function (v) {
|
|
|
|
VOLUME = v;
|
2014-01-02 05:13:45 +00:00
|
|
|
setOpt("volume", VOLUME);
|
2013-12-31 16:09:30 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-08-07 21:00:53 +00:00
|
|
|
if(CHANNEL.opts.allow_voteskip)
|
|
|
|
$("#voteskip").attr("disabled", false);
|
|
|
|
|
|
|
|
$("#currenttitle").text("Currently Playing: " + data.title);
|
|
|
|
|
|
|
|
if(data.type != "sc" && PLAYER.type == "sc")
|
|
|
|
// [](/goddamnitmango)
|
|
|
|
fixSoundcloudShit();
|
|
|
|
|
|
|
|
if(data.type != "jw" && PLAYER.type == "jw") {
|
|
|
|
// Is it so hard to not mess up my DOM?
|
|
|
|
$("<div/>").attr("id", "ytapiplayer")
|
|
|
|
.insertBefore($("#ytapiplayer_wrapper"));
|
|
|
|
$("#ytapiplayer_wrapper").remove();
|
|
|
|
}
|
|
|
|
|
2014-01-07 17:32:48 +00:00
|
|
|
if (data.type === "vi" && data.direct && data.direct.sd) {
|
2014-01-07 23:14:16 +00:00
|
|
|
data.type = "rv";
|
2014-01-07 17:32:48 +00:00
|
|
|
data.url = data.direct.sd.url;
|
2014-01-07 06:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (data.type != PLAYER.type) {
|
2013-08-07 21:00:53 +00:00
|
|
|
loadMediaPlayer(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleMediaUpdate(data);
|
|
|
|
},
|
|
|
|
|
|
|
|
mediaUpdate: function(data) {
|
|
|
|
handleMediaUpdate(data);
|
|
|
|
},
|
|
|
|
|
|
|
|
setPlaylistLocked: function(data) {
|
|
|
|
CHANNEL.openqueue = !data.locked;
|
|
|
|
handlePermissionChange();
|
|
|
|
if(CHANNEL.openqueue) {
|
|
|
|
$("#qlockbtn").removeClass("btn-danger")
|
|
|
|
.addClass("btn-success")
|
|
|
|
.attr("title", "Playlist Unlocked");
|
|
|
|
$("#qlockbtn").find("i")
|
|
|
|
.removeClass("icon-lock")
|
|
|
|
.addClass("icon-ok");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$("#qlockbtn").removeClass("btn-success")
|
|
|
|
.addClass("btn-danger")
|
|
|
|
.attr("title", "Playlist Locked");
|
|
|
|
$("#qlockbtn").find("i")
|
|
|
|
.removeClass("icon-ok")
|
|
|
|
.addClass("icon-lock");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
searchResults: function(data) {
|
|
|
|
$("#search_clear").remove();
|
|
|
|
clearSearchResults();
|
|
|
|
$("#library").data("entries", data.results);
|
|
|
|
$("<button/>").addClass("btn btn-block")
|
|
|
|
.addClass("span12")
|
|
|
|
.css("margin-left", "0")
|
|
|
|
.attr("id", "search_clear")
|
|
|
|
.text("Clear Results")
|
|
|
|
.click(function() {
|
|
|
|
clearSearchResults();
|
|
|
|
})
|
|
|
|
.insertBefore($("#library"));
|
2013-09-24 20:19:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
$("#search_pagination").remove();
|
2013-09-24 18:19:41 +00:00
|
|
|
var opts = {
|
|
|
|
preLoadPage: function () {
|
|
|
|
$("#library").html("");
|
|
|
|
},
|
2013-08-07 21:00:53 +00:00
|
|
|
|
2013-09-24 18:19:41 +00:00
|
|
|
generator: function (item, page, index) {
|
|
|
|
var li = makeSearchEntry(item, false);
|
|
|
|
if(hasPermission("playlistadd")) {
|
|
|
|
addLibraryButtons(li, item.id, data.source);
|
|
|
|
}
|
|
|
|
$(li).appendTo($("#library"));
|
|
|
|
},
|
2013-08-07 21:00:53 +00:00
|
|
|
|
2013-09-24 18:19:41 +00:00
|
|
|
itemsPerPage: 100
|
|
|
|
};
|
2013-08-07 21:00:53 +00:00
|
|
|
|
2013-09-24 18:19:41 +00:00
|
|
|
var p = Paginate(data.results, opts);
|
|
|
|
p.paginator.insertBefore($("#library"))
|
|
|
|
.attr("id", "search_pagination");
|
|
|
|
$("#library").data("paginator", p);
|
2013-08-07 21:00:53 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/* REGION Polls */
|
|
|
|
newPoll: function(data) {
|
|
|
|
Callbacks.closePoll();
|
|
|
|
var pollMsg = $("<div/>").addClass("poll-notify")
|
2013-12-01 23:20:42 +00:00
|
|
|
.html(data.initiator + " opened a poll: \"" + data.title + "\"")
|
2013-08-07 21:00:53 +00:00
|
|
|
.appendTo($("#messagebuffer"));
|
|
|
|
scrollChat();
|
|
|
|
|
|
|
|
var poll = $("<div/>").addClass("well active").prependTo($("#pollwrap"));
|
|
|
|
$("<button/>").addClass("close pull-right").html("×")
|
|
|
|
.appendTo(poll)
|
|
|
|
.click(function() { poll.remove(); });
|
|
|
|
if(hasPermission("pollctl")) {
|
|
|
|
$("<button/>").addClass("btn btn-danger pull-right").text("End Poll")
|
|
|
|
.appendTo(poll)
|
|
|
|
.click(function() {
|
|
|
|
socket.emit("closePoll")
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2013-12-01 23:20:42 +00:00
|
|
|
$("<h3/>").html(data.title).appendTo(poll);
|
2013-08-07 21:00:53 +00:00
|
|
|
for(var i = 0; i < data.options.length; i++) {
|
|
|
|
(function(i) {
|
2013-09-21 05:25:00 +00:00
|
|
|
var callback = function () {
|
|
|
|
socket.emit("vote", {
|
|
|
|
option: i
|
|
|
|
});
|
|
|
|
poll.find(".option button").each(function() {
|
|
|
|
$(this).attr("disabled", "disabled");
|
|
|
|
});
|
|
|
|
$(this).parent().addClass("option-selected");
|
2013-08-07 21:00:53 +00:00
|
|
|
}
|
|
|
|
$("<button/>").addClass("btn").text(data.counts[i])
|
2013-12-01 23:20:42 +00:00
|
|
|
.prependTo($("<div/>").addClass("option").html(data.options[i])
|
2013-08-07 21:00:53 +00:00
|
|
|
.appendTo(poll))
|
|
|
|
.click(callback);
|
|
|
|
})(i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
poll.find(".btn").attr("disabled", !hasPermission("pollvote"));
|
|
|
|
},
|
|
|
|
|
|
|
|
updatePoll: function(data) {
|
|
|
|
var poll = $("#pollwrap .active");
|
|
|
|
var i = 0;
|
|
|
|
poll.find(".option button").each(function() {
|
2013-09-21 05:25:00 +00:00
|
|
|
$(this).html(data.counts[i]);
|
2013-08-07 21:00:53 +00:00
|
|
|
i++;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
closePoll: function() {
|
|
|
|
if($("#pollwrap .active").length != 0) {
|
|
|
|
var poll = $("#pollwrap .active");
|
|
|
|
poll.removeClass("active").addClass("muted");
|
|
|
|
poll.find(".option button").each(function() {
|
|
|
|
$(this).attr("disabled", true);
|
|
|
|
});
|
|
|
|
poll.find(".btn-danger").each(function() {
|
|
|
|
$(this).remove()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
savePlaylist: function(data) {
|
|
|
|
if(data.success) {
|
|
|
|
makeAlert("Success", "Playlist saved.", "alert-success");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
makeAlert("Error", data.error, "alert-error")
|
|
|
|
.addClass("span12")
|
|
|
|
.insertBefore($("#userpl_list"));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
listPlaylists: function(data) {
|
|
|
|
if(data.error) {
|
|
|
|
makeAlert("Error", data.error, "alert-error")
|
|
|
|
.addClass("span12")
|
|
|
|
.insertBefore($("#userpl_list"));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
var pls = data.pllist;
|
|
|
|
pls.sort(function(a, b) {
|
|
|
|
var x = a.name.toLowerCase();
|
|
|
|
var y = b.name.toLowerCase();
|
|
|
|
if(x < y) return -1;
|
|
|
|
if(x > y) return 1;
|
|
|
|
return 0;
|
|
|
|
});
|
|
|
|
$("#userpl_list").html("");
|
|
|
|
for(var i = 0; i < pls.length; i++) {
|
|
|
|
var li = $("<li/>").appendTo($("#userpl_list"))
|
|
|
|
.addClass("well");
|
|
|
|
li.data("pl-name", pls[i].name);
|
|
|
|
$("<div/>").text(pls[i].name).appendTo(li)
|
|
|
|
.css("float", "left")
|
|
|
|
.css("margin-left", "1em");
|
|
|
|
var metastr = pls[i].count + " item";
|
|
|
|
if(pls[i].count != 1) {
|
|
|
|
metastr += "s";
|
|
|
|
}
|
|
|
|
metastr +=", playtime " + pls[i].time;
|
|
|
|
$("<div/>").text(metastr)
|
|
|
|
.css("float", "right")
|
|
|
|
.appendTo(li);
|
|
|
|
var bg = $("<div/>").addClass("btn-group")
|
|
|
|
.css("float", "left")
|
|
|
|
.prependTo(li);
|
|
|
|
var del = $("<button/>")
|
|
|
|
.addClass("btn btn-mini btn-danger")
|
|
|
|
.prependTo(bg);
|
|
|
|
$("<i/>").addClass("icon-trash").appendTo(del);
|
|
|
|
(function(li) {
|
|
|
|
del.click(function() {
|
|
|
|
var go = confirm("Are you sure you want to delete playlist '" + li.data("pl-name") + "'?");
|
|
|
|
if(go) {
|
|
|
|
socket.emit("deletePlaylist", {
|
|
|
|
name: li.data("pl-name")
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
})(li);
|
|
|
|
if(hasPermission("playlistaddlist")) {
|
|
|
|
(function(li) {
|
|
|
|
$("<button/>").addClass("btn btn-mini")
|
|
|
|
.text("End")
|
|
|
|
.prependTo(bg)
|
|
|
|
.click(function() {
|
|
|
|
socket.emit("queuePlaylist", {
|
|
|
|
name: li.data("pl-name"),
|
|
|
|
pos: "end"
|
|
|
|
});
|
|
|
|
});
|
|
|
|
})(li);
|
|
|
|
|
|
|
|
if(hasPermission("playlistnext")) {
|
|
|
|
(function(li) {
|
|
|
|
$("<button/>").addClass("btn btn-mini")
|
|
|
|
.text("Next")
|
|
|
|
.prependTo(bg)
|
|
|
|
.click(function() {
|
|
|
|
socket.emit("queuePlaylist", {
|
|
|
|
name: li.data("pl-name"),
|
|
|
|
pos: "next"
|
|
|
|
});
|
|
|
|
});
|
|
|
|
})(li);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var SOCKET_DEBUG = false;
|
|
|
|
setupCallbacks = function() {
|
|
|
|
for(var key in Callbacks) {
|
|
|
|
(function(key) {
|
|
|
|
socket.on(key, function(data) {
|
|
|
|
if(SOCKET_DEBUG)
|
|
|
|
console.log(key, data);
|
|
|
|
Callbacks[key](data);
|
|
|
|
});
|
|
|
|
})(key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$.getScript(IO_URL+"/socket.io/socket.io.js", function() {
|
|
|
|
try {
|
|
|
|
if(NO_WEBSOCKETS || USEROPTS.altsocket) {
|
|
|
|
var i = io.transports.indexOf("websocket");
|
|
|
|
if(i >= 0)
|
|
|
|
io.transports.splice(i, 1);
|
|
|
|
}
|
2013-09-09 22:16:41 +00:00
|
|
|
var opts = {};
|
|
|
|
if (location.protocol === "https:")
|
|
|
|
opts.secure = true;
|
2013-08-07 21:00:53 +00:00
|
|
|
socket = io.connect(IO_URL);
|
|
|
|
setupCallbacks();
|
|
|
|
}
|
|
|
|
catch(e) {
|
|
|
|
Callbacks.disconnect();
|
|
|
|
}
|
|
|
|
});
|