-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #283 from gampig/feature/database-versioning
Feature/database versioning
- Loading branch information
Showing
9 changed files
with
201 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
VUE_APP_TITLE=FeuerwehrApp | ||
VUE_APP_SUPPORTED_DATABASE_SCHEMA_VERSION=1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
{ | ||
"projects": { | ||
"default": "feuerwehr-parkstetten" | ||
"default": "feuerwehr-parkstetten", | ||
"test": "feuerwehr-parkstetten-test" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,145 @@ | ||
<template> | ||
<v-app id="feuerwehr-app"> | ||
<router-view /> | ||
<Loading :visible="loading" text="Anmelden..." /> | ||
<Loading v-if="loading" visible :text="loadingScreenText" /> | ||
<router-view v-else /> | ||
</v-app> | ||
</template> | ||
|
||
<script> | ||
<script lang="ts" setup> | ||
import version from "@/utils/version"; | ||
import modules from "./modules"; | ||
import Loading from "@/components/Loading"; | ||
import Loading from "@/components/Loading.vue"; | ||
import { requires } from "./utils/routerAuth"; | ||
import { mapActions, mapState } from "pinia"; | ||
import { useAuthStore } from "./stores/auth"; | ||
import { useDatabaseSchemaStore } from "./stores/databaseSchema"; | ||
import { computed, ref, watch, watchEffect } from "vue"; | ||
import router from "./router"; | ||
import handleError from "./utils/store/handleError"; | ||
export default { | ||
components: { Loading }, | ||
const authStore = useAuthStore(); | ||
const databaseSchemaStore = useDatabaseSchemaStore(); | ||
computed: { | ||
...mapState(useAuthStore, ["loading", "loggedIn"]), | ||
}, | ||
const loadingAuth = computed(() => authStore.loading); | ||
const loggedIn = computed(() => authStore.loggedIn); | ||
const loadingDatabaseSchemaVersion = computed( | ||
() => databaseSchemaStore.loading | ||
); | ||
watch: { | ||
loggedIn() { | ||
this.onStateChanged(); | ||
}, | ||
}, | ||
const serviceWorkerRegistration = ref<ServiceWorkerRegistration | null>(null); | ||
const updateFound = ref(false); | ||
const updateDownloaded = ref(false); | ||
const updateIsRequired = computed(() => databaseSchemaStore.updateIsRequired); | ||
created() { | ||
this.onStateChanged(); | ||
}, | ||
const loading = computed( | ||
() => | ||
loadingAuth.value || | ||
loadingDatabaseSchemaVersion.value || | ||
updateIsRequired.value | ||
); | ||
const loadingScreenText = computed(() => { | ||
if (loadingAuth.value) { | ||
return "Anmelden..."; | ||
} else if (loadingDatabaseSchemaVersion.value) { | ||
return "Lade Daten..."; | ||
} else if (updateIsRequired.value) { | ||
if (updateFound.value) { | ||
return "Lade Update herunter..."; | ||
} else if (updateDownloaded.value) { | ||
return "Update wurde heruntergeladen. Bitte App neu laden."; | ||
} else { | ||
return "Warte auf erforderliches Update..."; | ||
} | ||
} else { | ||
return "Laden..."; | ||
} | ||
}); | ||
methods: { | ||
...mapActions(useAuthStore, ["updateClientMetadata"]), | ||
function checkAuthState() { | ||
if ( | ||
loggedIn.value === true && | ||
!loadingDatabaseSchemaVersion.value && | ||
!updateIsRequired.value | ||
) { | ||
onLogin(); | ||
} else if (loggedIn.value === false) { | ||
onLogout(); | ||
} | ||
} | ||
onStateChanged() { | ||
if (this.loggedIn === true) { | ||
this.onLogin(); | ||
} else if (this.loggedIn === false) { | ||
this.onLogout(); | ||
} | ||
}, | ||
onLogin() { | ||
modules.onLogin(); | ||
const lastOnline = new Date().toISOString(); | ||
this.updateClientMetadata({ | ||
lastOnline, | ||
version, | ||
}); | ||
}, | ||
onLogout() { | ||
modules.onLogout(); | ||
this.toLoginPage(); | ||
}, | ||
toLoginPage() { | ||
if (requires(this.$route, "requiresAuth")) { | ||
this.$router.replace({ | ||
name: "UserLogin", | ||
params: { nextUrl: { name: "Home" } }, | ||
function onLogin() { | ||
modules.onLogin(); | ||
const lastOnline = new Date().toISOString(); | ||
authStore.updateClientMetadata({ | ||
lastOnline, | ||
version, | ||
}); | ||
} | ||
function onLogout() { | ||
modules.onLogout(); | ||
toLoginPage(); | ||
} | ||
function toLoginPage() { | ||
if (requires(router.currentRoute, "requiresAuth")) { | ||
router.replace({ | ||
name: "UserLogin", | ||
params: { nextRouteName: "Home" }, | ||
}); | ||
} | ||
} | ||
function fetchDatabaseSchemaVersion() { | ||
databaseSchemaStore.bind(); | ||
} | ||
function checkDatabaseSchemaVersion() { | ||
if (updateIsRequired.value) { | ||
if (updateDownloaded.value) { | ||
if (serviceWorkerRegistration.value?.waiting) { | ||
alert( | ||
"App wird neugestartet, damit ein erforderliches Update durchgeführt wird." | ||
); | ||
serviceWorkerRegistration.value.waiting.postMessage({ | ||
type: "SKIP_WAITING", | ||
}); | ||
} else { | ||
alert( | ||
"Bitte lade die App neu.\n\nEin erforderliches Update wurde heruntergeladen und muss installiert werden." | ||
); | ||
} | ||
}, | ||
} | ||
} | ||
} | ||
document.addEventListener( | ||
"swUpdateFound", | ||
() => { | ||
updateFound.value = true; | ||
}, | ||
}; | ||
{ once: true } | ||
); | ||
document.addEventListener( | ||
"swUpdated", | ||
(event) => { | ||
if (event instanceof CustomEvent) { | ||
updateDownloaded.value = true; | ||
serviceWorkerRegistration.value = event.detail; | ||
} else { | ||
handleError(new Error("Event ist nicht vom Typ CustomEvent")); | ||
} | ||
}, | ||
{ once: true } | ||
); | ||
watch( | ||
[loggedIn, loadingDatabaseSchemaVersion, updateIsRequired], | ||
checkAuthState | ||
); | ||
watchEffect(checkDatabaseSchemaVersion); | ||
fetchDatabaseSchemaVersion(); | ||
checkAuthState(); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { defineStore } from "pinia"; | ||
import firebase from "firebase/app"; | ||
|
||
interface State { | ||
loading: Boolean; | ||
localSchemaVersion?: Number | null; | ||
remoteSchemaVersion?: Number | null; | ||
} | ||
|
||
export const useDatabaseSchemaStore = defineStore("databaseSchema", { | ||
state: (): State => ({ | ||
loading: true, | ||
localSchemaVersion: process.env.VUE_APP_SUPPORTED_DATABASE_SCHEMA_VERSION, | ||
remoteSchemaVersion: undefined, | ||
}), | ||
|
||
getters: { | ||
updateIsRequired: (state) => | ||
state.localSchemaVersion !== undefined && | ||
state.localSchemaVersion !== null && | ||
state.remoteSchemaVersion !== undefined && | ||
state.remoteSchemaVersion !== null && | ||
state.localSchemaVersion < state.remoteSchemaVersion, | ||
}, | ||
|
||
actions: { | ||
bind() { | ||
firebase | ||
.database() | ||
.ref("schemaVersion") | ||
.once("value") | ||
.then((snapshot) => { | ||
const version = snapshot.val(); | ||
if (typeof version === "number") { | ||
this.remoteSchemaVersion = version; | ||
} | ||
}) | ||
.finally(() => (this.loading = false)); | ||
}, | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters