feat/FRO-36: PWA (#25)

Added a PWA for knockoutwhist including a special offline screen.

Co-authored-by: LQ63 <lkhermann@web.de>
Reviewed-on: #25
Reviewed-by: Janis <janis-e@gmx.de>
Co-authored-by: lq64 <lq@blackhole.local>
Co-committed-by: lq64 <lq@blackhole.local>
This commit is contained in:
2025-12-18 09:46:23 +01:00
committed by Janis
parent 9feb4a93b8
commit 2fbfca32a0
8 changed files with 4602 additions and 129 deletions

View File

@@ -8,6 +8,7 @@ import axios from "axios";
import { useUserInfo } from "@/composables/useUserInfo";
import rulesView from "../components/Rules.vue";
import Game from "@/views/Game.vue";
import OfflineView from "@/views/OfflineView.vue";
const api = window?.__RUNTIME_CONFIG__?.API_URL;
const router = createRouter({
@@ -55,12 +56,40 @@ const router = createRouter({
name: 'game',
component: Game,
meta: {requiresAuth: true }
},
{
path: '/offline',
name: 'offline',
component: OfflineView,
meta: {requiresAuth: false }
}
],
})
router.beforeEach(async (to, from, next) => {
const info = useUserInfo();
const isOnline = navigator.onLine;
if (to.name === 'offline') {
if (isOnline) {
try {
const response = await axios.get(`${api}/userInfo`, { withCredentials: true });
info.setUserInfo(response.data.username, response.data.userId);
return next({ name: 'mainmenu' });
} catch (err) {
info.clearUserInfo();
return next('/login');
}
} else {
return next();
}
}
if (!isOnline) {
return next({ name: 'offline' });
}
if (!to.meta.requiresAuth) return next();
try {
await axios.get(`${api}/userInfo`, { withCredentials: true }).then(
@@ -70,8 +99,9 @@ router.beforeEach(async (to, from, next) => {
);
next();
} catch (err) {
info.clearUserInfo();
next('/login');
info.clearUserInfo();
next('/login');
}
});