M4: PWA + Mobile-UX – Manifest/Service-Worker + Icons, Auf/Ab-Reorder, FAB, Touch-Targets + Safe-Area, Nav-Entdupidung, Heute-Highlight, Aktions-Trennung (Abhaken vs. Bearbeiten/Löschen), OIDC-Fixes + PWA-Tests
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "Essensplanung",
|
||||
"short_name": "Essen",
|
||||
"description": "Familien-Essensplanung: Planungsliste, Tagesansicht, Inspiration.",
|
||||
"lang": "de",
|
||||
"start_url": "/",
|
||||
"scope": "/",
|
||||
"display": "standalone",
|
||||
"orientation": "portrait",
|
||||
"background_color": "#f4eee1",
|
||||
"theme_color": "#3f6d4e",
|
||||
"icons": [
|
||||
{ "src": "/icons/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" },
|
||||
{ "src": "/icons/icon-512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" },
|
||||
{ "src": "/icons/maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/* Service Worker: App-Shell cachen (Offline + schneller Start).
|
||||
Version bei jeder Template-/Asset-Änderung bumpen (SHELL_VERSION),
|
||||
damit alte Caches beim Activate bereinigt werden. */
|
||||
const SHELL_VERSION = 'v1';
|
||||
const SHELL_CACHE = 'essen-shell-' + SHELL_VERSION;
|
||||
const SHELL = [
|
||||
'/',
|
||||
'/manifest.webmanifest',
|
||||
'/js/htmx.min.js',
|
||||
'/js/sortable.min.js',
|
||||
'/icons/icon-192.png',
|
||||
'/icons/icon-512.png',
|
||||
];
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
event.waitUntil(
|
||||
caches
|
||||
.open(SHELL_CACHE)
|
||||
.then((cache) => cache.addAll(SHELL))
|
||||
.then(() => self.skipWaiting())
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(
|
||||
caches
|
||||
.keys()
|
||||
.then((keys) =>
|
||||
Promise.all(
|
||||
keys
|
||||
.filter((key) => key.startsWith('essen-shell-') && key !== SHELL_CACHE)
|
||||
.map((key) => caches.delete(key))
|
||||
)
|
||||
)
|
||||
.then(() => self.clients.claim())
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
const url = new URL(event.request.url);
|
||||
if (event.request.method !== 'GET' || url.origin !== self.location.origin) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Navigations: erst Netzwerk (frische Deploys!), dann Cache (Offline).
|
||||
if (event.request.mode === 'navigate') {
|
||||
event.respondWith(
|
||||
fetch(event.request)
|
||||
.then((response) => {
|
||||
const kopie = response.clone();
|
||||
caches.open(SHELL_CACHE).then((cache) => cache.put(event.request, kopie));
|
||||
return response;
|
||||
})
|
||||
.catch(() =>
|
||||
caches.match(event.request).then((treffer) => treffer || caches.match('/'))
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Statische Assets: Cache-first (unveränderlich pro Version).
|
||||
if (
|
||||
url.pathname.startsWith('/js/') ||
|
||||
url.pathname.startsWith('/icons/') ||
|
||||
url.pathname === '/manifest.webmanifest'
|
||||
) {
|
||||
event.respondWith(
|
||||
caches.match(event.request).then(
|
||||
(treffer) =>
|
||||
treffer ||
|
||||
fetch(event.request).then((response) => {
|
||||
const kopie = response.clone();
|
||||
caches.open(SHELL_CACHE).then((cache) => cache.put(event.request, kopie));
|
||||
return response;
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user