thelounge/client/js/socket-events/configuration.js

218 lines
5.6 KiB
JavaScript
Raw Normal View History

"use strict";
const $ = require("jquery");
const socket = require("../socket");
const templates = require("../../views");
2017-11-07 21:22:16 +01:00
const options = require("../options");
const webpush = require("../webpush");
const connect = $("#connect");
const utils = require("../utils");
const upload = require("../upload");
2018-09-03 09:58:33 +02:00
const {vueApp} = require("../vue");
window.addEventListener("beforeinstallprompt", (installPromptEvent) => {
$("#webapp-install-button")
.on("click", function() {
if (installPromptEvent && installPromptEvent.prompt) {
installPromptEvent.prompt();
}
$(this).prop("hidden", true);
})
.prop("hidden", false);
$("#native-app").prop("hidden", false);
});
socket.on("configuration", function(data) {
2018-09-09 15:09:19 +02:00
vueApp.isFileUploadEnabled = data.fileUpload;
Offer optional syncing of client settings Write synced settings to localstorage. move settings and webpush init to init.js stub for server sending clientsettings get very basic setting sync working Also update client.config.clientSettings on settings:set Full setting sync with mandatory and excluded sync options Actually check client preferences. Further settings restructuring. Refactor options.js make storage act in a sane manner. Add new parameter to applySetting Do not sync if the setting is stored as a result of syncing General clean up, commenting and restructing. sync from server on checking "sync" offer initial sync Better deal with DOM being ready and instances of inital sync showing Don't try to disable autocompletion when not enabled. Restructure option.js to seperate functions from settings. More consistency in naming options vs settings Switch processSetting and applySetting names reflecting their functionality better. move options init back to configuration. simplify how settings are synced around. move options init after template building. Remove unneeded hasOwnProperty Use global for #theme and only apply theme in applySetting Return when no server side clientsettings excist. Autocompletion options to options.settings Make nocss param in url work again. Actually filter out empty highlight values. Clarify alwaysSync comment. Remove manual step for initial sync change attr to prop in options.js replace unbind with off in autocompletion.js Do not sync settings when the lounge is set to public. fix eslint error Fix merge error Do not show sync warning after page refresh when sync is enabled Move setting sync label in actual label. Improve server setting sync handling performance and failure potential. Don't give impression that the desktop notificiation is off when the browser permission is denied. Refine showing and hiding of notification warnings. rename all setting socket events to singular setting. add experimental note and icon to settingsync. fix css linting error
2017-12-11 20:01:15 +01:00
if (options.initialized) {
2018-03-30 09:49:02 +02:00
// Likely a reconnect, request sync for possibly missed settings.
socket.emit("setting:get");
2017-11-07 21:22:16 +01:00
return;
}
$("#settings").html(templates.windows.settings(data));
2017-11-12 19:00:34 +01:00
$("#help").html(templates.windows.help(data));
$("#changelog").html(templates.windows.changelog());
$("#settings").on("show", () => {
$("#session-list").html("<p>Loading…</p>");
socket.emit("sessions:get");
});
2017-11-07 21:22:16 +01:00
$("#play").on("click", () => {
const pop = new Audio();
2018-07-17 08:14:58 +02:00
pop.src = "audio/pop.wav";
2017-11-07 21:22:16 +01:00
pop.play();
});
if (data.fileUpload) {
upload.setMaxFileSize(data.fileUploadMaxFileSize);
}
2018-05-10 20:37:10 +02:00
utils.togglePasswordField("#change-password .reveal-password");
2018-05-08 01:52:54 +02:00
2017-11-07 21:22:16 +01:00
options.initialize();
webpush.initialize();
// If localStorage contains a theme that does not exist on this server, switch
// back to its default theme.
if (!data.themes.map((t) => t.name).includes(options.settings.theme)) {
options.processSetting("theme", data.defaultTheme, true);
}
function handleFormSubmit() {
2017-11-07 21:22:16 +01:00
const form = $(this);
const event = form.data("event");
form.find(".btn").prop("disabled", true);
2017-11-07 21:22:16 +01:00
const values = {};
$.each(form.serializeArray(), function(i, obj) {
if (obj.value !== "") {
values[obj.name] = obj.value;
}
});
socket.emit(event, values);
return false;
}
2017-11-07 21:22:16 +01:00
$("#change-password form").on("submit", handleFormSubmit);
connect.on("submit", "form", handleFormSubmit);
connect.on("show", function() {
connect
.html(templates.windows.connect(data))
.find("#connect\\:nick")
.on("focusin", function() {
// Need to set the first "lastvalue", so it can be used in the below function
const nick = $(this);
nick.data("lastvalue", nick.val());
})
.on("input", function() {
const nick = $(this).val();
const usernameInput = connect.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);
});
2018-05-10 20:37:10 +02:00
utils.togglePasswordField("#connect .reveal-password");
});
2018-06-19 17:00:07 +02:00
if ("URLSearchParams" in window) {
const params = new URLSearchParams(document.location.search);
2018-06-19 17:00:07 +02:00
if (params.has("uri")) {
parseIrcUri(params.get("uri") + location.hash, data);
} else if ($(document.body).hasClass("public")) {
parseOverrideParams(params, data);
}
}
});
2018-06-19 17:00:07 +02:00
function parseIrcUri(stringUri, defaults) {
const data = Object.assign({}, defaults.defaults);
try {
// https://tools.ietf.org/html/draft-butcher-irc-url-04
const uri = new URL(stringUri);
2018-06-19 17:00:07 +02:00
// Replace protocol with a "special protocol" (that's what it's called in WHATWG spec)
// So that the uri can be properly parsed
if (uri.protocol === "irc:") {
uri.protocol = "http:";
2018-06-19 17:00:07 +02:00
if (!uri.port) {
uri.port = 6667;
}
2018-06-19 17:00:07 +02:00
data.tls = false;
} else if (uri.protocol === "ircs:") {
uri.protocol = "https:";
if (!uri.port) {
uri.port = 6697;
}
2018-06-19 17:00:07 +02:00
data.tls = true;
} else {
return;
}
2018-06-19 17:00:07 +02:00
data.host = data.name = uri.hostname;
data.port = uri.port;
data.username = window.decodeURIComponent(uri.username) || data.username;
data.password = window.decodeURIComponent(uri.password) || data.password;
let channel = (uri.pathname + uri.hash).substr(1);
const index = channel.indexOf(",");
if (index > -1) {
channel = channel.substring(0, index);
}
data.join = channel;
// TODO: Need to show connect window with uri params without overriding defaults
defaults.defaults = data;
$('button[data-target="#connect"]').trigger("click");
} catch (e) {
// do nothing on invalid uri
}
2018-06-19 17:00:07 +02:00
}
function parseOverrideParams(params, data) {
for (let [key, value] of params) {
// Support `channels` as a compatibility alias with other clients
if (key === "channels") {
key = "join";
}
if (!Object.prototype.hasOwnProperty.call(data.defaults, key)) {
2018-06-19 17:00:07 +02:00
continue;
}
// When the network is locked, URL overrides should not affect disabled fields
if (data.lockNetwork &&
["host", "port", "tls", "rejectUnauthorized"].includes(key)) {
continue;
}
// When the network is not displayed, its name in the UI is not customizable
if (!data.displayNetwork && key === "name") {
continue;
}
2018-06-19 17:00:07 +02:00
if (key === "join") {
value = value.split(",").map((chan) => {
if (!chan.match(/^[#&!+]/)) {
return `#${chan}`;
}
return chan;
}).join(", ");
}
// Override server provided defaults with parameters passed in the URL if they match the data type
switch (typeof data.defaults[key]) {
case "boolean": data.defaults[key] = value === "1" || value === "true"; break;
case "number": data.defaults[key] = Number(value); break;
case "string": data.defaults[key] = String(value); break;
}
}
}