Fix options

This commit is contained in:
Pavel Djundik 2017-11-07 22:22:16 +02:00
parent e85e00ebed
commit 8d88779918
9 changed files with 194 additions and 190 deletions

View File

@ -27,7 +27,6 @@ $(function() {
$(document.body).data("app-name", document.title); $(document.body).data("app-name", document.title);
var windows = $("#windows");
var viewport = $("#viewport"); var viewport = $("#viewport");
var sidebarSlide = slideoutMenu(viewport[0], sidebar[0]); var sidebarSlide = slideoutMenu(viewport[0], sidebar[0]);
var contextMenuContainer = $("#context-menu-container"); var contextMenuContainer = $("#context-menu-container");
@ -484,18 +483,6 @@ $(function() {
container.html(templates.user_filtered({matches: result})).show(); container.html(templates.user_filtered({matches: result})).show();
}); });
var forms = $("#sign-in, #connect, #change-password");
windows.on("show", "#sign-in", function() {
$(this).find("input").each(function() {
var self = $(this);
if (self.val() === "") {
self.focus();
return false;
}
});
});
if ($("body").hasClass("public") && (window.location.hash === "#connect" || window.location.hash === "")) { if ($("body").hasClass("public") && (window.location.hash === "#connect" || window.location.hash === "")) {
$("#connect").one("show", function() { $("#connect").one("show", function() {
var params = URI(document.location.search); var params = URI(document.location.search);
@ -522,56 +509,6 @@ $(function() {
}); });
} }
forms.on("submit", "form", function(e) {
e.preventDefault();
var event = "auth";
var form = $(this);
form.find(".btn").attr("disabled", true);
if (form.closest(".window").attr("id") === "connect") {
event = "conn";
} else if (form.closest("div").attr("id") === "change-password") {
event = "change-password";
}
var values = {};
$.each(form.serializeArray(), function(i, obj) {
if (obj.value !== "") {
values[obj.name] = obj.value;
}
});
if (values.user) {
storage.set("user", values.user);
}
socket.emit(
event, values
);
});
forms.on("focusin", ".nick", function() {
// Need to set the first "lastvalue", so it can be used in the below function
var nick = $(this);
nick.data("lastvalue", nick.val());
});
forms.on("input", ".nick", function() {
var nick = $(this).val();
var usernameInput = forms.find(".username");
// Because this gets called /after/ it has already changed, we need use the previous value
var lastValue = $(this).data("lastvalue");
// They were the same before the change, so update the username field
if (usernameInput.val() === lastValue) {
usernameInput.val(nick);
}
// Store the "previous" value, for next time
$(this).data("lastvalue", nick);
});
$(document).on("visibilitychange focus click", () => { $(document).on("visibilitychange focus click", () => {
if (sidebar.find(".highlight").length === 0) { if (sidebar.find(".highlight").length === 0) {
utils.toggleNotificationMarkers(false); utils.toggleNotificationMarkers(false);

View File

@ -3,7 +3,6 @@
const $ = require("jquery"); const $ = require("jquery");
require("jquery-textcomplete"); require("jquery-textcomplete");
const escapeRegExp = require("lodash/escapeRegExp"); const escapeRegExp = require("lodash/escapeRegExp");
const settings = $("#settings");
const userStyles = $("#user-specified-css"); const userStyles = $("#user-specified-css");
const storage = require("./localStorage"); const storage = require("./localStorage");
const tz = require("./libs/handlebars/tz"); const tz = require("./libs/handlebars/tz");
@ -35,6 +34,11 @@ for (const key in options) {
} }
} }
// Apply custom CSS on page load
if (typeof userOptions.userStyles === "string" && !/[?&]nocss/.test(window.location.search)) {
userStyles.html(userOptions.userStyles);
}
userOptions = null; userOptions = null;
module.exports = options; module.exports = options;
@ -43,123 +47,126 @@ module.exports.shouldOpenMessagePreview = function(type) {
return (options.links && type === "link") || (options.thumbnails && type === "image"); return (options.links && type === "link") || (options.thumbnails && type === "image");
}; };
for (var i in options) { module.exports.initialize = () => {
if (i === "userStyles") { module.exports.initialize = null;
if (!/[?&]nocss/.test(window.location.search)) {
$(document.head).find("#user-specified-css").html(options[i]); const settings = $("#settings");
for (var i in options) {
if (i === "userStyles") {
settings.find("#user-specified-css-input").val(options[i]);
} else if (i === "highlights") {
settings.find("input[name=" + i + "]").val(options[i]);
} else if (i === "statusMessages") {
settings.find(`input[name=${i}][value=${options[i]}]`)
.prop("checked", true);
} else if (i === "theme") {
$("#theme").attr("href", "themes/" + options[i] + ".css");
settings.find("select[name=" + i + "]").val(options[i]);
} else if (options[i]) {
settings.find("input[name=" + i + "]").prop("checked", true);
} }
settings.find("#user-specified-css-input").val(options[i]);
} else if (i === "highlights") {
settings.find("input[name=" + i + "]").val(options[i]);
} else if (i === "statusMessages") {
settings.find(`input[name=${i}][value=${options[i]}]`)
.prop("checked", true);
} else if (i === "theme") {
$("#theme").attr("href", "themes/" + options[i] + ".css");
settings.find("select[name=" + i + "]").val(options[i]);
} else if (options[i]) {
settings.find("input[name=" + i + "]").prop("checked", true);
} }
}
settings.on("change", "input, select, textarea", function() { settings.on("change", "input, select, textarea", function() {
const self = $(this); const self = $(this);
const type = self.attr("type"); const type = self.attr("type");
const name = self.attr("name"); const name = self.attr("name");
if (type === "password") { if (type === "password") {
return; return;
} else if (type === "radio") { } else if (type === "radio") {
if (self.prop("checked")) { if (self.prop("checked")) {
options[name] = self.val();
}
} else if (type === "checkbox") {
options[name] = self.prop("checked");
} else {
options[name] = self.val(); options[name] = self.val();
} }
} else if (type === "checkbox") {
options[name] = self.prop("checked"); storage.set("settings", JSON.stringify(options));
if (name === "motd") {
chat.toggleClass("hide-" + name, !self.prop("checked"));
} else if (name === "statusMessages") {
chat.toggleClass("hide-status-messages", options[name] === "hidden");
chat.toggleClass("condensed-status-messages", options[name] === "condensed");
} else if (name === "coloredNicks") {
chat.toggleClass("colored-nicks", self.prop("checked"));
} else if (name === "theme") {
$("#theme").attr("href", "themes/" + options[name] + ".css");
} else if (name === "userStyles") {
userStyles.html(options[name]);
} else if (name === "highlights") {
var highlightString = options[name];
options.highlights = highlightString.split(",").map(function(h) {
return h.trim();
}).filter(function(h) {
// Ensure we don't have empty string in the list of highlights
// otherwise, users get notifications for everything
return h !== "";
});
// Construct regex with wordboundary for every highlight item
const highlightsTokens = options.highlights.map(function(h) {
return escapeRegExp(h);
});
if (highlightsTokens && highlightsTokens.length) {
module.exports.highlightsRE = new RegExp("\\b(?:" + highlightsTokens.join("|") + ")\\b", "i");
} else {
module.exports.highlightsRE = null;
}
} else if (name === "showSeconds") {
chat.find(".msg > .time").each(function() {
$(this).text(tz($(this).parent().data("time")));
});
chat.toggleClass("show-seconds", self.prop("checked"));
} else if (name === "autocomplete") {
if (self.prop("checked")) {
$("#input").trigger("autocomplete:on");
} else {
$("#input").textcomplete("destroy");
}
}
}).find("input")
.trigger("change");
$("#desktopNotifications").on("change", function() {
if ($(this).prop("checked") && Notification.permission !== "granted") {
Notification.requestPermission(updateDesktopNotificationStatus);
}
});
// Updates the checkbox and warning in settings when the Settings page is
// opened or when the checkbox state is changed.
// When notifications are not supported, this is never called (because
// checkbox state can not be changed).
var updateDesktopNotificationStatus = function() {
if (Notification.permission === "denied") {
desktopNotificationsCheckbox.attr("disabled", true);
desktopNotificationsCheckbox.attr("checked", false);
warningBlocked.show();
} else {
if (Notification.permission === "default" && desktopNotificationsCheckbox.prop("checked")) {
desktopNotificationsCheckbox.attr("checked", false);
}
desktopNotificationsCheckbox.attr("disabled", false);
warningBlocked.hide();
}
};
// If browser does not support notifications, override existing settings and
// display proper message in settings.
var desktopNotificationsCheckbox = $("#desktopNotifications");
var warningUnsupported = $("#warnUnsupportedDesktopNotifications");
var warningBlocked = $("#warnBlockedDesktopNotifications");
warningBlocked.hide();
if (("Notification" in window)) {
warningUnsupported.hide();
windows.on("show", "#settings", updateDesktopNotificationStatus);
} else { } else {
options[name] = self.val(); options.desktopNotifications = false;
}
storage.set("settings", JSON.stringify(options));
if (name === "motd") {
chat.toggleClass("hide-" + name, !self.prop("checked"));
} else if (name === "statusMessages") {
chat.toggleClass("hide-status-messages", options[name] === "hidden");
chat.toggleClass("condensed-status-messages", options[name] === "condensed");
} else if (name === "coloredNicks") {
chat.toggleClass("colored-nicks", self.prop("checked"));
} else if (name === "theme") {
$("#theme").attr("href", "themes/" + options[name] + ".css");
} else if (name === "userStyles") {
userStyles.html(options[name]);
} else if (name === "highlights") {
var highlightString = options[name];
options.highlights = highlightString.split(",").map(function(h) {
return h.trim();
}).filter(function(h) {
// Ensure we don't have empty string in the list of highlights
// otherwise, users get notifications for everything
return h !== "";
});
// Construct regex with wordboundary for every highlight item
const highlightsTokens = options.highlights.map(function(h) {
return escapeRegExp(h);
});
if (highlightsTokens && highlightsTokens.length) {
module.exports.highlightsRE = new RegExp("\\b(?:" + highlightsTokens.join("|") + ")\\b", "i");
} else {
module.exports.highlightsRE = null;
}
} else if (name === "showSeconds") {
chat.find(".msg > .time").each(function() {
$(this).text(tz($(this).parent().data("time")));
});
chat.toggleClass("show-seconds", self.prop("checked"));
} else if (name === "autocomplete") {
if (self.prop("checked")) {
$("#input").trigger("autocomplete:on");
} else {
$("#input").textcomplete("destroy");
}
}
}).find("input")
.trigger("change");
$("#desktopNotifications").on("change", function() {
if ($(this).prop("checked") && Notification.permission !== "granted") {
Notification.requestPermission(updateDesktopNotificationStatus);
}
});
// Updates the checkbox and warning in settings when the Settings page is
// opened or when the checkbox state is changed.
// When notifications are not supported, this is never called (because
// checkbox state can not be changed).
var updateDesktopNotificationStatus = function() {
if (Notification.permission === "denied") {
desktopNotificationsCheckbox.attr("disabled", true); desktopNotificationsCheckbox.attr("disabled", true);
desktopNotificationsCheckbox.attr("checked", false); desktopNotificationsCheckbox.attr("checked", false);
warningBlocked.show();
} else {
if (Notification.permission === "default" && desktopNotificationsCheckbox.prop("checked")) {
desktopNotificationsCheckbox.attr("checked", false);
}
desktopNotificationsCheckbox.attr("disabled", false);
warningBlocked.hide();
} }
}; };
// If browser does not support notifications, override existing settings and
// display proper message in settings.
var desktopNotificationsCheckbox = $("#desktopNotifications");
var warningUnsupported = $("#warnUnsupportedDesktopNotifications");
var warningBlocked = $("#warnBlockedDesktopNotifications");
warningBlocked.hide();
if (("Notification" in window)) {
warningUnsupported.hide();
windows.on("show", "#settings", updateDesktopNotificationStatus);
} else {
options.desktopNotifications = false;
desktopNotificationsCheckbox.attr("disabled", true);
desktopNotificationsCheckbox.attr("checked", false);
}

View File

@ -3,10 +3,71 @@
const $ = require("jquery"); const $ = require("jquery");
const socket = require("../socket"); const socket = require("../socket");
const templates = require("../../views"); const templates = require("../../views");
const options = require("../options");
const webpush = require("../webpush");
const storage = require("../localStorage");
socket.on("configuration", function(data) { socket.on("configuration", function(data) {
if (!options.initialize) {
return;
}
$("#settings").html(templates.windows.settings(data)); $("#settings").html(templates.windows.settings(data));
$("#connect").html(templates.windows.connect(data)); $("#connect").html(templates.windows.connect(data));
require("../options"); $("#play").on("click", () => {
const pop = new Audio();
pop.src = "audio/pop.ogg";
pop.play();
});
options.initialize();
webpush.initialize();
// TODO: #sign-in needs to be handled in auth.js otherwise its broken
const forms = $("#sign-in, #connect, #change-password");
forms.on("submit", "form", function() {
const form = $(this);
const event = form.data("event");
form.find(".btn").attr("disabled", true);
const values = {};
$.each(form.serializeArray(), function(i, obj) {
if (obj.value !== "") {
values[obj.name] = obj.value;
}
});
if (values.user) {
storage.set("user", values.user);
}
socket.emit(event, values);
return false;
});
forms.on("focusin", ".nick", function() {
// Need to set the first "lastvalue", so it can be used in the below function
const nick = $(this);
nick.data("lastvalue", nick.val());
});
forms.on("input", ".nick", function() {
const nick = $(this).val();
const usernameInput = forms.find(".username");
// Because this gets called /after/ it has already changed, we need use the previous value
const lastValue = $(this).data("lastvalue");
// They were the same before the change, so update the username field
if (usernameInput.val() === lastValue) {
usernameInput.val(nick);
}
// Store the "previous" value, for next time
$(this).data("lastvalue", nick);
});
}); });

View File

@ -21,8 +21,6 @@ try {
}; };
} }
$("#play").on("click", () => pop.play());
socket.on("msg", function(data) { socket.on("msg", function(data) {
// We set a maximum timeout of 2 seconds so that messages don't take too long to appear. // We set a maximum timeout of 2 seconds so that messages don't take too long to appear.
utils.requestIdleCallback(() => processReceivedMessage(data), 2000); utils.requestIdleCallback(() => processReceivedMessage(data), 2000);

View File

@ -4,7 +4,7 @@ const $ = require("jquery");
const storage = require("./localStorage"); const storage = require("./localStorage");
const socket = require("./socket"); const socket = require("./socket");
const pushNotificationsButton = $("#pushNotifications"); let pushNotificationsButton;
let clientSubscribed = null; let clientSubscribed = null;
let applicationServerKey; let applicationServerKey;
@ -29,7 +29,13 @@ module.exports.configurePushNotifications = (subscribedOnServer, key) => {
} }
}; };
if (isAllowedServiceWorkersHost()) { module.exports.initialize = () => {
pushNotificationsButton = $("#pushNotifications");
if (!isAllowedServiceWorkersHost()) {
return;
}
$("#pushNotificationsHttps").hide(); $("#pushNotificationsHttps").hide();
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
@ -57,7 +63,7 @@ if (isAllowedServiceWorkersHost()) {
$("#pushNotificationsUnsupported span").text(err); $("#pushNotificationsUnsupported span").text(err);
}); });
} }
} };
function onPushButton() { function onPushButton() {
pushNotificationsButton.attr("disabled", true); pushNotificationsButton.attr("disabled", true);

View File

@ -1,7 +1,7 @@
<div class="header"> <div class="header">
<button class="lt" aria-label="Toggle channel list"></button> <button class="lt" aria-label="Toggle channel list"></button>
</div> </div>
<form class="container" method="post" action=""> <form class="container" method="post" action="" data-event="conn">
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<h1 class="title"> <h1 class="title">

View File

@ -147,7 +147,7 @@
{{#unless public}} {{#unless public}}
{{#unless ldapEnabled}} {{#unless ldapEnabled}}
<div id="change-password"> <div id="change-password">
<form action="" method="post"> <form action="" method="post" data-event="change-password">
<div class="col-sm-12"> <div class="col-sm-12">
<h2>Change password</h2> <h2>Change password</h2>
</div> </div>

View File

@ -1,4 +1,4 @@
<form class="container" method="post" action=""> <form class="container" method="post" action="" data-event="auth">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<h1 class="title">Sign in to The Lounge</h1> <h1 class="title">Sign in to The Lounge</h1>
@ -6,7 +6,7 @@
<div class="col-xs-12"> <div class="col-xs-12">
<label> <label>
Username Username
<input class="input" name="user"> <input class="input" name="user" autofocus>
</label> </label>
</div> </div>
<div class="col-xs-12"> <div class="col-xs-12">
@ -15,12 +15,6 @@
<input class="input" type="password" name="password"> <input class="input" type="password" name="password">
</label> </label>
</div> </div>
<div class="col-xs-12">
<label class="remember">
<input type="checkbox" name="remember" value="on" id="sign-in-remember" checked>
Stay signed in
</label>
</div>
<div class="col-xs-12 error" style="display: none;">Authentication failed.</div> <div class="col-xs-12 error" style="display: none;">Authentication failed.</div>
<div class="col-xs-12"> <div class="col-xs-12">
<button type="submit" class="btn">Sign in</button> <button type="submit" class="btn">Sign in</button>

View File

@ -210,7 +210,6 @@ function index(req, res, next) {
Helper.config Helper.config
); );
data.gitCommit = Helper.getGitCommit(); data.gitCommit = Helper.getGitCommit();
data.themes = themes.getAll();
const policies = [ const policies = [
"default-src *", "default-src *",
@ -479,6 +478,8 @@ function getClientConfiguration() {
]); ]);
config.ldapEnabled = Helper.config.ldap.enable; config.ldapEnabled = Helper.config.ldap.enable;
config.gitCommit = Helper.getGitCommit();
config.themes = themes.getAll();
return config; return config;
} }