sync/www/js/callbacks.js

1309 lines
40 KiB
JavaScript
Raw Normal View History

2013-08-07 21:00:53 +00:00
Callbacks = {
/* fired when socket connection completes */
connect: function() {
HAS_CONNECTED_BEFORE = true;
SOCKETIO_CONNECT_ERROR_COUNT = 0;
$("#socketio-connect-error").remove();
2013-08-07 21:00:53 +00:00
socket.emit("joinChannel", {
name: CHANNEL.name
});
2014-01-19 02:18:00 +00:00
2013-11-25 22:20:15 +00:00
if (CHANNEL.opts.password) {
socket.emit("channelPassword", CHANNEL.opts.password);
}
2014-01-19 02:18:00 +00:00
if (CLIENT.name && CLIENT.guest) {
2013-08-07 21:00:53 +00:00
socket.emit("login", {
name: CLIENT.name
});
}
2014-01-19 02:18:00 +00:00
2013-08-07 21:00:53 +00:00
$("<div/>").addClass("server-msg-reconnect")
.text("Connected")
.appendTo($("#messagebuffer"));
2013-12-15 03:59:47 +00:00
scrollChat();
stopQueueSpinner(null);
2013-08-07 21:00:53 +00:00
},
disconnect: function() {
if(KICKED)
return;
$("<div/>")
.addClass("server-msg-disconnect")
.text("Disconnected from server.")
2013-08-07 21:00:53 +00:00
.appendTo($("#messagebuffer"));
scrollChat();
},
2017-08-02 02:29:11 +00:00
// Socket.IO error callback
error: function (msg) {
2017-12-07 06:09:13 +00:00
window.SOCKET_ERROR_REASON = msg;
2017-08-02 02:29:11 +00:00
$("<div/>")
.addClass("server-msg-disconnect")
.text("Unable to connect: " + msg)
.appendTo($("#messagebuffer"));
},
2013-08-07 21:00:53 +00:00
errorMsg: function(data) {
2014-02-06 00:05:52 +00:00
if (data.alert) {
alert(data.msg);
} else {
errDialog(data.msg);
}
2013-08-07 21:00:53 +00:00
},
2013-08-18 23:35:49 +00:00
costanza: function (data) {
$("#costanza-modal").modal("hide");
2013-12-15 03:59:47 +00:00
var modal = makeModal();
modal.attr("id", "costanza-modal")
2013-08-18 23:35:49 +00:00
.appendTo($("body"));
2013-12-15 03:59:47 +00:00
var body = $("<div/>").addClass("modal-body")
.appendTo(modal.find(".modal-content"));
2013-08-18 23:35:49 +00:00
$("<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.modal();
},
2013-08-07 21:00:53 +00:00
announcement: function(data) {
// Suppress this announcement for people who have already closed it
if (data.id && CyTube.ui.suppressedAnnouncementId
&& data.id === CyTube.ui.suppressedAnnouncementId) {
return;
}
2013-08-07 21:00:53 +00:00
$("#announcements").html("");
var signature = "<br>\u2014" + data.from;
var announcement = makeAlert(data.title, data.text + signature)
2013-08-07 21:00:53 +00:00
.appendTo($("#announcements"));
if (data.id) {
announcement.find(".close").click(function suppressThisAnnouncement() {
CyTube.ui.suppressedAnnouncementId = data.id;
setOpt("suppressed_announcement_id", data.id);
});
}
2013-08-07 21:00:53 +00:00
},
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();
},
spamFiltered: function(data) {
var message = "Spam Filtered.";
switch (data.reason) {
case "NEW_USER_CHAT":
message = "Your account is too new to chat in this channel. " +
"Please wait a while and try again.";
break;
case "NEW_USER_CHAT_LINK":
message = "Your account is too new to post links in this channel. " +
"Please wait a while and try again.";
break;
}
errDialog(message);
},
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);
}
2013-12-15 03:59:47 +00:00
var pwbox = $("<input/>").addClass("form-control")
2013-11-25 22:20:15 +00:00
.attr("type", "password")
.appendTo(div);
2013-12-15 03:59:47 +00:00
var submit = $("<button/>").addClass("btn btn-xs btn-default btn-block")
.css("margin-top", "5px")
2013-11-25 22:20:15 +00:00
.text("Submit")
.appendTo(div);
var parent = chatDialog(div);
parent.attr("id", "needpw");
var sendpw = function () {
2014-01-26 03:29:56 +00:00
socket.emit("channelPassword", pwbox.val());
2013-11-25 22:20:15 +00:00
parent.remove();
};
submit.click(sendpw);
pwbox.keydown(function (ev) {
if (ev.keyCode == 13) {
sendpw();
}
});
pwbox.focus();
},
cancelNeedPassword: function () {
$("#needpw").remove();
},
2014-05-21 03:11:40 +00:00
cooldown: function (time) {
2013-11-19 21:14:40 +00:00
time = time + 200;
$("#chatline").css("color", "#ff0000");
2015-04-24 02:49:01 +00:00
$(".pm-input").css("color", "#ff0000");
2013-11-19 21:14:40 +00:00
if (CHATTHROTTLE && $("#chatline").data("throttle_timer")) {
clearTimeout($("#chatline").data("throttle_timer"));
}
CHATTHROTTLE = true;
$("#chatline").data("throttle_timer", setTimeout(function () {
CHATTHROTTLE = false;
$("#chatline").css("color", "");
2015-04-24 02:49:01 +00:00
$(".pm-input").css("color", "");
2013-11-19 21:14:40 +00:00
}, time));
},
2013-08-07 21:00:53 +00:00
channelNotRegistered: function() {
var div = $("<div/>").addClass("alert alert-info")
2014-02-02 18:41:41 +00:00
.appendTo($("<div/>").addClass("col-md-12").appendTo($("#announcements")));
$("<button/>").addClass("close pull-right")
2013-08-07 21:00:53 +00:00
.appendTo(div)
2014-02-02 18:41:41 +00:00
.click(function () {
div.parent().remove();
})
.html("&times;");
$("<h4/>").appendTo(div).text("Unregistered channel");
$("<p/>").appendTo(div)
.html("This channel is not registered to a CyTube account. You can still " +
"use it, but some features will not be available. To register a " +
"channel to your account, visit your <a href='/account/channels'>" +
"channels</a> page.");
2013-08-07 21:00:53 +00:00
},
setMotd: function(motd) {
CHANNEL.motd = motd;
$("#motd").html(motd);
$("#cs-motdtext").val(motd);
2015-01-17 01:35:26 +00:00
if (motd != "") {
2013-10-03 03:26:28 +00:00
$("#motdwrap").show();
2013-08-07 21:00:53 +00:00
$("#motd").show();
2013-12-15 03:59:47 +00:00
$("#togglemotd").find(".glyphicon-plus")
.removeClass("glyphicon-plus")
.addClass("glyphicon-minus");
2014-05-21 03:11:40 +00:00
} else {
2013-10-03 03:26:28 +00:00
$("#motdwrap").hide();
2014-05-21 03:11:40 +00:00
}
2013-08-07 21:00:53 +00:00
},
chatFilters: function(entries) {
2014-01-16 17:53:34 +00:00
var tbl = $("#cs-chatfilters table");
tbl.data("entries", entries);
formatCSChatFilterList();
2013-08-07 21:00:53 +00:00
},
2014-01-19 02:18:00 +00:00
updateChatFilter: function (f) {
var entries = $("#cs-chatfilters table").data("entries") || [];
var found = false;
for (var i = 0; i < entries.length; i++) {
if (entries[i].name === f.name) {
entries[i] = f;
found = true;
break;
}
}
if (!found) {
entries.push(f);
}
$("#cs-chatfilters table").data("entries", entries);
formatCSChatFilterList();
},
deleteChatFilter: function (f) {
var entries = $("#cs-chatfilters table").data("entries") || [];
var found = false;
for (var i = 0; i < entries.length; i++) {
if (entries[i].name === f.name) {
entries[i] = f;
found = i;
break;
}
}
if (found !== false) {
entries.splice(found, 1);
}
$("#cs-chatfilters table").data("entries", entries);
formatCSChatFilterList();
},
2013-08-07 21:00:53 +00:00
channelOpts: function(opts) {
document.title = opts.pagetitle;
PAGETITLE = opts.pagetitle;
2014-08-27 23:45:11 +00:00
if (!USEROPTS.ignore_channelcss &&
opts.externalcss !== CHANNEL.opts.externalcss) {
$("#chanexternalcss").remove();
if (opts.externalcss.trim() !== "") {
$("#chanexternalcss").remove();
$("<link/>")
.attr("rel", "stylesheet")
.attr("href", opts.externalcss)
.attr("id", "chanexternalcss")
.appendTo($("head"));
}
2013-08-07 21:00:53 +00:00
}
if(opts.externaljs.trim() != "" && !USEROPTS.ignore_channeljs &&
opts.externaljs !== CHANNEL.opts.externaljs) {
checkScriptAccess(opts.externaljs, "external", function (pref) {
if (pref === "ALLOW") {
$.getScript(opts.externaljs);
}
});
2013-08-07 21:00:53 +00:00
}
CHANNEL.opts = opts;
if(opts.allow_voteskip)
$("#voteskip").attr("disabled", false);
else
$("#voteskip").attr("disabled", true);
handlePermissionChange();
},
setPermissions: function(perms) {
CHANNEL.perms = perms;
2014-01-20 18:16:30 +00:00
genPermissionsEditor();
2013-08-07 21:00:53 +00:00
handlePermissionChange();
},
channelCSSJS: function(data) {
$("#chancss").remove();
CHANNEL.css = data.css;
$("#cs-csstext").val(data.css);
2013-08-07 21:00:53 +00:00
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;
$("#cs-jstext").val(data.js);
2013-08-07 21:00:53 +00:00
if(data.js && !USEROPTS.ignore_channeljs) {
var src = data.js
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/\n/g, "<br>")
.replace(/\t/g, " ")
.replace(/ /g, "&nbsp;");
src = encodeURIComponent(src);
var viewsource = "data:text/html, <body style='font: 9pt monospace;" +
"max-width:60rem;margin:0 auto;padding:4rem;'>" +
src + "</body>";
checkScriptAccess(viewsource, "embedded", function (pref) {
if (pref === "ALLOW") {
$("<script/>").attr("type", "text/javascript")
.attr("id", "chanjs")
.text(data.js)
.appendTo($("body"));
}
});
2013-08-07 21:00:53 +00:00
}
},
banlist: function(entries) {
2014-01-09 02:12:02 +00:00
var tbl = $("#cs-banlist table");
2014-01-09 23:43:07 +00:00
tbl.data("entries", entries);
formatCSBanlist();
2014-01-12 23:06:25 +00:00
},
banlistRemove: function (data) {
var entries = $("#cs-banlist table").data("entries") || [];
var found = false;
for (var i = 0; i < entries.length; i++) {
if (entries[i].id === data.id) {
found = i;
break;
}
}
if (found !== false) {
entries.splice(i, 1);
$("#cs-banlist table").data("entries", entries);
}
formatCSBanlist();
2013-08-07 21:00:53 +00:00
},
channelRanks: function(entries) {
2014-01-09 02:12:02 +00:00
var tbl = $("#cs-chanranks table");
2014-01-09 23:16:09 +00:00
tbl.data("entries", entries);
formatCSModList();
2013-08-07 21:00:53 +00:00
},
2014-01-09 05:45:26 +00:00
channelRankFail: function (data) {
2014-05-21 03:11:40 +00:00
if ($("#cs-chanranks").is(":visible")) {
makeAlert("Error", data.msg, "alert-danger")
.removeClass().addClass("vertical-spacer")
.insertAfter($("#cs-chanranks form"));
} else {
Callbacks.noflood({ action: "/rank", msg: data.msg });
}
2013-08-07 21:00:53 +00:00
},
readChanLog: function (data) {
2014-02-08 18:45:07 +00:00
var log = $("#cs-chanlog-text");
if (log.length == 0)
2013-08-07 21:00:53 +00:00
return;
2014-02-08 18:45:07 +00:00
if (data.success) {
setupChanlogFilter(data.data);
2013-11-16 05:56:25 +00:00
filterChannelLog();
2013-08-07 21:00:53 +00:00
} else {
2014-02-08 18:45:07 +00:00
$("#cs-chanlog-text").text("Error reading channel log");
2013-08-07 21:00:53 +00:00
}
},
voteskip: function(data) {
2014-01-14 00:31:12 +00:00
var icon = $("#voteskip").find(".glyphicon").remove();
2013-08-07 21:00:53 +00:00
if(data.count > 0) {
2014-01-14 00:31:12 +00:00
$("#voteskip").text(" ("+data.count+"/"+data.need+")");
} else {
$("#voteskip").text("");
2013-08-07 21:00:53 +00:00
}
2014-01-14 00:31:12 +00:00
icon.prependTo($("#voteskip"));
2013-08-07 21:00:53 +00:00
},
/* REGION Rank Stuff */
rank: function(r) {
if(r >= 255)
SUPERADMIN = true;
CLIENT.rank = r;
handlePermissionChange();
if(SUPERADMIN && $("#setrank").length == 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>");
}
},
login: function(data) {
2014-02-02 18:41:41 +00:00
if (!data.success) {
if (data.error != "Session expired") {
errDialog(data.error);
2013-08-07 21:00:53 +00:00
}
2014-02-02 18:41:41 +00:00
} else {
2013-08-07 21:00:53 +00:00
CLIENT.name = data.name;
2014-01-19 02:18:00 +00:00
CLIENT.guest = data.guest;
2013-08-07 21:00:53 +00:00
CLIENT.logged_in = true;
2014-02-02 18:41:41 +00:00
if (!CLIENT.guest) {
socket.emit("initUserPLCallbacks");
}
2013-08-07 21:00:53 +00:00
}
},
/* 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);
},
2014-02-15 07:40:14 +00:00
pm: function (data) {
var name = data.username;
if (IGNORED.indexOf(name) !== -1) {
return;
}
if (data.username === CLIENT.name) {
name = data.to;
} else {
pingMessage(true);
2014-02-15 07:40:14 +00:00
}
var pm = initPm(name);
var msg = formatChatMessage(data, pm.data("last"));
var buffer = pm.find(".pm-buffer");
msg.appendTo(buffer);
buffer.scrollTop(buffer.prop("scrollHeight"));
if (pm.find(".panel-body").is(":hidden")) {
pm.removeClass("panel-default").addClass("panel-primary");
}
},
2013-08-07 21:00:53 +00:00
clearchat: function() {
$("#messagebuffer").html("");
2015-10-26 00:31:04 +00:00
LASTCHAT.name = "";
2013-08-07 21:00:53 +00:00
},
userlist: function(data) {
2013-12-19 04:50:19 +00:00
$(".userlist_item").remove();
2013-08-07 21:00:53 +00:00
for(var i = 0; i < data.length; i++) {
CyTube._internal_do_not_use_or_you_will_be_banned.addUserToList(data[i]);
2013-08-07 21:00:53 +00:00
}
sortUserlist();
2013-08-07 21:00:53 +00:00
},
addUser: function(data) {
CyTube._internal_do_not_use_or_you_will_be_banned.addUserToList(data);
2013-08-08 14:54:07 +00:00
sortUserlist();
2013-08-07 21:00:53 +00:00
},
2014-01-08 04:47:00 +00:00
setUserMeta: function (data) {
var user = findUserlistItem(data.name);
if (user == null) {
return;
}
user.data("meta", data.meta);
if (data.meta.muted || data.meta.smuted) {
user.data("icon", "glyphicon-volume-off");
} else {
user.data("icon", false);
}
/*
* 2017-06-15
* TODO: Remove this and the empty function below
* after script authors have had ample time to update
*/
socket.listeners('setAFK').forEach(function(listener){
2017-06-30 02:04:49 +00:00
listener({ name: data.name, afk: data.meta.afk });
});
formatUserlistItem(user, data);
addUserDropdown(user, data);
sortUserlist();
2014-01-08 04:47:00 +00:00
},
setAFK: function() {
return true;
},
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 () {
2013-12-19 04:50:19 +00:00
$(this).find(".glyphicon-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) {
2014-02-16 08:16:58 +00:00
data.name = data.name.toLowerCase();
var entries = $("#cs-chanranks table").data("entries") || [];
2014-01-09 23:16:09 +00:00
var found = false;
for (var i = 0; i < entries.length; i++) {
2014-02-16 08:16:58 +00:00
if (entries[i].name.toLowerCase() === data.name) {
2014-01-09 23:16:09 +00:00
entries[i].rank = data.rank;
found = i;
break;
}
}
if (found === false) {
entries.push(data);
} else if (entries[found].rank < 2) {
entries.splice(found, 1);
}
formatCSModList();
2014-01-09 05:45:26 +00:00
2013-11-09 04:12:17 +00:00
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);
2014-01-09 05:45:26 +00:00
if (USEROPTS.sort_rank) {
2013-11-09 04:12:17 +00:00
sortUserlist();
2014-01-09 05:45:26 +00:00
}
2013-11-09 04:12:17 +00:00
},
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) {
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) {
stopQueueSpinner(data.item.media);
2013-10-01 18:35:29 +00:00
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);
2014-01-14 06:52:56 +00:00
li.show("fade", function () {
2013-10-01 18:35:29 +00:00
plq.release();
});
} else if (data.after === "append") {
li.appendTo(q);
2014-01-14 06:52:56 +00:00
li.show("fade", function () {
2013-10-01 18:35:29 +00:00
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);
2014-01-14 06:52:56 +00:00
li.show("fade", function () {
2013-10-01 18:35:29 +00:00
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) {
if (data.id) {
2016-05-26 00:39:22 +00:00
stopQueueSpinner(data);
}
2013-12-19 04:50:19 +00:00
queueMessage(data, "alert-danger");
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);
2014-01-14 06:52:56 +00:00
li.hide("fade", function() {
2013-10-01 18:35:29 +00:00
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) {
2014-05-30 03:44:09 +00:00
if ($("body").hasClass("chatOnly") || $("#videowrap").length === 0) {
2014-02-18 01:06:49 +00:00
return;
}
2015-05-02 16:45:35 +00:00
// Failsafe
if (isNaN(VOLUME) || VOLUME > 1 || VOLUME < 0) {
2014-05-21 04:10:08 +00:00
VOLUME = 1;
}
2015-05-02 22:37:09 +00:00
function loadNext() {
2015-07-01 16:38:01 +00:00
if (!PLAYER || data.type !== PLAYER.mediaType) {
2015-05-02 22:37:09 +00:00
loadMediaPlayer(data);
2017-12-16 08:05:28 +00:00
} else {
handleMediaUpdate(data);
2015-05-02 22:37:09 +00:00
}
}
2015-05-02 16:45:35 +00:00
// Persist the user's volume preference from the the player, if possible
if (PLAYER && typeof PLAYER.getVolume === "function") {
PLAYER.getVolume(function (v) {
if (typeof v === "number") {
if (v < 0 || v > 1) {
2015-05-02 16:45:35 +00:00
// Dailymotion's API was wrong once and caused a huge
// headache. This alert is here to make debugging easier.
alert("Something went wrong with retrieving the volume. " +
"Please tell calzoneman the following: " +
2015-05-02 16:45:35 +00:00
JSON.stringify({
v: v,
t: PLAYER.mediaType,
i: PLAYER.mediaId
}));
} else {
VOLUME = v;
setOpt("volume", VOLUME);
}
}
2015-05-02 22:37:09 +00:00
loadNext();
});
2015-05-02 22:37:09 +00:00
} else {
loadNext();
}
2015-05-02 16:45:35 +00:00
// Reset voteskip since the video changed
if (CHANNEL.opts.allow_voteskip) {
2013-08-07 21:00:53 +00:00
$("#voteskip").attr("disabled", false);
}
$("#currenttitle").text("Currently Playing: " + data.title);
2013-08-07 21:00:53 +00:00
},
mediaUpdate: function(data) {
2014-08-22 01:32:58 +00:00
if ($("body").hasClass("chatOnly") || $("#videowrap").length === 0) {
2014-02-18 01:06:49 +00:00
return;
}
2015-07-01 16:38:01 +00:00
if (PLAYER) {
handleMediaUpdate(data);
}
2013-08-07 21:00:53 +00:00
},
2014-01-08 04:47:00 +00:00
setPlaylistLocked: function (locked) {
CHANNEL.openqueue = !locked;
2013-08-07 21:00:53 +00:00
handlePermissionChange();
if(CHANNEL.openqueue) {
$("#qlockbtn").removeClass("btn-danger")
.addClass("btn-success")
.attr("title", "Playlist Unlocked");
2014-01-14 00:31:12 +00:00
$("#qlockbtn").find("span")
2013-12-19 04:50:19 +00:00
.removeClass("glyphicon-lock")
.addClass("glyphicon-ok");
2013-08-07 21:00:53 +00:00
}
else {
$("#qlockbtn").removeClass("btn-success")
.addClass("btn-danger")
.attr("title", "Playlist Locked");
2014-01-14 00:31:12 +00:00
$("#qlockbtn").find("span")
2013-12-19 04:50:19 +00:00
.removeClass("glyphicon-ok")
.addClass("glyphicon-lock");
2013-08-07 21:00:53 +00:00
}
},
searchResults: function(data) {
$("#search_clear").remove();
clearSearchResults();
$("#library").data("entries", data.results);
2013-12-19 04:50:19 +00:00
$("<button/>").addClass("btn btn-default btn-sm btn-block")
2013-08-07 21:00:53 +00:00
.css("margin-left", "0")
.attr("id", "search_clear")
.text("Clear Results")
.click(function() {
clearSearchResults();
})
.insertBefore($("#library"));
$("#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") || hasPermission("deletefromchannellib")) {
addLibraryButtons(li, item, data.source);
2013-09-24 18:19:41 +00:00
}
$(li).appendTo($("#library"));
},
2013-08-07 21:00:53 +00:00
2014-02-25 00:25:49 +00:00
itemsPerPage: 100
2013-09-24 18:19:41 +00:00
};
2013-08-07 21:00:53 +00:00
2013-09-24 18:19:41 +00:00
var p = Paginate(data.results, opts);
2014-01-22 04:41:53 +00:00
p.paginator.insertAfter($("#library"))
.addClass("pull-right")
2013-09-24 18:19:41 +00:00
.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("&times;")
.appendTo(poll)
.click(function() { poll.remove(); });
if(hasPermission("pollctl")) {
2013-12-19 04:50:19 +00:00
$("<button/>").addClass("btn btn-danger btn-sm pull-right").text("End Poll")
2013-08-07 21:00:53 +00:00
.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
}
2013-12-19 04:50:19 +00:00
$("<button/>").addClass("btn btn-default btn-sm").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);
}
2016-07-07 13:53:06 +00:00
$("<span/>").addClass("label label-default pull-right").data('timestamp',data.timestamp).appendTo(poll)
.text(new Date(data.timestamp).toTimeString().split(" ")[0]);
2013-08-07 21:00:53 +00:00
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()
});
}
},
listPlaylists: function(data) {
2014-02-02 18:41:41 +00:00
$("#userpl_list").data("entries", data);
formatUserPlaylistList();
2014-02-10 05:53:46 +00:00
},
emoteList: function (data) {
loadEmotes(data);
EMOTELIST.handleChange();
CSEMOTELIST.handleChange();
2014-02-10 05:53:46 +00:00
},
updateEmote: function (data) {
data.regex = new RegExp(data.source, "gi");
var found = false;
for (var i = 0; i < CHANNEL.emotes.length; i++) {
if (CHANNEL.emotes[i].name === data.name) {
found = true;
CHANNEL.emotes[i] = data;
break;
}
}
for (var i = 0; i < CHANNEL.badEmotes.length; i++) {
if (CHANNEL.badEmotes[i].name === data.name) {
CHANNEL.badEmotes[i] = data;
break;
}
}
2014-02-10 05:53:46 +00:00
if (!found) {
CHANNEL.emotes.push(data);
if (/\s/g.test(data.name)) {
CHANNEL.badEmotes.push(data);
} else {
CHANNEL.emoteMap[data.name] = data;
}
} else {
CHANNEL.emoteMap[data.name] = data;
2014-02-10 05:53:46 +00:00
}
EMOTELIST.handleChange();
CSEMOTELIST.handleChange();
2014-02-10 05:53:46 +00:00
},
renameEmote: function (data) {
var badBefore = /\s/g.test(data.old);
var badAfter = /\s/g.test(data.name);
var oldName = data.old;
delete data.old;
data.regex = new RegExp(data.source, "gi");
for (var i = 0; i < CHANNEL.emotes.length; i++) {
if (CHANNEL.emotes[i].name === oldName) {
CHANNEL.emotes[i] = data;
break;
}
}
// Now bad
if(badAfter){
// But wasn't bad before: Add it to bad list
if(!badBefore){
CHANNEL.badEmotes.push(data);
2017-05-17 02:15:12 +00:00
delete CHANNEL.emoteMap[oldName];
}
// Was bad before too: Update
else {
for (var i = 0; i < CHANNEL.badEmotes.length; i++) {
if (CHANNEL.badEmotes[i].name === oldName) {
CHANNEL.badEmotes[i] = data;
break;
}
}
}
}
// Not bad now
else {
// But was bad before: Drop from list
if(badBefore){
for (var i = 0; i < CHANNEL.badEmotes.length; i++) {
if (CHANNEL.badEmotes[i].name === oldName) {
CHANNEL.badEmotes.splice(i, 1);
break;
}
}
2017-05-17 02:15:12 +00:00
} else {
delete CHANNEL.emoteMap[oldName];
}
2017-05-17 02:15:12 +00:00
CHANNEL.emoteMap[data.name] = data;
}
EMOTELIST.handleChange();
CSEMOTELIST.handleChange();
},
2014-02-13 05:33:42 +00:00
removeEmote: function (data) {
var found = -1;
for (var i = 0; i < CHANNEL.emotes.length; i++) {
if (CHANNEL.emotes[i].name === data.name) {
found = i;
break;
}
}
2014-02-10 05:53:46 +00:00
2014-02-13 05:33:42 +00:00
if (found !== -1) {
var row = $("code:contains('" + data.name + "')").parent().parent();
row.hide("fade", row.remove.bind(row));
CHANNEL.emotes.splice(i, 1);
delete CHANNEL.emoteMap[data.name];
for (var i = 0; i < CHANNEL.badEmotes.length; i++) {
if (CHANNEL.badEmotes[i].name === data.name) {
CHANNEL.badEmotes.splice(i, 1);
break;
}
}
2014-02-13 05:33:42 +00:00
}
},
warnLargeChandump: function (data) {
function toHumanReadable(size) {
if (size > 1048576) {
return Math.floor((size / 1048576) * 100) / 100 + "MiB";
} else if (size > 1024) {
return Math.floor((size / 1024) * 100) / 100 + "KiB";
} else {
return size + "B";
}
}
if ($("#chandumptoobig").length > 0) {
$("#chandumptoobig").remove();
}
errDialog("This channel currently exceeds the maximum size of " +
toHumanReadable(data.limit) + " (channel size is " +
toHumanReadable(data.actual) + "). Please reduce the size by removing " +
2015-09-21 06:17:06 +00:00
"unneeded playlist items, filters, and/or emotes. Changes to the channel " +
"will not be saved until the size is reduced to under the limit.")
.attr("id", "chandumptoobig");
2016-06-09 05:54:16 +00:00
},
partitionChange: function (socketConfig) {
window.socket.disconnect();
HAS_CONNECTED_BEFORE = false;
2016-06-09 05:54:16 +00:00
ioServerConnect(socketConfig);
setupCallbacks();
},
validationError: function (error) {
var target = $(error.target);
target.parent().find(".text-danger").remove();
var formGroup = target.parent();
while (!formGroup.hasClass("form-group") && formGroup.length > 0) {
formGroup = formGroup.parent();
}
if (formGroup.length > 0) {
formGroup.addClass("has-error");
}
$("<p/>").addClass("text-danger")
.text(error.message)
.insertAfter(target);
},
validationPassed: function (data) {
var target = $(data.target);
target.parent().find(".text-danger").remove();
var formGroup = target.parent();
while (!formGroup.hasClass("form-group") && formGroup.length > 0) {
formGroup = formGroup.parent();
}
if (formGroup.length > 0) {
formGroup.removeClass("has-error");
}
2017-04-04 03:31:21 +00:00
},
clearVoteskipVote: function () {
if (CHANNEL.opts.allow_voteskip && hasPermission("voteskip")) {
$("#voteskip").attr("disabled", false);
}
2014-02-13 05:33:42 +00:00
}
2013-08-07 21:00:53 +00:00
}
2016-03-03 03:18:33 +00:00
var SOCKET_DEBUG = localStorage.getItem('cytube_socket_debug') === 'true';
2013-08-07 21:00:53 +00:00
setupCallbacks = function() {
for(var key in Callbacks) {
(function(key) {
2014-08-22 01:32:58 +00:00
socket.on(key, function(data) {
if (SOCKET_DEBUG) {
console.log(key, data);
}
try {
Callbacks[key](data);
} catch (e) {
if (SOCKET_DEBUG) {
2015-04-30 20:26:09 +00:00
console.log("EXCEPTION: " + e + "\n" + e.stack);
2014-08-22 01:32:58 +00:00
}
}
});
2013-08-07 21:00:53 +00:00
})(key);
}
socket.on("connect_error", function (error) {
// If the socket has connected at least once during this
// session and now gets a connect error, it is likely because
// the server is down temporarily and not because of any configuration
// issue. Therefore, omit the warning message about refreshing.
if (HAS_CONNECTED_BEFORE) {
return;
}
SOCKETIO_CONNECT_ERROR_COUNT++;
if (SOCKETIO_CONNECT_ERROR_COUNT >= 3 &&
$("#socketio-connect-error").length === 0) {
var message = "Failed to connect to the server. Try clearing your " +
"cache and refreshing the page.";
makeAlert("Error", message, "alert-danger")
.attr("id", "socketio-connect-error")
.appendTo($("#announcements"));
}
});
2015-10-20 05:32:00 +00:00
};
2013-08-07 21:00:53 +00:00
2016-06-09 05:54:16 +00:00
function ioServerConnect(socketConfig) {
if (socketConfig.error) {
makeAlert("Error", "Socket.io configuration returned error: " +
socketConfig.error, "alert-danger")
.appendTo($("#announcements"));
return;
}
var servers;
if (socketConfig.alt && socketConfig.alt.length > 0 &&
localStorage.useAltServer === "true") {
servers = socketConfig.alt;
console.log("Using alt servers: " + JSON.stringify(servers));
} else {
servers = socketConfig.servers;
}
var chosenServer = null;
servers.forEach(function (server) {
if (chosenServer === null) {
chosenServer = server;
} else if (server.secure && !chosenServer.secure) {
chosenServer = server;
} else if (!server.ipv6Only && chosenServer.ipv6Only) {
chosenServer = server;
}
});
console.log("Connecting to " + JSON.stringify(chosenServer));
if (chosenServer === null) {
makeAlert("Error",
"Socket.io configuration was unable to find a suitable server",
"alert-danger")
.appendTo($("#announcements"));
}
var opts = {
secure: chosenServer.secure
};
window.socket = io(chosenServer.url, opts);
}
var USING_LETS_ENCRYPT = false;
function initSocketIO(socketConfig) {
function genericConnectionError() {
var message = "The socket.io library could not be loaded from <code>" +
source + "</code>. Ensure that it is not being blocked " +
"by a script blocking extension or firewall and try again.";
makeAlert("Error", message, "alert-danger")
2014-01-26 20:15:50 +00:00
.appendTo($("#announcements"));
Callbacks.disconnect();
}
if (typeof io === "undefined") {
var script = document.getElementById("socketio-js");
var source = "unknown";
if (script) {
source = script.src;
}
if (/^https/.test(source) && location.protocol === "http:"
&& USING_LETS_ENCRYPT) {
checkLetsEncrypt(socketConfig, genericConnectionError);
return;
}
genericConnectionError();
2015-10-20 05:32:00 +00:00
return;
2014-01-26 20:15:50 +00:00
}
2015-10-20 05:32:00 +00:00
ioServerConnect(socketConfig);
setupCallbacks();
}
function checkLetsEncrypt(socketConfig, nonLetsEncryptError) {
var servers = socketConfig.servers.filter(function (server) {
return !server.secure && !server.ipv6Only
});
if (servers.length === 0) {
nonLetsEncryptError();
return;
}
$.ajax({
url: servers[0].url + "/socket.io/socket.io.js",
dataType: "script",
timeout: 10000
}).done(function () {
var message = "Your browser cannot connect securely because it does " +
"not support the newer Let's Encrypt certificate " +
"authority. Click below to acknowledge and continue " +
"connecting over an unencrypted connection. See " +
"<a href=\"https://community.letsencrypt.org/t/which-browsers-and-operating-systems-support-lets-encrypt/4394\" target=\"_blank\">here</a> " +
"for more details.";
var connectionAlert = makeAlert("Error", message, "alert-danger")
.appendTo($("#announcements"));
var button = document.createElement("button");
button.className = "btn btn-default";
button.textContent = "Connect Anyways";
var alertBox = connectionAlert.find(".alert")[0];
alertBox.appendChild(document.createElement("hr"));
alertBox.appendChild(button);
button.onclick = function connectAnyways() {
ioServerConnect({
servers: servers
});
setupCallbacks();
};
}).error(function () {
nonLetsEncryptError();
});
}
(function () {
2015-10-20 05:32:00 +00:00
$.getJSON("/socketconfig/" + CHANNEL.name + ".json")
.done(function (socketConfig) {
initSocketIO(socketConfig);
2015-10-20 05:32:00 +00:00
}).fail(function () {
makeAlert("Error", "Failed to retrieve socket.io configuration. " +
"Please try again in a few minutes.",
2015-10-26 00:20:39 +00:00
"alert-danger")
2015-10-20 05:32:00 +00:00
.appendTo($("#announcements"));
Callbacks.disconnect();
});
})();