2017-11-04 17:32:18 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const $ = require("jquery");
|
|
|
|
const socket = require("../socket");
|
|
|
|
const templates = require("../../views");
|
2017-11-07 20:22:16 +00:00
|
|
|
const options = require("../options");
|
|
|
|
const webpush = require("../webpush");
|
2018-03-15 08:37:32 +00:00
|
|
|
const connect = $("#connect");
|
2018-09-03 07:30:05 +00:00
|
|
|
const upload = require("../upload");
|
2018-09-03 07:58:33 +00:00
|
|
|
const {vueApp} = require("../vue");
|
2017-11-04 17:32:18 +00:00
|
|
|
|
2018-06-05 12:29:43 +00:00
|
|
|
window.addEventListener("beforeinstallprompt", (installPromptEvent) => {
|
|
|
|
$("#webapp-install-button")
|
|
|
|
.on("click", function() {
|
|
|
|
if (installPromptEvent && installPromptEvent.prompt) {
|
|
|
|
installPromptEvent.prompt();
|
|
|
|
}
|
|
|
|
|
|
|
|
$(this).prop("hidden", true);
|
|
|
|
})
|
|
|
|
.prop("hidden", false);
|
2018-08-18 19:48:58 +00:00
|
|
|
|
|
|
|
$("#native-app").prop("hidden", false);
|
2018-06-05 12:29:43 +00:00
|
|
|
});
|
|
|
|
|
2017-11-04 17:32:18 +00:00
|
|
|
socket.on("configuration", function(data) {
|
2018-09-09 13:09:19 +00:00
|
|
|
vueApp.isFileUploadEnabled = data.fileUpload;
|
2018-09-03 07:30:05 +00:00
|
|
|
|
2017-12-11 19:01:15 +00:00
|
|
|
if (options.initialized) {
|
2018-03-30 07:49:02 +00:00
|
|
|
// Likely a reconnect, request sync for possibly missed settings.
|
|
|
|
socket.emit("setting:get");
|
2017-11-07 20:22:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-02-20 09:10:18 +00:00
|
|
|
vueApp.serverConfiguration = data;
|
2017-11-04 17:32:18 +00:00
|
|
|
|
2018-03-15 08:37:32 +00:00
|
|
|
$("#settings").on("show", () => {
|
|
|
|
$("#session-list").html("<p>Loading…</p>");
|
|
|
|
socket.emit("sessions:get");
|
|
|
|
});
|
|
|
|
|
2018-09-03 07:30:05 +00:00
|
|
|
if (data.fileUpload) {
|
2019-10-21 15:52:46 +00:00
|
|
|
upload.initialize(data.fileUploadMaxFileSize);
|
2018-09-03 07:30:05 +00:00
|
|
|
}
|
|
|
|
|
2017-11-07 20:22:16 +00:00
|
|
|
options.initialize();
|
|
|
|
webpush.initialize();
|
|
|
|
|
2018-04-02 04:25:45 +00:00
|
|
|
// If localStorage contains a theme that does not exist on this server, switch
|
|
|
|
// back to its default theme.
|
2019-07-22 16:50:04 +00:00
|
|
|
const currentTheme = data.themes.find((t) => t.name === options.settings.theme);
|
|
|
|
|
|
|
|
if (currentTheme === undefined) {
|
2018-04-02 04:25:45 +00:00
|
|
|
options.processSetting("theme", data.defaultTheme, true);
|
2019-07-22 16:50:04 +00:00
|
|
|
} else if (currentTheme.themeColor) {
|
|
|
|
document.querySelector('meta[name="theme-color"]').content = currentTheme.themeColor;
|
2018-04-02 04:25:45 +00:00
|
|
|
}
|
|
|
|
|
2019-03-03 15:19:48 +00:00
|
|
|
// TODO: move to component (this mirrors the nick to the username field if the username is empty)
|
2018-03-15 08:37:32 +00:00
|
|
|
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-04-22 18:28:00 +00:00
|
|
|
|
2018-06-19 15:00:07 +00:00
|
|
|
if ("URLSearchParams" in window) {
|
2018-05-28 07:16:00 +00:00
|
|
|
const params = new URLSearchParams(document.location.search);
|
2018-04-22 18:28:00 +00:00
|
|
|
|
2018-06-19 15:00:07 +00:00
|
|
|
if (params.has("uri")) {
|
|
|
|
parseIrcUri(params.get("uri") + location.hash, data);
|
|
|
|
} else if ($(document.body).hasClass("public")) {
|
|
|
|
parseOverrideParams(params, data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2018-04-22 18:28:00 +00:00
|
|
|
|
2018-06-19 15:00:07 +00: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-04-22 18:28:00 +00:00
|
|
|
|
2018-06-19 15:00:07 +00: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-04-22 18:28:00 +00:00
|
|
|
|
2018-06-19 15:00:07 +00:00
|
|
|
if (!uri.port) {
|
|
|
|
uri.port = 6667;
|
2018-04-22 18:28:00 +00:00
|
|
|
}
|
|
|
|
|
2018-06-19 15:00:07 +00:00
|
|
|
data.tls = false;
|
|
|
|
} else if (uri.protocol === "ircs:") {
|
|
|
|
uri.protocol = "https:";
|
|
|
|
|
|
|
|
if (!uri.port) {
|
|
|
|
uri.port = 6697;
|
2018-04-22 18:28:00 +00:00
|
|
|
}
|
2018-06-19 15:00:07 +00:00
|
|
|
|
|
|
|
data.tls = true;
|
|
|
|
} else {
|
|
|
|
return;
|
2018-04-22 18:28:00 +00:00
|
|
|
}
|
2018-06-19 15:00:07 +00: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-04-22 18:28:00 +00:00
|
|
|
}
|
2018-06-19 15:00:07 +00: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";
|
|
|
|
}
|
|
|
|
|
2019-06-25 08:51:47 +00:00
|
|
|
if (!Object.prototype.hasOwnProperty.call(data.defaults, key)) {
|
2018-06-19 15:00:07 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-08-11 22:06:23 +00:00
|
|
|
// When the network is locked, URL overrides should not affect disabled fields
|
2019-07-17 09:33:59 +00:00
|
|
|
if (data.lockNetwork && ["host", "port", "tls", "rejectUnauthorized"].includes(key)) {
|
2018-08-11 22:06:23 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-08-11 22:12:49 +00:00
|
|
|
// When the network is not displayed, its name in the UI is not customizable
|
|
|
|
if (!data.displayNetwork && key === "name") {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-06-19 15:00:07 +00:00
|
|
|
if (key === "join") {
|
2019-07-17 09:33:59 +00:00
|
|
|
value = value
|
|
|
|
.split(",")
|
|
|
|
.map((chan) => {
|
|
|
|
if (!chan.match(/^[#&!+]/)) {
|
|
|
|
return `#${chan}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
return chan;
|
|
|
|
})
|
|
|
|
.join(", ");
|
2018-06-19 15:00:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Override server provided defaults with parameters passed in the URL if they match the data type
|
|
|
|
switch (typeof data.defaults[key]) {
|
2019-07-17 09:33:59 +00:00
|
|
|
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;
|
2018-06-19 15:00:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|