mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
wip service worker
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
<html lang="{{ LANGUAGE_CODE }}">
|
<html lang="{{ LANGUAGE_CODE }}">
|
||||||
<head>
|
<head>
|
||||||
<title>Tandoor</title>
|
<title>Tandoor</title>
|
||||||
|
<meta name="description" content="{% trans 'Tandoor Recipe Manager' %}">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, minimal-ui, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5, minimal-ui, shrink-to-fit=no">
|
||||||
<meta name="robots" content="noindex,nofollow"/>
|
<meta name="robots" content="noindex,nofollow"/>
|
||||||
@@ -43,16 +44,16 @@
|
|||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
localStorage.setItem('BASE_PATH', "{% base_path request 'base' %}")
|
localStorage.setItem('BASE_PATH', "{% base_path request 'base' %}")
|
||||||
|
|
||||||
window.addEventListener("load", () => {
|
{#window.addEventListener("load", () => {#}
|
||||||
if ("serviceWorker" in navigator) {
|
{# if ("serviceWorker" in navigator) {#}
|
||||||
navigator.serviceWorker.register("{% url 'service_worker' %}", {scope: "{% base_path request 'base' %}" + '/'}).then(function (reg) {
|
{# navigator.serviceWorker.register("{% url 'service_worker' %}", {scope: "{% base_path request 'base' %}" + '/'}).then(function (reg) {#}
|
||||||
}).catch(function (err) {
|
{# }).catch(function (err) {#}
|
||||||
console.warn('Error whilst registering service worker', err);
|
{# console.warn('Error whilst registering service worker', err);#}
|
||||||
});
|
{# });#}
|
||||||
} else {
|
{# } else {#}
|
||||||
console.warn('service worker not in navigator');
|
{# console.warn('service worker not in navigator');#}
|
||||||
}
|
{# }#}
|
||||||
});
|
{#});#}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -523,6 +523,9 @@ def report_share_abuse(request, token):
|
|||||||
return HttpResponseRedirect(reverse('index'))
|
return HttpResponseRedirect(reverse('index'))
|
||||||
|
|
||||||
|
|
||||||
|
def service_worker(request):
|
||||||
|
return
|
||||||
|
|
||||||
def web_manifest(request):
|
def web_manifest(request):
|
||||||
theme_values = get_theming_values(request)
|
theme_values = get_theming_values(request)
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
"jsdom": "^26.1.0",
|
"jsdom": "^26.1.0",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
"vite": "6.2.6",
|
"vite": "6.2.6",
|
||||||
|
"vite-plugin-pwa": "^1.0.0",
|
||||||
"vite-plugin-vuetify": "^2.1.1",
|
"vite-plugin-vuetify": "^2.1.1",
|
||||||
"vue-tsc": "^2.2.8"
|
"vue-tsc": "^2.2.8"
|
||||||
}
|
}
|
||||||
|
|||||||
137
vue3/src/sw.ts
Normal file
137
vue3/src/sw.ts
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
// These JavaScript module imports need to be bundled:
|
||||||
|
import {precacheAndRoute, cleanupOutdatedCaches} from 'workbox-precaching';
|
||||||
|
import {registerRoute, setCatchHandler} from 'workbox-routing';
|
||||||
|
import {CacheFirst, NetworkFirst, NetworkOnly, StaleWhileRevalidate} from 'workbox-strategies';
|
||||||
|
import {ExpirationPlugin} from 'workbox-expiration';
|
||||||
|
import {BackgroundSyncPlugin, Queue} from "workbox-background-sync";
|
||||||
|
|
||||||
|
cleanupOutdatedCaches()
|
||||||
|
|
||||||
|
declare let self: ServiceWorkerGlobalScope
|
||||||
|
precacheAndRoute(self.__WB_MANIFEST)
|
||||||
|
|
||||||
|
const OFFLINE_CACHE_NAME = 'offline-html';
|
||||||
|
let script_name = typeof window !== 'undefined' ? localStorage.getItem('SCRIPT_NAME') : '/'
|
||||||
|
var OFFLINE_PAGE_URL = script_name + 'offline/';
|
||||||
|
|
||||||
|
self.addEventListener('install', async (event) => {
|
||||||
|
event.waitUntil(
|
||||||
|
caches.open(OFFLINE_CACHE_NAME).then((cache) => cache.add(new Request(OFFLINE_PAGE_URL, {cache: "reload"})))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// default handler if everything else fails
|
||||||
|
setCatchHandler(({event}) => {
|
||||||
|
switch (event.request.destination) {
|
||||||
|
case 'document':
|
||||||
|
console.log('Triggered fallback HTML')
|
||||||
|
return caches.open(OFFLINE_CACHE_NAME).then((cache) => cache.match(OFFLINE_PAGE_URL))
|
||||||
|
default:
|
||||||
|
console.log('Triggered response ERROR')
|
||||||
|
return Response.error();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
registerRoute(
|
||||||
|
({request}) => request.destination === 'image',
|
||||||
|
new CacheFirst({
|
||||||
|
cacheName: 'images',
|
||||||
|
plugins: [
|
||||||
|
new ExpirationPlugin({
|
||||||
|
maxEntries: 20,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
registerRoute(
|
||||||
|
({request}) => (request.destination === 'script' || request.destination === 'style'),
|
||||||
|
new NetworkFirst({
|
||||||
|
cacheName: 'assets'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
registerRoute(
|
||||||
|
new RegExp('jsreverse'),
|
||||||
|
new StaleWhileRevalidate({
|
||||||
|
cacheName: 'assets'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
registerRoute(
|
||||||
|
new RegExp('jsi18n'),
|
||||||
|
new StaleWhileRevalidate({
|
||||||
|
cacheName: 'assets'
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
registerRoute(
|
||||||
|
new RegExp('api/recipe/([0-9]+)'),
|
||||||
|
new NetworkFirst({
|
||||||
|
cacheName: 'api-recipe',
|
||||||
|
plugins: [
|
||||||
|
new ExpirationPlugin({
|
||||||
|
maxEntries: 50,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
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({
|
||||||
|
cacheName: 'api',
|
||||||
|
plugins: [
|
||||||
|
new ExpirationPlugin({
|
||||||
|
maxEntries: 50
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
registerRoute(
|
||||||
|
({request}) => request.destination === 'document',
|
||||||
|
new NetworkFirst({
|
||||||
|
cacheName: 'html',
|
||||||
|
plugins: [
|
||||||
|
new ExpirationPlugin({
|
||||||
|
maxAgeSeconds: 60 * 60 * 24 * 30,
|
||||||
|
maxEntries: 50,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
@@ -3,6 +3,7 @@ import {fileURLToPath, URL} from 'node:url'
|
|||||||
import {defineConfig} from 'vite'
|
import {defineConfig} from 'vite'
|
||||||
import vue from '@vitejs/plugin-vue'
|
import vue from '@vitejs/plugin-vue'
|
||||||
import vuetify, {transformAssetUrls} from 'vite-plugin-vuetify'
|
import vuetify, {transformAssetUrls} from 'vite-plugin-vuetify'
|
||||||
|
import {VitePWA} from "vite-plugin-pwa";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@@ -14,6 +15,16 @@ export default defineConfig({
|
|||||||
vuetify({
|
vuetify({
|
||||||
autoImport: true,
|
autoImport: true,
|
||||||
}),
|
}),
|
||||||
|
VitePWA({
|
||||||
|
registerType: 'autoUpdate',
|
||||||
|
strategies: 'injectManifest',
|
||||||
|
srcDir: 'src',
|
||||||
|
filename: 'sw.ts',
|
||||||
|
injectManifest: {
|
||||||
|
swDest: "../cookbook/templates/sw.js",
|
||||||
|
injectionPoint: undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
|||||||
2601
vue3/yarn.lock
2601
vue3/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user