From 181a19899491cc2af7154670e74b0637a0a9060d Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Mon, 20 Jul 2020 11:38:12 +0300 Subject: [PATCH] Cleanup vue router route guards --- client/js/router.js | 86 ++++++++++++++++++--------------- client/js/socket-events/init.js | 52 ++++++++++++-------- 2 files changed, 79 insertions(+), 59 deletions(-) diff --git a/client/js/router.js b/client/js/router.js index 1ead0f9f..489b9441 100644 --- a/client/js/router.js +++ b/client/js/router.js @@ -32,12 +32,58 @@ const router = new VueRouter({ next(); }, }, + { + name: "Connect", + path: "/connect", + component: Connect, + props: (route) => ({queryParams: route.query}), + }, + { + name: "Settings", + path: "/settings", + component: Settings, + }, + { + name: "Help", + path: "/help", + component: Help, + }, + { + name: "Changelog", + path: "/changelog", + component: Changelog, + }, + { + name: "NetworkEdit", + path: "/edit-network/:uuid", + component: NetworkEdit, + }, + { + name: "RoutedChat", + path: "/chan-:id", + component: RoutedChat, + }, ], }); +router.beforeEach((to, from, next) => { + // If user is not yet signed in, wait for appLoaded state to change + // unless they are trying to open SignIn (which can be triggered in auth.js) + if (!store.state.appLoaded && to.name !== "SignIn") { + store.watch( + (state) => state.appLoaded, + () => next() + ); + + return; + } + + next(); +}); + router.beforeEach((to, from, next) => { // Disallow navigating to non-existing routes - if (store.state.appLoaded && !to.matched.length) { + if (!to.matched.length) { next(false); return; } @@ -91,42 +137,6 @@ router.afterEach((to) => { } }); -function initialize() { - router.addRoutes([ - { - name: "Connect", - path: "/connect", - component: Connect, - props: (route) => ({queryParams: route.query}), - }, - { - name: "Settings", - path: "/settings", - component: Settings, - }, - { - name: "Help", - path: "/help", - component: Help, - }, - { - name: "Changelog", - path: "/changelog", - component: Changelog, - }, - { - name: "NetworkEdit", - path: "/edit-network/:uuid", - component: NetworkEdit, - }, - { - name: "RoutedChat", - path: "/chan-:id", - component: RoutedChat, - }, - ]); -} - function navigate(routeName, params = {}) { if (router.currentRoute.name) { router.push({name: routeName, params}).catch(() => {}); @@ -156,4 +166,4 @@ if ("serviceWorker" in navigator) { }); } -export {initialize, router, navigate, switchToChannel}; +export {router, navigate, switchToChannel}; diff --git a/client/js/socket-events/init.js b/client/js/socket-events/init.js index bef3f47f..fd0451d9 100644 --- a/client/js/socket-events/init.js +++ b/client/js/socket-events/init.js @@ -1,8 +1,9 @@ "use strict"; +import Vue from "vue"; import socket from "../socket"; import storage from "../localStorage"; -import {router, switchToChannel, navigate, initialize as routerInitialize} from "../router"; +import {router, switchToChannel, navigate} from "../router"; import store from "../store"; import parseIrcUri from "../helpers/parseIrcUri"; @@ -16,10 +17,6 @@ socket.on("init", function (data) { } if (!store.state.appLoaded) { - // Routes are initialized after networks data is merged - // so the route guard for channels works correctly on page load - routerInitialize(); - store.commit("appLoaded"); socket.emit("setting:get"); @@ -28,24 +25,27 @@ socket.on("init", function (data) { window.g_TheLoungeRemoveLoading(); } - // TODO: Review this code and make it better - if (!router.currentRoute.name || router.currentRoute.name === "SignIn") { - const channel = store.getters.findChannel(data.active); + Vue.nextTick(() => { + // If we handled query parameters like irc:// links or just general + // connect parameters in public mode, then nothing to do here + if (!handleQueryParams()) { + // If we are on an unknown route or still on SignIn component + // then we can open last known channel on server, or Connect window if none + if (!router.currentRoute.name || router.currentRoute.name === "SignIn") { + const channel = store.getters.findChannel(data.active); - if (channel) { - switchToChannel(channel.channel); - } else if (store.state.networks.length > 0) { - // Server is telling us to open a channel that does not exist - // For example, it can be unset if you first open the page after server start - switchToChannel(store.state.networks[0].channels[0]); - } else { - navigate("Connect"); + if (channel) { + switchToChannel(channel.channel); + } else if (store.state.networks.length > 0) { + // Server is telling us to open a channel that does not exist + // For example, it can be unset if you first open the page after server start + switchToChannel(store.state.networks[0].channels[0]); + } else { + navigate("Connect"); + } + } } - } - - if ("URLSearchParams" in window) { - handleQueryParams(); - } + }); } }); @@ -154,6 +154,10 @@ function mergeChannelData(oldChannels, newChannels) { } function handleQueryParams() { + if (!("URLSearchParams" in window)) { + return false; + } + const params = new URLSearchParams(document.location.search); const cleanParams = () => { @@ -169,11 +173,17 @@ function handleQueryParams() { cleanParams(); router.push({name: "Connect", query: queryParams}); + + return true; } else if (document.body.classList.contains("public") && document.location.search) { // Set default connection settings from url params const queryParams = Object.fromEntries(params.entries()); cleanParams(); router.push({name: "Connect", query: queryParams}); + + return true; } + + return false; }