Skip to content

Commit

Permalink
feat(serviceworker): make updatable by selection
Browse files Browse the repository at this point in the history
  • Loading branch information
rudnovd committed Jan 21, 2022
1 parent 9ef5e8a commit 9d5ff7e
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 43 deletions.
59 changes: 37 additions & 22 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,60 @@
Home page
</router-link>
<router-view />

<BaseNotification v-if="needRefresh" :show="needRefresh" :buttons="notificationsButtons">
New content is available.
</BaseNotification>
</template>

<script lang="ts">
import { useRegisterSW } from 'virtual:pwa-register/vue'
import { defineComponent, watch } from 'vue'
import { defineComponent } from 'vue'
import { useRoute } from 'vue-router'
import BaseNotification from './components/base/BaseNotification.vue'
import { useStore } from './store'
const { needRefresh, updateServiceWorker } = useRegisterSW({
immediate: true,
onRegistered(registration) {
if (import.meta.env.DEV && registration) {
setInterval(async () => {
/* eslint-disable no-console */
console.log('Checking for sw update')
await registration.update()
}, 20000 /* 20s for testing purposes */)
} else if (import.meta.env.PROD && registration) {
/* eslint-disable no-console */
console.log('Service worker registered')
}
},
})
export default defineComponent({
name: 'App',
components: { BaseNotification },
setup() {
const store = useStore()
const route = useRoute()
watch(needRefresh, () => {
updateServiceWorker()
/* eslint-disable no-console */
console.log('Service work updated')
})
store.initData()
const { updateServiceWorker, needRefresh } = useRegisterSW({
immediate: false,
onRegistered(registration) {
if (registration) {
/* eslint-disable no-console */
console.log('Service worker registered')
}
},
onRegisterError(error) {
if (error) {
/* eslint-disable no-console */
console.log(`Service worker registartion error: ${error}`)
}
},
})
const notificationsButtons = [
{
text: 'Update app',
onClick: () => {
updateServiceWorker(true)
},
},
{
text: 'Dismiss',
},
]
return {
route,
needRefresh,
notificationsButtons,
}
},
})
Expand Down
51 changes: 35 additions & 16 deletions src/components/base/BaseNotification.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
<template>
<div v-if="show" class="notification-container">
<div class="notification">
<div><slot></slot></div>
<div v-if="buttons" class="notification-buttons">
<button
v-for="(button, index) in buttons"
:key="`button-${index}`"
class="notification-button"
:style="{ color: button.textColor }"
@click="onClick(button)"
>
{{ button.text }}
</button>
<transition name="notification">
<div v-if="showNotification" class="notification">
<div><slot></slot></div>
<div v-if="buttons" class="notification-buttons">
<button
v-for="(button, index) in buttons"
:key="`button-${index}`"
class="notification-button"
:style="{ color: button.textColor }"
@click="onClick(button)"
>
{{ button.text }}
</button>
</div>
</div>
</div>
</transition>
</div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { defineComponent, nextTick, ref } from 'vue'
interface BaseNotificationButtonProp {
text: string
Expand Down Expand Up @@ -55,13 +57,18 @@ export default defineComponent({
},
},
emits: ['close'],
setup(props, context) {
setup(_, context) {
const showNotification = ref(false)
nextTick(() => (showNotification.value = true))
const onClick = (button: BaseNotificationButtonProp) => {
context.emit('close')
showNotification.value = false
if (button.onClick) button.onClick()
context.emit('close')
}
return {
showNotification,
onClick,
}
},
Expand All @@ -81,6 +88,7 @@ export default defineComponent({
flex-wrap: nowrap;
align-items: flex-end;
position: fixed;
pointer-events: none;
}
.notification {
Expand All @@ -102,6 +110,7 @@ export default defineComponent({
color: v-bind(textColor);
min-height: 50px;
min-width: 100px;
pointer-events: all;
}
.notification-buttons {
Expand All @@ -117,4 +126,14 @@ export default defineComponent({
background-color: rgba(255, 255, 255, 0.1);
}
}
.notification-enter-active,
.notification-leave-active {
transition: transform 1s ease;
}
.notification-enter-from,
.notification-leave-to {
transform: translateY(100px);
}
</style>
10 changes: 5 additions & 5 deletions src/sw.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { CacheableResponsePlugin } from 'workbox-cacheable-response'
import { clientsClaim } from 'workbox-core'
import { ExpirationPlugin } from 'workbox-expiration'
import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching'
import { NavigationRoute, registerRoute } from 'workbox-routing'
import { CacheFirst } from 'workbox-strategies'

declare let self: ServiceWorkerGlobalScope

self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') self.skipWaiting()
})

// self.__WB_MANIFEST is default injection point
precacheAndRoute(self.__WB_MANIFEST)

// clean old assets
cleanupOutdatedCaches()

// to allow work offline
registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html')), new CacheFirst())
registerRoute(new NavigationRoute(createHandlerBoundToURL('index.html')))
registerRoute(
({ request }) => request.destination === 'image',
new CacheFirst({
Expand Down Expand Up @@ -43,6 +46,3 @@ registerRoute(
],
})
)

self.skipWaiting()
clientsClaim()

0 comments on commit 9d5ff7e

Please sign in to comment.