added background sync to shopping list entry checking

This commit is contained in:
vabene1111 2023-02-12 12:56:29 +01:00
parent 39656152d3
commit cb363d6321
3 changed files with 71 additions and 6 deletions

View File

@ -43,7 +43,8 @@
"vue2-touch-events": "^3.2.2",
"vuedraggable": "^2.24.3",
"vuex": "^3.6.0",
"workbox-webpack-plugin": "^6.5.4"
"workbox-webpack-plugin": "^6.5.4",
"workbox-window": "^6.5.4"
},
"devDependencies": {
"@kazupon/vue-i18n-loader": "^0.5.0",
@ -62,6 +63,7 @@
"typescript": "~4.9.3",
"vue-cli-plugin-i18n": "^2.3.1",
"webpack-bundle-tracker": "1.8.0",
"workbox-background-sync": "^6.5.4",
"workbox-expiration": "^6.5.4",
"workbox-navigation-preload": "^6.5.4",
"workbox-precaching": "^6.5.4",

View File

@ -1,6 +1,7 @@
<template>
<div id="app" style="margin-bottom: 4vh">
<b-alert :show="!online" dismissible class="small float-up" variant="warning">{{ $t("OfflineAlert") }}</b-alert>
<b-button @click="replaySyncQueue">SYNC</b-button>
<div class="row float-top w-100">
<div class="col-auto no-gutter ml-auto">
<b-button variant="link" class="px-1 pt-0 pb-1 d-none d-md-inline-block">
@ -615,6 +616,7 @@ import ShoppingSettingsComponent from "@/components/Settings/ShoppingSettingsCom
Vue.use(BootstrapVue)
Vue.use(VueCookies)
let SETTINGS_COOKIE_NAME = "shopping_settings"
import {Workbox} from 'workbox-window';
export default {
name: "ShoppingListView",
@ -903,9 +905,30 @@ export default {
}
})
this.$i18n.locale = window.CUSTOM_LOCALE
console.log(window.CUSTOM_LOCALE)
},
methods: {
/**
* failed requests to sync entry check events are automatically re-queued by the service worker for sync
* this command allows to manually force replaying those events before re-enabling automatic sync
*/
replaySyncQueue: function () {
const wb = new Workbox('/service-worker.js');
wb.register();
wb.messageSW({type: 'BGSYNC_REPLAY_REQUESTS'}).then((r) => {
console.log('Background sync queue replayed!', r);
})
},
/**
* get the number of entries left in the sync queue for entry check events
* @returns {Promise<Number>} promise resolving to the number of entries left
*/
getSyncQueueLength: function (){
const wb = new Workbox('/service-worker.js');
wb.register();
return wb.messageSW({type: 'BGSYNC_COUNT_QUEUE'}).then((r) => {
return r
})
},
setFocus() {
if (this.ui.entry_mode_simple) {
this.$refs['amount_input_simple'].focus()
@ -1043,8 +1066,7 @@ export default {
} else {
this.loading = true
}
this.genericAPI(this.Models.SHOPPING_LIST, this.Actions.LIST, params)
.then((results) => {
this.genericAPI(this.Models.SHOPPING_LIST, this.Actions.LIST, params).then((results) => {
if (!autosync) {
if (results.data?.length) {
this.items = results.data
@ -1054,7 +1076,14 @@ export default {
this.loading = false
} else {
if (!this.auto_sync_blocked) {
this.mergeShoppingList(results.data)
this.getSyncQueueLength().then((r) => {
if (r === 0){
this.mergeShoppingList(results.data)
} else {
this.auto_sync_running = false
this.replaySyncQueue()
}
})
}
}
})

View File

@ -1,8 +1,9 @@
// These JavaScript module imports need to be bundled:
import {precacheAndRoute} from 'workbox-precaching';
import {registerRoute, setCatchHandler} from 'workbox-routing';
import {CacheFirst, NetworkFirst, StaleWhileRevalidate} from 'workbox-strategies';
import {CacheFirst, NetworkFirst, NetworkOnly, StaleWhileRevalidate} from 'workbox-strategies';
import {ExpirationPlugin} from 'workbox-expiration';
import {BackgroundSyncPlugin, Queue} from "workbox-background-sync";
const OFFLINE_CACHE_NAME = 'offline-html';
@ -77,6 +78,39 @@ registerRoute(
})
)
const queue = new Queue('shopping-sync-queue', {
maxRetentionTime: 7 * 24 * 60,
});
registerRoute(
new RegExp('api/shopping-list-entry/([0-9]+)'),
new NetworkOnly({
plugins: [
{
fetchDidFail: async ({request}) => {
await queue.pushRequest({request});
},
}
],
}),
'PATCH'
)
addEventListener('message', (event) => {
if (event.data.type === 'BGSYNC_REPLAY_REQUESTS') {
queue.replayRequests().then((r) => {
event.ports[0].postMessage('REPLAY_SUCCESS SW');
}).catch((err) => {
event.ports[0].postMessage('REPLAY_FAILURE');
});
}
if (event.data.type === 'BGSYNC_COUNT_QUEUE') {
queue.getAll().then((r) => {
event.ports[0].postMessage(r.length);
})
}
});
registerRoute(
new RegExp('api/*'),
new NetworkFirst({