mirror of https://github.com/calzoneman/sync.git
Merge pull request #636 from calzoneman/deprecate-http
HTTPS enforcement phase 1
This commit is contained in:
commit
041d50cb23
|
@ -2,7 +2,7 @@
|
||||||
"author": "Calvin Montgomery",
|
"author": "Calvin Montgomery",
|
||||||
"name": "CyTube",
|
"name": "CyTube",
|
||||||
"description": "Online media synchronizer and chat",
|
"description": "Online media synchronizer and chat",
|
||||||
"version": "3.24.3",
|
"version": "3.25.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "http://github.com/calzoneman/sync"
|
"url": "http://github.com/calzoneman/sync"
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,6 +3,10 @@ var Config = require("../config");
|
||||||
var Utilities = require("../utilities");
|
var Utilities = require("../utilities");
|
||||||
var url = require("url");
|
var url = require("url");
|
||||||
|
|
||||||
|
function realTypeOf(thing) {
|
||||||
|
return thing === null ? 'null' : typeof thing;
|
||||||
|
}
|
||||||
|
|
||||||
function OptionsModule(channel) {
|
function OptionsModule(channel) {
|
||||||
ChannelModule.apply(this, arguments);
|
ChannelModule.apply(this, arguments);
|
||||||
this.opts = {
|
this.opts = {
|
||||||
|
@ -100,8 +104,11 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sendUpdate = false;
|
||||||
|
|
||||||
if ("allow_voteskip" in data) {
|
if ("allow_voteskip" in data) {
|
||||||
this.opts.allow_voteskip = Boolean(data.allow_voteskip);
|
this.opts.allow_voteskip = Boolean(data.allow_voteskip);
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("voteskip_ratio" in data) {
|
if ("voteskip_ratio" in data) {
|
||||||
|
@ -110,6 +117,7 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
|
||||||
ratio = 0;
|
ratio = 0;
|
||||||
}
|
}
|
||||||
this.opts.voteskip_ratio = ratio;
|
this.opts.voteskip_ratio = ratio;
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("afk_timeout" in data) {
|
if ("afk_timeout" in data) {
|
||||||
|
@ -125,12 +133,14 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
|
||||||
u.autoAFK();
|
u.autoAFK();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("pagetitle" in data && user.account.effectiveRank >= 3) {
|
if ("pagetitle" in data && user.account.effectiveRank >= 3) {
|
||||||
var title = (""+data.pagetitle).substring(0, 100);
|
var title = (""+data.pagetitle).substring(0, 100);
|
||||||
if (!title.trim().match(Config.get("reserved-names.pagetitles"))) {
|
if (!title.trim().match(Config.get("reserved-names.pagetitles"))) {
|
||||||
this.opts.pagetitle = (""+data.pagetitle).substring(0, 100);
|
this.opts.pagetitle = (""+data.pagetitle).substring(0, 100);
|
||||||
|
sendUpdate = true;
|
||||||
} else {
|
} else {
|
||||||
user.socket.emit("errorMsg", {
|
user.socket.emit("errorMsg", {
|
||||||
msg: "That pagetitle is reserved",
|
msg: "That pagetitle is reserved",
|
||||||
|
@ -151,63 +161,90 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
|
||||||
ml = 0;
|
ml = 0;
|
||||||
}
|
}
|
||||||
this.opts.maxlength = ml;
|
this.opts.maxlength = ml;
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("externalcss" in data && user.account.effectiveRank >= 3) {
|
if ("externalcss" in data && user.account.effectiveRank >= 3) {
|
||||||
var link = (""+data.externalcss).substring(0, 255);
|
var prefix = "Invalid URL for external CSS: ";
|
||||||
if (!link) {
|
if (typeof data.externalcss !== "string") {
|
||||||
this.opts.externalcss = "";
|
user.socket.emit("validationError", {
|
||||||
} else {
|
target: "#cs-externalcss",
|
||||||
try {
|
message: prefix + "URL must be a string, not "
|
||||||
var data = url.parse(link);
|
+ realTypeOf(data.externalcss)
|
||||||
if (!data.protocol || !data.protocol.match(/^(https?|ftp):/)) {
|
});
|
||||||
throw "Unacceptable protocol " + data.protocol;
|
}
|
||||||
} else if (!data.host) {
|
|
||||||
throw "URL is missing host";
|
|
||||||
} else {
|
|
||||||
link = data.href;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
user.socket.emit("errorMsg", {
|
|
||||||
msg: "Invalid URL for external CSS: " + e,
|
|
||||||
alert: true
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.opts.externalcss = link;
|
var link = data.externalcss.substring(0, 255).trim();
|
||||||
|
if (!link) {
|
||||||
|
sendUpdate = (this.opts.externalcss !== "");
|
||||||
|
this.opts.externalcss = "";
|
||||||
|
user.socket.emit("validationPassed", {
|
||||||
|
target: "#cs-externalcss"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var data = url.parse(link);
|
||||||
|
if (!data.protocol || data.protocol !== 'https:') {
|
||||||
|
user.socket.emit("validationError", {
|
||||||
|
target: "#cs-externalcss",
|
||||||
|
message: prefix + " URL must begin with 'https://'"
|
||||||
|
});
|
||||||
|
} else if (!data.host) {
|
||||||
|
user.socket.emit("validationError", {
|
||||||
|
target: "#cs-externalcss",
|
||||||
|
message: prefix + "missing hostname"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
user.socket.emit("validationPassed", {
|
||||||
|
target: "#cs-externalcss"
|
||||||
|
});
|
||||||
|
this.opts.externalcss = data.href;
|
||||||
|
sendUpdate = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("externaljs" in data && user.account.effectiveRank >= 3) {
|
if ("externaljs" in data && user.account.effectiveRank >= 3) {
|
||||||
var link = (""+data.externaljs).substring(0, 255);
|
var prefix = "Invalid URL for external JS: ";
|
||||||
|
if (typeof data.externaljs !== "string") {
|
||||||
|
user.socket.emit("validationError", {
|
||||||
|
target: "#cs-externaljs",
|
||||||
|
message: prefix + "URL must be a string, not "
|
||||||
|
+ realTypeOf(data.externaljs)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var link = data.externaljs.substring(0, 255).trim();
|
||||||
if (!link) {
|
if (!link) {
|
||||||
|
sendUpdate = (this.opts.externaljs !== "");
|
||||||
this.opts.externaljs = "";
|
this.opts.externaljs = "";
|
||||||
|
user.socket.emit("validationPassed", {
|
||||||
|
target: "#cs-externaljs"
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
var data = url.parse(link);
|
||||||
try {
|
if (!data.protocol || data.protocol !== 'https:') {
|
||||||
var data = url.parse(link);
|
user.socket.emit("validationError", {
|
||||||
if (!data.protocol || !data.protocol.match(/^(https?|ftp):/)) {
|
target: "#cs-externaljs",
|
||||||
throw "Unacceptable protocol " + data.protocol;
|
message: prefix + " URL must begin with 'https://'"
|
||||||
} else if (!data.host) {
|
|
||||||
throw "URL is missing host";
|
|
||||||
} else {
|
|
||||||
link = data.href;
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
user.socket.emit("errorMsg", {
|
|
||||||
msg: "Invalid URL for external JS: " + e,
|
|
||||||
alert: true
|
|
||||||
});
|
});
|
||||||
return;
|
} else if (!data.host) {
|
||||||
|
user.socket.emit("validationError", {
|
||||||
|
target: "#cs-externaljs",
|
||||||
|
message: prefix + "missing hostname"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
user.socket.emit("validationPassed", {
|
||||||
|
target: "#cs-externaljs"
|
||||||
|
});
|
||||||
|
this.opts.externaljs = data.href;
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.opts.externaljs = link;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("chat_antiflood" in data) {
|
if ("chat_antiflood" in data) {
|
||||||
this.opts.chat_antiflood = Boolean(data.chat_antiflood);
|
this.opts.chat_antiflood = Boolean(data.chat_antiflood);
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("chat_antiflood_params" in data) {
|
if ("chat_antiflood_params" in data) {
|
||||||
|
@ -238,38 +275,46 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
|
||||||
sustained: s,
|
sustained: s,
|
||||||
cooldown: c
|
cooldown: c
|
||||||
};
|
};
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("show_public" in data && user.account.effectiveRank >= 3) {
|
if ("show_public" in data && user.account.effectiveRank >= 3) {
|
||||||
this.opts.show_public = Boolean(data.show_public);
|
this.opts.show_public = Boolean(data.show_public);
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("enable_link_regex" in data) {
|
if ("enable_link_regex" in data) {
|
||||||
this.opts.enable_link_regex = Boolean(data.enable_link_regex);
|
this.opts.enable_link_regex = Boolean(data.enable_link_regex);
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("password" in data && user.account.effectiveRank >= 3) {
|
if ("password" in data && user.account.effectiveRank >= 3) {
|
||||||
var pw = data.password + "";
|
var pw = data.password + "";
|
||||||
pw = pw === "" ? false : pw.substring(0, 100);
|
pw = pw === "" ? false : pw.substring(0, 100);
|
||||||
this.opts.password = pw;
|
this.opts.password = pw;
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("allow_dupes" in data) {
|
if ("allow_dupes" in data) {
|
||||||
this.opts.allow_dupes = Boolean(data.allow_dupes);
|
this.opts.allow_dupes = Boolean(data.allow_dupes);
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("torbanned" in data && user.account.effectiveRank >= 3) {
|
if ("torbanned" in data && user.account.effectiveRank >= 3) {
|
||||||
this.opts.torbanned = Boolean(data.torbanned);
|
this.opts.torbanned = Boolean(data.torbanned);
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("allow_ascii_control" in data && user.account.effectiveRank >= 3) {
|
if ("allow_ascii_control" in data && user.account.effectiveRank >= 3) {
|
||||||
this.opts.allow_ascii_control = Boolean(data.allow_ascii_control);
|
this.opts.allow_ascii_control = Boolean(data.allow_ascii_control);
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("playlist_max_per_user" in data && user.account.effectiveRank >= 3) {
|
if ("playlist_max_per_user" in data && user.account.effectiveRank >= 3) {
|
||||||
var max = parseInt(data.playlist_max_per_user);
|
var max = parseInt(data.playlist_max_per_user);
|
||||||
if (!isNaN(max) && max >= 0) {
|
if (!isNaN(max) && max >= 0) {
|
||||||
this.opts.playlist_max_per_user = max;
|
this.opts.playlist_max_per_user = max;
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,6 +322,7 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
|
||||||
var delay = data.new_user_chat_delay;
|
var delay = data.new_user_chat_delay;
|
||||||
if (!isNaN(delay) && delay >= 0) {
|
if (!isNaN(delay) && delay >= 0) {
|
||||||
this.opts.new_user_chat_delay = delay;
|
this.opts.new_user_chat_delay = delay;
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,11 +330,14 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
|
||||||
var delay = data.new_user_chat_link_delay;
|
var delay = data.new_user_chat_link_delay;
|
||||||
if (!isNaN(delay) && delay >= 0) {
|
if (!isNaN(delay) && delay >= 0) {
|
||||||
this.opts.new_user_chat_link_delay = delay;
|
this.opts.new_user_chat_link_delay = delay;
|
||||||
|
sendUpdate = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.channel.logger.log("[mod] " + user.getName() + " updated channel options");
|
this.channel.logger.log("[mod] " + user.getName() + " updated channel options");
|
||||||
this.sendOpts(this.channel.users);
|
if (sendUpdate) {
|
||||||
|
this.sendOpts(this.channel.users);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = OptionsModule;
|
module.exports = OptionsModule;
|
||||||
|
|
|
@ -13,6 +13,7 @@ var Config = require("../config");
|
||||||
var Server = require("../server");
|
var Server = require("../server");
|
||||||
var session = require("../session");
|
var session = require("../session");
|
||||||
var csrf = require("./csrf");
|
var csrf = require("./csrf");
|
||||||
|
const url = require("url");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a GET request for /account/edit
|
* Handles a GET request for /account/edit
|
||||||
|
@ -396,6 +397,25 @@ function handleAccountProfilePage(req, res) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validateProfileImage(image, callback) {
|
||||||
|
var prefix = "Invalid URL for profile image: ";
|
||||||
|
var link = image.trim();
|
||||||
|
if (!link) {
|
||||||
|
process.nextTick(callback, null, link);
|
||||||
|
} else {
|
||||||
|
var data = url.parse(link);
|
||||||
|
if (!data.protocol || data.protocol !== 'https:') {
|
||||||
|
process.nextTick(callback,
|
||||||
|
new Error(prefix + " URL must begin with 'https://'"));
|
||||||
|
} else if (!data.host) {
|
||||||
|
process.nextTick(callback,
|
||||||
|
new Error(prefix + "missing hostname"));
|
||||||
|
} else {
|
||||||
|
process.nextTick(callback, null, link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles a POST request to edit a profile
|
* Handles a POST request to edit a profile
|
||||||
*/
|
*/
|
||||||
|
@ -410,23 +430,37 @@ function handleAccountProfile(req, res) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var image = req.body.image;
|
var rawImage = String(req.body.image).substring(0, 255);
|
||||||
var text = req.body.text;
|
var text = String(req.body.text).substring(0, 255);
|
||||||
|
|
||||||
db.users.setProfile(req.user.name, { image: image, text: text }, function (err) {
|
validateProfileImage(rawImage, (error, image) => {
|
||||||
if (err) {
|
if (error) {
|
||||||
sendPug(res, "account-profile", {
|
db.users.getProfile(req.user.name, function (err, profile) {
|
||||||
profileImage: "",
|
var errorMessage = err || error.message;
|
||||||
profileText: "",
|
sendPug(res, "account-profile", {
|
||||||
profileError: err
|
profileImage: profile ? profile.image : "",
|
||||||
|
profileText: profile ? profile.text : "",
|
||||||
|
profileError: errorMessage
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendPug(res, "account-profile", {
|
db.users.setProfile(req.user.name, { image: image, text: text }, function (err) {
|
||||||
profileImage: image,
|
if (err) {
|
||||||
profileText: text,
|
sendPug(res, "account-profile", {
|
||||||
profileError: false
|
profileImage: "",
|
||||||
|
profileText: "",
|
||||||
|
profileError: err
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendPug(res, "account-profile", {
|
||||||
|
profileImage: image,
|
||||||
|
profileText: text,
|
||||||
|
profileError: false
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,13 +35,42 @@ html(lang="en")
|
||||||
input(type="hidden", name="_csrf", value=csrfToken)
|
input(type="hidden", name="_csrf", value=csrfToken)
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(for="profileimage") Image
|
label.control-label(for="profileimage") Image
|
||||||
input#profileimage.form-control(type="text", name="image")
|
input#profileimage.form-control(type="text", name="image", maxlength="255")
|
||||||
.form-group
|
.form-group
|
||||||
label.control-label(for="profiletext") Text
|
label.control-label(for="profiletext") Text
|
||||||
textarea#profiletext.form-control(cols="10", name="text")= profileText
|
textarea#profiletext.form-control(cols="10", name="text", maxlength="255")= profileText
|
||||||
button.btn.btn-primary.btn-block(type="submit") Save
|
button.btn.btn-primary.btn-block(type="submit") Save
|
||||||
|
|
||||||
include footer
|
include footer
|
||||||
+footer()
|
+footer()
|
||||||
script(type="text/javascript").
|
script(type="text/javascript").
|
||||||
$("#profileimage").val("#{profileImage}");
|
var $profileImage = $("#profileimage");
|
||||||
|
$profileImage.val("#{profileImage}");
|
||||||
|
var hasError = false;
|
||||||
|
function validateImage() {
|
||||||
|
var value = $profileImage.val().trim();
|
||||||
|
$profileImage.val(value);
|
||||||
|
if (!/^$|^https:/.test(value)) {
|
||||||
|
hasError = true;
|
||||||
|
$profileImage.parent().addClass("has-error");
|
||||||
|
var $error = $("#profileimage-error");
|
||||||
|
if ($error.length === 0) {
|
||||||
|
$error = $("<p/>")
|
||||||
|
.attr({ id: "profileimage-error" })
|
||||||
|
.addClass("text-danger")
|
||||||
|
.html("Profile image must be a URL beginning with <code>https://</code>")
|
||||||
|
.insertAfter($profileImage);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasError = false;
|
||||||
|
$profileImage.parent().removeClass("has-error");
|
||||||
|
$("#profileimage-error").remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$("form").submit(function (event) {
|
||||||
|
validateImage();
|
||||||
|
if (hasError) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -49,7 +49,6 @@ Callbacks = {
|
||||||
},
|
},
|
||||||
|
|
||||||
costanza: function (data) {
|
costanza: function (data) {
|
||||||
hidePlayer();
|
|
||||||
$("#costanza-modal").modal("hide");
|
$("#costanza-modal").modal("hide");
|
||||||
var modal = makeModal();
|
var modal = makeModal();
|
||||||
modal.attr("id", "costanza-modal")
|
modal.attr("id", "costanza-modal")
|
||||||
|
@ -61,7 +60,6 @@ Callbacks = {
|
||||||
.appendTo(body);
|
.appendTo(body);
|
||||||
|
|
||||||
$("<strong/>").text(data.msg).appendTo(body);
|
$("<strong/>").text(data.msg).appendTo(body);
|
||||||
hidePlayer();
|
|
||||||
modal.modal();
|
modal.modal();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1052,6 +1050,38 @@ Callbacks = {
|
||||||
HAS_CONNECTED_BEFORE = false;
|
HAS_CONNECTED_BEFORE = false;
|
||||||
ioServerConnect(socketConfig);
|
ioServerConnect(socketConfig);
|
||||||
setupCallbacks();
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -488,7 +488,6 @@ $("#voteskip").click(function() {
|
||||||
|
|
||||||
$("#getplaylist").click(function() {
|
$("#getplaylist").click(function() {
|
||||||
var callback = function(data) {
|
var callback = function(data) {
|
||||||
hidePlayer();
|
|
||||||
var idx = socket.listeners("errorMsg").indexOf(errCallback);
|
var idx = socket.listeners("errorMsg").indexOf(errCallback);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
socket.listeners("errorMsg").splice(idx);
|
socket.listeners("errorMsg").splice(idx);
|
||||||
|
@ -523,7 +522,6 @@ $("#getplaylist").click(function() {
|
||||||
$("<div/>").addClass("modal-footer").appendTo(modal);
|
$("<div/>").addClass("modal-footer").appendTo(modal);
|
||||||
outer.on("hidden.bs.modal", function() {
|
outer.on("hidden.bs.modal", function() {
|
||||||
outer.remove();
|
outer.remove();
|
||||||
unhidePlayer();
|
|
||||||
});
|
});
|
||||||
outer.modal();
|
outer.modal();
|
||||||
};
|
};
|
||||||
|
@ -862,7 +860,6 @@ applyOpts();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
var EMOTELISTMODAL = $("#emotelist");
|
var EMOTELISTMODAL = $("#emotelist");
|
||||||
EMOTELISTMODAL.on("hidden.bs.modal", unhidePlayer);
|
|
||||||
$("#emotelistbtn").click(function () {
|
$("#emotelistbtn").click(function () {
|
||||||
EMOTELISTMODAL.modal();
|
EMOTELISTMODAL.modal();
|
||||||
});
|
});
|
||||||
|
|
|
@ -616,11 +616,6 @@ function rebuildPlaylist() {
|
||||||
|
|
||||||
/* user settings menu */
|
/* user settings menu */
|
||||||
function showUserOptions() {
|
function showUserOptions() {
|
||||||
hidePlayer();
|
|
||||||
$("#useroptions").on("hidden.bs.modal", function () {
|
|
||||||
unhidePlayer();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (CLIENT.rank < 2) {
|
if (CLIENT.rank < 2) {
|
||||||
$("a[href='#us-mod']").parent().hide();
|
$("a[href='#us-mod']").parent().hide();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2046,21 +2041,6 @@ function waitUntilDefined(obj, key, fn) {
|
||||||
fn();
|
fn();
|
||||||
}
|
}
|
||||||
|
|
||||||
function hidePlayer() {
|
|
||||||
/* 2015-09-16
|
|
||||||
* Originally used to hide the player while a modal was open because of
|
|
||||||
* certain flash videos that always rendered on top. Seems to no longer
|
|
||||||
* be an issue. Uncomment this if it is.
|
|
||||||
if (!PLAYER) return;
|
|
||||||
|
|
||||||
$("#ytapiplayer").hide();
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
function unhidePlayer() {
|
|
||||||
//$("#ytapiplayer").show();
|
|
||||||
}
|
|
||||||
|
|
||||||
function chatDialog(div) {
|
function chatDialog(div) {
|
||||||
var parent = $("<div/>").addClass("profile-box")
|
var parent = $("<div/>").addClass("profile-box")
|
||||||
.css({
|
.css({
|
||||||
|
@ -2103,6 +2083,44 @@ function errDialog(err) {
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2016-12-08
|
||||||
|
* I *promise* that one day I will actually split this file into submodules
|
||||||
|
* -cal
|
||||||
|
*/
|
||||||
|
function modalAlert(options) {
|
||||||
|
if (typeof options !== "object" || options === null) {
|
||||||
|
throw new Error("modalAlert() called without required parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
var modal = makeModal();
|
||||||
|
modal.addClass("cytube-modal-alert");
|
||||||
|
modal.removeClass("fade");
|
||||||
|
modal.find(".modal-dialog").addClass("modal-dialog-nonfluid");
|
||||||
|
|
||||||
|
if (options.title) {
|
||||||
|
$("<h3/>").text(options.title).appendTo(modal.find(".modal-header"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var contentDiv = $("<div/>").addClass("modal-body");
|
||||||
|
if (options.htmlContent) {
|
||||||
|
contentDiv.html(options.htmlContent);
|
||||||
|
} else if (options.textContent) {
|
||||||
|
contentDiv.text(options.textContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
contentDiv.appendTo(modal.find(".modal-content"));
|
||||||
|
|
||||||
|
var footer = $("<div/>").addClass("modal-footer");
|
||||||
|
var okButton = $("<button/>").addClass("btn btn-primary")
|
||||||
|
.attr({ "data-dismiss": "modal"})
|
||||||
|
.text("OK")
|
||||||
|
.appendTo(footer);
|
||||||
|
footer.appendTo(modal.find(".modal-content"));
|
||||||
|
modal.appendTo(document.body);
|
||||||
|
modal.modal();
|
||||||
|
}
|
||||||
|
|
||||||
function queueMessage(data, type) {
|
function queueMessage(data, type) {
|
||||||
if (!data)
|
if (!data)
|
||||||
data = { link: null };
|
data = { link: null };
|
||||||
|
@ -2237,7 +2255,6 @@ function makeModal() {
|
||||||
.appendTo(head);
|
.appendTo(head);
|
||||||
|
|
||||||
wrap.on("hidden.bs.modal", function () {
|
wrap.on("hidden.bs.modal", function () {
|
||||||
unhidePlayer();
|
|
||||||
wrap.remove();
|
wrap.remove();
|
||||||
});
|
});
|
||||||
return wrap;
|
return wrap;
|
||||||
|
@ -3160,11 +3177,6 @@ window.CSEMOTELIST = new CSEmoteList("#cs-emotes");
|
||||||
window.CSEMOTELIST.sortAlphabetical = USEROPTS.emotelist_sort;
|
window.CSEMOTELIST.sortAlphabetical = USEROPTS.emotelist_sort;
|
||||||
|
|
||||||
function showChannelSettings() {
|
function showChannelSettings() {
|
||||||
hidePlayer();
|
|
||||||
$("#channeloptions").on("hidden.bs.modal", function () {
|
|
||||||
unhidePlayer();
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#channeloptions").modal();
|
$("#channeloptions").modal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue