From d3709ed8525858a5ed0a69c21a259d774c90dec5 Mon Sep 17 00:00:00 2001 From: Janis Date: Tue, 20 Jan 2026 12:28:20 +0100 Subject: [PATCH] feat/auth (#29) Reviewed-on: https://git.janis-eccarius.de/KnockOutWhist/KnockOutWhist-Frontend/pulls/29 Co-authored-by: Janis Co-committed-by: Janis --- src/App.vue | 73 +--- src/components/MainMenuBoxes.vue | 44 ++- src/components/User.vue | 17 +- src/composables/useWebsocket.ts | 20 +- src/main.ts | 10 +- src/router/index.ts | 36 +- src/views/Game.vue | 11 +- src/views/LoginView.vue | 378 ++++++++++++++++---- src/views/RegisterView.vue | 516 ++++++++++++++++++++++++++++ src/views/UsernameSelectionView.vue | 457 ++++++++++++++++++++++++ 10 files changed, 1411 insertions(+), 151 deletions(-) create mode 100644 src/views/RegisterView.vue create mode 100644 src/views/UsernameSelectionView.vue diff --git a/src/App.vue b/src/App.vue index 8ce5497..b06dc33 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,10 +3,7 @@ import { RouterView } from 'vue-router' import { onMounted, onUnmounted, watch } from 'vue'; import { useRoute, useRouter } from 'vue-router'; import { useUserInfo } from "@/composables/useUserInfo"; -import { useIngame } from "@/composables/useIngame"; -import { storeToRefs } from "pinia"; -import { useWebSocket } from "@/composables/useWebsocket"; -import { useQuasar } from "quasar"; +import {Dark } from "quasar"; const route = useRoute(); const router = useRouter(); @@ -22,15 +19,26 @@ const handleOnlineStatusChange = () => { let interval: number | null = null; -onMounted(() => { +onMounted(async () => { window.addEventListener('online', handleOnlineStatusChange); + // Initialize dark mode based on browser preference + Dark.set('auto'); + + // Immediately check user state on app load + if (navigator.onLine) { + await info.requestState(); + if (!info.username && route.meta.requiresAuth) { + router.push({ name: '/' }); + } + } + // Continuously check user state every 10 seconds interval = window.setInterval(async () => { - if (navigator.onLine && route.name !== 'login' && route.name !== 'offline') { + if (navigator.onLine) { await info.requestState(); - if (!info.username && route.name !== 'login') { - router.push({ name: 'login' }); + if (!info.username && route.meta.requiresAuth) { + router.push({ name: '/' }); } } }, 10000); @@ -48,55 +56,6 @@ watch(() => info.gameId, (newGameId) => { router.push({ name: 'game' }); } }); - -const ig = useIngame() -const { isWsConnected } = storeToRefs(ig) -const wb = useWebSocket() -const $q = useQuasar(); - -watch(isWsConnected, (connected) => { - if (!connected && info.gameId && route.name === 'game') { - showReconnectDialog(); - } -}); - -function showReconnectDialog() { - $q.dialog({ - title: 'Connection Lost', - message: 'The connection to the game server was lost. Would you like to reconnect?', - persistent: true, - ok: { - label: 'Reconnect', - color: 'positive' - }, - cancel: { - label: 'Quit', - color: 'negative' - } - }).onOk(() => { - reconnect(); - }).onCancel(() => { - router.replace("/"); - }); -} - -async function reconnect() { - try { - await wb.connect(); - $q.notify({ - message: 'Reconnected successfully!', - color: 'positive', - icon: 'check' - }); - } catch (err) { - $q.notify({ - message: 'Failed to reconnect. Please try again.', - color: 'negative', - icon: 'error' - }); - showReconnectDialog(); - } -}