Support PWA (#437)

* add PWA

* cleanup

* add offline cache
This commit is contained in:
wengtad
2021-05-28 00:48:59 +08:00
committed by GitHub
parent 8e7a17b1bb
commit 39baca4462
26 changed files with 1034 additions and 45 deletions

View File

@@ -9,6 +9,17 @@
</div>
</v-banner>
<GlobalSnackbar />
<v-snackbar v-model="snackWithButtons" bottom left timeout="-1">
{{ snackWithBtnText }}
<template v-slot:action="{ attrs }">
<v-btn text color="primary" v-bind="attrs" @click.stop="refreshApp">
{{ snackBtnText }}
</v-btn>
<v-btn icon class="ml-4" @click="snackWithButtons = false">
<v-icon>{{ $globals.icons.close }}</v-icon>
</v-btn>
</template>
</v-snackbar>
<router-view></router-view>
</v-main>
</v-app>
@@ -51,6 +62,29 @@ export default {
this.$store.dispatch("requestSiteSettings");
},
data() {
return {
refreshing: false,
registration: null,
snackBtnText: "",
snackWithBtnText: "",
snackWithButtons: false,
};
},
created() {
// Listen for swUpdated event and display refresh snackbar as required.
document.addEventListener("swUpdated", this.showRefreshUI, { once: true });
// Refresh all open app tabs when a new service worker is installed.
if (navigator.serviceWorker) {
navigator.serviceWorker.addEventListener("controllerchange", () => {
if (this.refreshing) return;
this.refreshing = true;
window.location.reload();
});
}
},
methods: {
// For Later!
@@ -70,6 +104,25 @@ export default {
this.darkModeSystemCheck();
});
},
showRefreshUI(e) {
// Display a snackbar inviting the user to refresh/reload the app due
// to an app update being available.
// The new service worker is installed, but not yet active.
// Store the ServiceWorkerRegistration instance for later use.
this.registration = e.detail;
this.snackBtnText = "Refresh";
this.snackWithBtnText = "New version available!";
this.snackWithButtons = true;
},
refreshApp() {
this.snackWithButtons = false;
// Protect against missing registration.waiting.
if (!this.registration || !this.registration.waiting) {
return;
}
this.registration.waiting.postMessage("skipWaiting");
},
},
};
</script>