release v2.0.0 #4

Merged
crimsen merged 481 commits from develop into master 2024-01-18 15:15:08 +00:00
7 changed files with 80 additions and 63 deletions
Showing only changes of commit 29c085bd2c - Show all commits

View File

@ -10,7 +10,7 @@ function loadToken() {
} }
function clearToken() { function clearToken() {
PersistentStorage.remove('fg_token'); void PersistentStorage.remove('fg_token');
} }
export function saveToken(token?: string) { export function saveToken(token?: string) {

View File

@ -1,7 +1,8 @@
import { LocalStorage, Platform } from 'quasar'; import { LocalStorage, Platform } from 'quasar';
import { Storage } from '@capacitor/storage'; import { Storage } from '@capacitor/storage';
type GetReturn = Date | number | boolean | string | object; // eslint-disable-next-line @typescript-eslint/no-explicit-any
type PersitentTypes = Date | RegExp | number | boolean | string | object;
export class PersistentStorage { export class PersistentStorage {
static clear() { static clear() {
@ -14,13 +15,12 @@ export class PersistentStorage {
else return Promise.resolve(LocalStorage.remove(key)); else return Promise.resolve(LocalStorage.remove(key));
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any static set(key: string, value: PersitentTypes) {
static set(key: string, value: any) {
if (Platform.is.capacitor) return Storage.set({ key, value: JSON.stringify(value) }); if (Platform.is.capacitor) return Storage.set({ key, value: JSON.stringify(value) });
else return Promise.resolve(LocalStorage.set(key, value)); else return Promise.resolve(LocalStorage.set(key, value));
} }
static get<T extends GetReturn>(key: string) { static get<T extends PersitentTypes>(key: string) {
if (Platform.is.capacitor) if (Platform.is.capacitor)
return Storage.get({ key }).then((v) => return Storage.get({ key }).then((v) =>
v.value === null ? null : (JSON.parse(v.value) as T) v.value === null ? null : (JSON.parse(v.value) as T)

View File

@ -1,5 +1,4 @@
import { useMainStore, api } from '@flaschengeist/api'; import { useMainStore, api } from '@flaschengeist/api';
import { LocalStorage, Notify } from 'quasar';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { boot } from 'quasar/wrappers'; import { boot } from 'quasar/wrappers';
import config from 'src/config'; import config from 'src/config';
@ -31,7 +30,8 @@ function minify(o: unknown, cloned = false) {
} }
export default boot(({ router }) => { export default boot(({ router }) => {
api.defaults.baseURL = LocalStorage.getItem<string>('baseURL') || config.baseURL; // Persisted value is read in plugins.ts boot file!
api.defaults.baseURL = config.baseURL;
/*** /***
* Intercept requests * Intercept requests
@ -95,17 +95,3 @@ export default boot(({ router }) => {
}); });
export { api }; export { api };
export const setBaseURL = (url: string) => {
LocalStorage.set('baseURL', url);
api.defaults.baseURL = url;
Notify.create({
message: 'Serveraddresse gespeichert',
position: 'bottom',
caption: `${url}`,
color: 'positive',
});
setTimeout(() => {
window.location.reload();
}, 5000);
};

View File

@ -1,10 +1,10 @@
import { Notify } from 'quasar'; import { Notify, Platform } from 'quasar';
import { api } from 'src/boot/axios'; import { api } from 'src/boot/axios';
import { boot } from 'quasar/wrappers'; import { boot } from 'quasar/wrappers';
import routes from 'src/router/routes'; import routes from 'src/router/routes';
import { AxiosResponse } from 'axios';
import { RouteRecordRaw } from 'vue-router'; import { RouteRecordRaw } from 'vue-router';
import { FG_Plugin } from '@flaschengeist/types'; import { FG_Plugin } from '@flaschengeist/types';
import { PersistentStorage } from '@flaschengeist/api';
/**************************************************** /****************************************************
******** Internal area for some magic ************** ******** Internal area for some magic **************
@ -264,16 +264,24 @@ function loadPlugin(
return true; return true;
} }
async function loadBaseUrl() {
return PersistentStorage.get<string>('baseURL').then((url) => {
if (url !== null) api.defaults.baseURL = url;
console.log('loaded: ', url, api.defaults.baseURL);
});
}
/** /**
* Loading backend information * Loading backend information
* @returns Backend object or null * @returns Backend object or null
*/ */
async function getBackend() { async function getBackend() {
try { try {
const { data }: AxiosResponse<Backend> = await api.get('/'); const { data } = await api.get<Backend>('/');
if (!data || typeof data !== 'object' || !('plugins' in data))
throw Error('Invalid backend response received');
return data; return data;
} catch (e) { } catch (e) {
console.warn(e); console.error('Loading backend', e);
return null; return null;
} }
} }
@ -282,10 +290,13 @@ async function getBackend() {
* Boot file, load all required plugins, check for dependencies * Boot file, load all required plugins, check for dependencies
*/ */
export default boot(async ({ router, app }) => { export default boot(async ({ router, app }) => {
await loadBaseUrl();
const backend = await getBackend(); const backend = await getBackend();
if (!backend || typeof backend !== 'object' || !('plugins' in backend)) { if (backend === null) {
console.log('Backend error'); router.isReady().finally(() => {
router.isReady().finally(() => void router.push({ name: 'offline', params: { refresh: 1 } })); if (Platform.is.capacitor) void router.push({ name: 'setup_backend' });
else void router.push({ name: 'offline', params: { refresh: 1 } });
});
return; return;
} }

46
src/pages/Backend.vue Normal file
View File

@ -0,0 +1,46 @@
<template>
<div class="row justify-center items-center content-center q-pa-md">
<q-card class="col-xs-11 col-sm-8 col-md-6 col-lg-4 justify-center items-center content-center">
<q-toolbar class="bg-primary text-white">
<q-toolbar-title>Servereinstellung</q-toolbar-title>
</q-toolbar>
<q-card-section>
<q-form class="q-gutter-md" @submit="changeUrl">
<q-input v-model="server" filled label="Server" dense />
<q-btn dense color="primary" label="Speichern" type="submit" />
</q-form>
</q-card-section>
</q-card>
</div>
</template>
<script lang="ts">
import { useRouter } from 'vue-router';
import { notEmpty, PersistentStorage } from '@flaschengeist/api';
import { defineComponent, ref } from 'vue';
import { api } from 'boot/axios';
export default defineComponent({
name: 'PageBackend',
setup() {
const router = useRouter();
const server = ref(api.defaults.baseURL);
function changeUrl() {
if (server.value) {
void PersistentStorage.set('baseURL', server.value).then(() => {
console.log('uiuiui');
void router.push({ name: 'login' }).then(() => router.go(0));
});
}
}
return {
changeUrl,
notEmpty,
server,
};
},
});
</script>

View File

@ -44,25 +44,13 @@
</q-card-section> </q-card-section>
<div class="row justify-end"> <div class="row justify-end">
<q-btn <q-btn
v-if="quasar.platform.is.cordova || quasar.platform.is.electron" v-if="$q.platform.is.capacitor || $q.platform.is.electron"
flat flat
round round
icon="mdi-menu-down" icon="mdi-menu-down"
@click="openServerSettings" :to="{ name: 'setup_backend' }"
/> />
</div> </div>
<q-slide-transition v-if="quasar.platform.is.cordova || quasar.platform.is.electron">
<div v-show="visible">
<q-separator />
<q-card-section>
<q-form ref="ServerSettingsForm" class="q-gutter-md" @submit="changeUrl">
<div class="text-h6">Servereinstellung</div>
<q-input v-model="server" filled label="Server" dense />
<q-btn size="xs" dense color="primary" label="Speichern" type="submit" />
</q-form>
</q-card-section>
</div>
</q-slide-transition>
</q-card> </q-card>
</q-page> </q-page>
</template> </template>
@ -73,34 +61,20 @@ import { Loading, Notify } from 'quasar';
import { notEmpty, useMainStore, useUserStore } from '@flaschengeist/api'; import { notEmpty, useMainStore, useUserStore } from '@flaschengeist/api';
import { PasswordInput } from '@flaschengeist/api/components'; import { PasswordInput } from '@flaschengeist/api/components';
import { defineComponent, ref } from 'vue'; import { defineComponent, ref } from 'vue';
import { setBaseURL, api } from 'boot/axios';
import { useQuasar } from 'quasar';
export default defineComponent({ export default defineComponent({
name: 'PageLogin', name: 'PageLogin',
components: { PasswordInput }, components: { PasswordInput },
setup() { setup() {
const mainRoute = { name: 'dashboard' };
const mainStore = useMainStore(); const mainStore = useMainStore();
const userStore = useUserStore(); const userStore = useUserStore();
const mainRoute = { name: 'dashboard' };
const router = useRouter(); const router = useRouter();
/* Stuff for the real login page */ /* Stuff for the real login page */
const userid = ref(''); const userid = ref('');
const password = ref(''); const password = ref('');
const server = ref<string | undefined>(api.defaults.baseURL);
const visible = ref(false);
const quasar = useQuasar();
function openServerSettings() {
visible.value = !visible.value;
}
function changeUrl() {
if (server.value) {
setBaseURL(server.value);
}
}
async function doLogin() { async function doLogin() {
Loading.show({ message: 'Du wirst angemeldet' }); Loading.show({ message: 'Du wirst angemeldet' });
@ -155,16 +129,11 @@ export default defineComponent({
} }
return { return {
changeUrl,
doLogin, doLogin,
doReset, doReset,
notEmpty, notEmpty,
openServerSettings,
password, password,
server,
userid, userid,
visible,
quasar,
}; };
}, },
}); });

View File

@ -53,6 +53,11 @@ const routes: RouteRecordRaw[] = [
name: 'offline', name: 'offline',
component: () => import('pages/Offline.vue'), component: () => import('pages/Offline.vue'),
}, },
{
path: '/setup-backend',
name: 'setup_backend',
component: () => import('pages/Backend.vue'),
},
// Always leave this as last one, // Always leave this as last one,
// but you can also remove it // but you can also remove it
{ {