diff --git a/client/components/App.vue b/client/components/App.vue index b136874f..48c95a5a 100644 --- a/client/components/App.vue +++ b/client/components/App.vue @@ -13,7 +13,9 @@ diff --git a/client/components/Sidebar.vue b/client/components/Sidebar.vue index 724dac00..bc6a2a2d 100644 --- a/client/components/Sidebar.vue +++ b/client/components/Sidebar.vue @@ -31,27 +31,30 @@ - + > + + + + + + + + + + > + + + + diff --git a/client/css/style.css b/client/css/style.css index 1180f9ce..ff5f2174 100644 --- a/client/css/style.css +++ b/client/css/style.css @@ -554,6 +554,10 @@ p { /* End icons */ +#viewport-mount { + height: 100%; +} + #viewport { display: flex; height: 100%; diff --git a/client/index.html.tpl b/client/index.html.tpl index 847c9477..e7113a9a 100644 --- a/client/index.html.tpl +++ b/client/index.html.tpl @@ -48,7 +48,7 @@ " data-transports="<%- JSON.stringify(transports) %>"> -
+
diff --git a/client/js/router.js b/client/js/router.js index 58381238..5dda701c 100644 --- a/client/js/router.js +++ b/client/js/router.js @@ -2,10 +2,7 @@ const constants = require("./constants"); -import Vue from "vue"; -import VueRouter from "vue-router"; - -Vue.use(VueRouter); +import {createRouter, createWebHashHistory} from "vue-router"; import SignIn from "../components/Windows/SignIn.vue"; import Connect from "../components/Windows/Connect.vue"; @@ -16,7 +13,8 @@ import NetworkEdit from "../components/Windows/NetworkEdit.vue"; import RoutedChat from "../components/RoutedChat.vue"; import store from "./store"; -const router = new VueRouter({ +const router = createRouter({ + history: createWebHashHistory(), routes: [ { name: "SignIn", @@ -100,6 +98,9 @@ router.beforeEach((to, from, next) => { return; } + next(); + return; // TODO + // Handle closing image viewer with the browser back button if (!router.app.$refs.app) { next(); @@ -144,7 +145,7 @@ router.afterEach((to) => { }); function navigate(routeName, params = {}) { - if (router.currentRoute.name) { + if (router.currentRoute.value.name) { router.push({name: routeName, params}).catch(() => {}); } else { // If current route is null, replace the history entry diff --git a/client/js/socket-events/auth.js b/client/js/socket-events/auth.js index 58bbb46c..f91ff8dc 100644 --- a/client/js/socket-events/auth.js +++ b/client/js/socket-events/auth.js @@ -80,7 +80,7 @@ function showSignIn() { window.g_TheLoungeRemoveLoading(); } - if (router.currentRoute.name !== "SignIn") { + if (router.currentRoute.value.name !== "SignIn") { navigate("SignIn"); } } diff --git a/client/js/socket-events/init.js b/client/js/socket-events/init.js index fd0451d9..7071ceb8 100644 --- a/client/js/socket-events/init.js +++ b/client/js/socket-events/init.js @@ -1,6 +1,6 @@ "use strict"; -import Vue from "vue"; +import {nextTick} from "vue"; import socket from "../socket"; import storage from "../localStorage"; import {router, switchToChannel, navigate} from "../router"; @@ -25,13 +25,16 @@ socket.on("init", function (data) { window.g_TheLoungeRemoveLoading(); } - Vue.nextTick(() => { + 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") { + if ( + !router.currentRoute.value.name || + router.currentRoute.value.name === "SignIn" + ) { const channel = store.getters.findChannel(data.active); if (channel) { diff --git a/client/js/socket-events/more.js b/client/js/socket-events/more.js index 5acaa3cb..dbff353e 100644 --- a/client/js/socket-events/more.js +++ b/client/js/socket-events/more.js @@ -1,6 +1,6 @@ "use strict"; -import Vue from "vue"; +import {nextTick} from "vue"; import socket from "../socket"; import store from "../store"; @@ -16,7 +16,7 @@ socket.on("more", function (data) { data.totalMessages > channel.channel.messages.length + data.messages.length; channel.channel.messages.unshift(...data.messages); - Vue.nextTick(() => { + nextTick(() => { channel.channel.historyLoading = false; }); }); diff --git a/client/js/socket-events/msg_preview.js b/client/js/socket-events/msg_preview.js index 310dcd51..1b28546f 100644 --- a/client/js/socket-events/msg_preview.js +++ b/client/js/socket-events/msg_preview.js @@ -1,7 +1,5 @@ "use strict"; -import Vue from "vue"; - import socket from "../socket"; import store from "../store"; @@ -16,6 +14,7 @@ socket.on("msg:preview", function (data) { const previewIndex = message.previews.findIndex((m) => m.link === data.preview.link); if (previewIndex > -1) { - Vue.set(message.previews, previewIndex, data.preview); + // TODO: Does this work? + message.previews[previewIndex] = data.preview; } }); diff --git a/client/js/socket-events/network.js b/client/js/socket-events/network.js index 9f248657..6c00b563 100644 --- a/client/js/socket-events/network.js +++ b/client/js/socket-events/network.js @@ -1,7 +1,5 @@ "use strict"; -import Vue from "vue"; - import socket from "../socket"; import store from "../store"; import {switchToChannel} from "../router"; @@ -61,7 +59,8 @@ socket.on("network:info", function (data) { } for (const key in data) { - Vue.set(network, key, data[key]); + // TODO: does this work in vue? + network[key] = data[key]; } }); diff --git a/client/js/store.js b/client/js/store.js index 3d336d06..1ec52378 100644 --- a/client/js/store.js +++ b/client/js/store.js @@ -1,12 +1,9 @@ -import Vue from "vue"; -import Vuex from "vuex"; +import {createStore} from "vuex"; import {createSettingsStore} from "./store-settings"; import storage from "./localStorage"; const appName = document.title; -Vue.use(Vuex); - function detectDesktopNotificationState() { if (!("Notification" in window)) { return "unsupported"; @@ -17,7 +14,7 @@ function detectDesktopNotificationState() { return "blocked"; } -const store = new Vuex.Store({ +const store = createStore({ state: { appLoaded: false, activeChannel: null, diff --git a/client/js/vue.js b/client/js/vue.js index 18f913da..3ce00ceb 100644 --- a/client/js/vue.js +++ b/client/js/vue.js @@ -3,12 +3,11 @@ const constants = require("./constants"); import "../css/style.css"; -import Vue from "vue"; +import {createApp} from "vue"; import store from "./store"; import App from "../components/App.vue"; import storage from "./localStorage"; -import {router, navigate} from "./router"; -import socket from "./socket"; +import {router} from "./router"; import eventbus from "./eventbus"; import "./socket-events"; @@ -19,57 +18,10 @@ const favicon = document.getElementById("favicon"); const faviconNormal = favicon.getAttribute("href"); const faviconAlerted = favicon.dataset.other; -new Vue({ - el: "#viewport", - router, - mounted() { - socket.open(); - }, - methods: { - switchToChannel(channel) { - navigate("RoutedChat", {id: channel.id}); - }, - closeChannel(channel) { - if (channel.type === "lobby") { - eventbus.emit( - "confirm-dialog", - { - title: "Remove network", - text: `Are you sure you want to quit and remove ${channel.name}? This cannot be undone.`, - button: "Remove network", - }, - (result) => { - if (!result) { - return; - } - - channel.closed = true; - socket.emit("input", { - target: Number(channel.id), - text: "/quit", - }); - } - ); - - return; - } - - channel.closed = true; - - socket.emit("input", { - target: Number(channel.id), - text: "/close", - }); - }, - }, - render(createElement) { - return createElement(App, { - ref: "app", - props: this, - }); - }, - store, -}); +const vueApp = createApp(App); +vueApp.use(store); +vueApp.use(router); +vueApp.mount("#viewport-mount"); store.watch( (state) => state.sidebarOpen, @@ -112,7 +64,7 @@ store.watch( } ); -Vue.config.errorHandler = function (e) { +vueApp.config.errorHandler = function (e) { store.commit("currentUserVisibleError", `Vue error: ${e.message}`); console.error(e); // eslint-disable-line }; diff --git a/webpack.config.js b/webpack.config.js index c7dd8872..e2e51251 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -87,6 +87,10 @@ const config = { json3: "JSON", // socket.io uses json3.js, but we do not target any browsers that need it }, plugins: [ + new webpack.DefinePlugin({ + __VUE_OPTIONS_API__: true, + __VUE_PROD_DEVTOOLS__: false, + }), new VueLoaderPlugin(), new MiniCssExtractPlugin({ filename: "css/style.css",