PWA update available notification (#42)
This commit is contained in:
parent
81e9eef154
commit
ff0f078ee6
5 changed files with 79 additions and 4 deletions
33
src/App.vue
33
src/App.vue
|
@ -11,6 +11,10 @@
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar-end">
|
<div class="navbar-end">
|
||||||
|
<div v-if="updateAvailable" class="update-notification">
|
||||||
|
<p>There is an update for Vikunja available!</p>
|
||||||
|
<a @click="refreshApp()" class="button is-primary noshadow">Update Now</a>
|
||||||
|
</div>
|
||||||
<div class="user">
|
<div class="user">
|
||||||
<img :src="gravatar()" class="avatar" alt=""/>
|
<img :src="gravatar()" class="avatar" alt=""/>
|
||||||
<div class="dropdown is-right is-active">
|
<div class="dropdown is-right is-active">
|
||||||
|
@ -187,6 +191,8 @@
|
||||||
import NamespaceService from './services/namespace'
|
import NamespaceService from './services/namespace'
|
||||||
import authTypes from './models/authTypes'
|
import authTypes from './models/authTypes'
|
||||||
|
|
||||||
|
import swEvents from './ServiceWorker/events'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
|
|
||||||
|
@ -201,6 +207,11 @@
|
||||||
userMenuActive: false,
|
userMenuActive: false,
|
||||||
authTypes: authTypes,
|
authTypes: authTypes,
|
||||||
isOnline: true,
|
isOnline: true,
|
||||||
|
|
||||||
|
// Service Worker stuff
|
||||||
|
updateAvailable: false,
|
||||||
|
registration: null,
|
||||||
|
refreshing: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
@ -226,6 +237,17 @@
|
||||||
if (auth.user.authenticated && auth.user.infos.type === authTypes.USER && (this.$route.params.name === 'home' || this.namespaces.length === 0)) {
|
if (auth.user.authenticated && auth.user.infos.type === authTypes.USER && (this.$route.params.name === 'home' || this.namespaces.length === 0)) {
|
||||||
this.loadNamespaces()
|
this.loadNamespaces()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Service worker communication
|
||||||
|
document.addEventListener(swEvents.SW_UPDATED, this.showRefreshUI, { once: true })
|
||||||
|
|
||||||
|
navigator.serviceWorker.addEventListener(
|
||||||
|
'controllerchange', () => {
|
||||||
|
if (this.refreshing) return;
|
||||||
|
this.refreshing = true;
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
// call the method again if the route changes
|
// call the method again if the route changes
|
||||||
|
@ -261,6 +283,17 @@
|
||||||
setFullPage() {
|
setFullPage() {
|
||||||
this.fullpage = true;
|
this.fullpage = true;
|
||||||
},
|
},
|
||||||
|
showRefreshUI (e) {
|
||||||
|
console.log('recieved refresh event', e)
|
||||||
|
this.registration = e.detail;
|
||||||
|
this.updateAvailable = true;
|
||||||
|
},
|
||||||
|
refreshApp () {
|
||||||
|
this.updateExists = false;
|
||||||
|
if (!this.registration || !this.registration.waiting) { return; }
|
||||||
|
// Notify the service worker to actually do the update
|
||||||
|
this.registration.waiting.postMessage('skipWaiting');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
3
src/ServiceWorker/events.json
Normal file
3
src/ServiceWorker/events.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"SW_UPDATED": "swUpdated"
|
||||||
|
}
|
|
@ -19,3 +19,24 @@ workbox.routing.registerRoute(
|
||||||
new RegExp('.*'),
|
new RegExp('.*'),
|
||||||
new workbox.strategies.StaleWhileRevalidate()
|
new workbox.strategies.StaleWhileRevalidate()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// This code listens for the user's confirmation to update the app.
|
||||||
|
self.addEventListener('message', (e) => {
|
||||||
|
if (!e.data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (e.data) {
|
||||||
|
case 'skipWaiting':
|
||||||
|
self.skipWaiting();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// NOOP
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
workbox.core.clientsClaim();
|
||||||
|
// The precaching code provided by Workbox.
|
||||||
|
self.__precacheManifest = [].concat(self.__precacheManifest || []);
|
||||||
|
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
import { register } from 'register-service-worker'
|
import { register } from 'register-service-worker'
|
||||||
|
import swEvents from './ServiceWorker/events'
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
register(`${process.env.BASE_URL}sw.js`, {
|
register(`${process.env.BASE_URL}sw.js`, {
|
||||||
ready () {
|
ready () {
|
||||||
console.log(
|
console.log('App is being served from cache by a service worker.')
|
||||||
'App is being served from cache by a service worker.'
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
registered () {
|
registered () {
|
||||||
console.log('Service worker has been registered.')
|
console.log('Service worker has been registered.')
|
||||||
|
@ -18,8 +17,12 @@ if (process.env.NODE_ENV === 'production') {
|
||||||
updatefound () {
|
updatefound () {
|
||||||
console.log('New content is downloading.')
|
console.log('New content is downloading.')
|
||||||
},
|
},
|
||||||
updated () {
|
updated (registration) {
|
||||||
console.log('New content is available; please refresh.')
|
console.log('New content is available; please refresh.')
|
||||||
|
// Send an event with the updated info
|
||||||
|
document.dispatchEvent(
|
||||||
|
new CustomEvent(swEvents.SW_UPDATED, { detail:registration })
|
||||||
|
)
|
||||||
},
|
},
|
||||||
offline () {
|
offline () {
|
||||||
console.log('No internet connection found. App is running in offline mode.')
|
console.log('No internet connection found. App is running in offline mode.')
|
||||||
|
|
|
@ -288,3 +288,18 @@ h1,h2,h3,h4,h5,h6{
|
||||||
height: 18px;
|
height: 18px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.update-notification {
|
||||||
|
margin: 1em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: $warning;
|
||||||
|
padding: 0 0 0 .5em;
|
||||||
|
border-radius: $radius;
|
||||||
|
font-size: .9em;
|
||||||
|
color: darken($dark, 5);
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-left: .5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue