Move url parameter handling to vue
This commit is contained in:
parent
897f238c38
commit
0c7db6dffe
@ -1,9 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<NetworkForm
|
<NetworkForm :handle-submit="handleSubmit" :defaults="defaults" :disabled="disabled" />
|
||||||
:handle-submit="handleSubmit"
|
|
||||||
:defaults="$store.state.serverConfiguration.defaults"
|
|
||||||
:disabled="disabled"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@ -16,9 +12,19 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
NetworkForm,
|
NetworkForm,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
queryParams: Object,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
|
// Merge settings from url params into default settings
|
||||||
|
const defaults = Object.assign(
|
||||||
|
{},
|
||||||
|
this.$store.state.serverConfiguration.defaults,
|
||||||
|
this.parseOverrideParams(this.queryParams)
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
defaults,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -26,6 +32,73 @@ export default {
|
|||||||
this.disabled = true;
|
this.disabled = true;
|
||||||
socket.emit("network:new", data);
|
socket.emit("network:new", data);
|
||||||
},
|
},
|
||||||
|
parseOverrideParams(params) {
|
||||||
|
const parsedParams = {};
|
||||||
|
|
||||||
|
for (let key of Object.keys(params)) {
|
||||||
|
if (params[key] === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param can contain multiple values in an array if its supplied more than once
|
||||||
|
let value = typeof params[key] === "string" ? params[key] : params[key][0];
|
||||||
|
|
||||||
|
// Support `channels` as a compatibility alias with other clients
|
||||||
|
if (key === "channels") {
|
||||||
|
key = "join";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Object.prototype.hasOwnProperty.call(
|
||||||
|
this.$store.state.serverConfiguration.defaults,
|
||||||
|
key
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the network is locked, URL overrides should not affect disabled fields
|
||||||
|
if (
|
||||||
|
this.$store.state.lockNetwork &&
|
||||||
|
["host", "port", "tls", "rejectUnauthorized"].includes(key)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the network is not displayed, its name in the UI is not customizable
|
||||||
|
if (!this.$store.state.serverConfiguration.displayNetwork && key === "name") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 this.$store.state.serverConfiguration.defaults[key]) {
|
||||||
|
case "boolean":
|
||||||
|
parsedParams[key] = value === "1" || value === "true";
|
||||||
|
break;
|
||||||
|
case "number":
|
||||||
|
parsedParams[key] = Number(value);
|
||||||
|
break;
|
||||||
|
case "string":
|
||||||
|
parsedParams[key] = String(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedParams;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -35,7 +35,8 @@ const router = new VueRouter({
|
|||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
// Disallow navigating to non-existing routes
|
// Disallow navigating to non-existing routes
|
||||||
if (!to.matched.length) {
|
|
||||||
|
if (store.state.appLoaded && !to.matched.length) {
|
||||||
next(false);
|
next(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -84,8 +85,9 @@ function initialize() {
|
|||||||
router.addRoutes([
|
router.addRoutes([
|
||||||
{
|
{
|
||||||
name: "Connect",
|
name: "Connect",
|
||||||
path: "/connect",
|
path: "/connect*",
|
||||||
component: Connect,
|
component: Connect,
|
||||||
|
props: (route) => ({queryParams: route.query}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Settings",
|
name: "Settings",
|
||||||
|
@ -5,6 +5,7 @@ const socket = require("../socket");
|
|||||||
const webpush = require("../webpush");
|
const webpush = require("../webpush");
|
||||||
const upload = require("../upload");
|
const upload = require("../upload");
|
||||||
const store = require("../store").default;
|
const store = require("../store").default;
|
||||||
|
const {vueApp} = require("../vue");
|
||||||
|
|
||||||
window.addEventListener("beforeinstallprompt", (installPromptEvent) => {
|
window.addEventListener("beforeinstallprompt", (installPromptEvent) => {
|
||||||
$("#webapp-install-button")
|
$("#webapp-install-button")
|
||||||
@ -75,16 +76,32 @@ socket.once("configuration", function(data) {
|
|||||||
if ("URLSearchParams" in window) {
|
if ("URLSearchParams" in window) {
|
||||||
const params = new URLSearchParams(document.location.search);
|
const params = new URLSearchParams(document.location.search);
|
||||||
|
|
||||||
|
const cleanParams = () => {
|
||||||
|
// Remove query parameters from url without reloading the page
|
||||||
|
const cleanUri =
|
||||||
|
window.location.origin + window.location.pathname + window.location.hash;
|
||||||
|
window.history.replaceState({}, document.title, cleanUri);
|
||||||
|
};
|
||||||
|
|
||||||
if (params.has("uri")) {
|
if (params.has("uri")) {
|
||||||
parseIrcUri(params.get("uri") + location.hash, data);
|
// Set default connection settings from IRC protocol links
|
||||||
} else if ($(document.body).hasClass("public")) {
|
const uri =
|
||||||
parseOverrideParams(params, data);
|
params.get("uri") +
|
||||||
|
(location.hash.includes("#/") ? location.hash.split("#/")[0] : location.hash);
|
||||||
|
const queryParams = parseIrcUri(uri, data);
|
||||||
|
cleanParams();
|
||||||
|
vueApp.$router.push({path: "/connect", query: queryParams});
|
||||||
|
} else if (document.body.classList.contains("public") && document.location.search) {
|
||||||
|
// Set default connection settings from url params
|
||||||
|
const queryParams = document.location.search;
|
||||||
|
cleanParams();
|
||||||
|
vueApp.$router.push("/connect" + queryParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function parseIrcUri(stringUri, defaults) {
|
function parseIrcUri(stringUri) {
|
||||||
const data = Object.assign({}, defaults.defaults);
|
const data = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// https://tools.ietf.org/html/draft-butcher-irc-url-04
|
// https://tools.ietf.org/html/draft-butcher-irc-url-04
|
||||||
@ -125,61 +142,9 @@ function parseIrcUri(stringUri, defaults) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.join = channel;
|
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) {
|
} catch (e) {
|
||||||
// do nothing on invalid uri
|
// do nothing on invalid uri
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
return data;
|
||||||
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)) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user