From 619ff559e628e9f14a7f9c16bd23ca92c0661afc Mon Sep 17 00:00:00 2001 From: rene Date: Tue, 14 Apr 2026 17:26:02 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20SW=20Network-First=20f=C3=BCr=20Navigati?= =?UTF-8?q?on=20+=20versionierte=20CSS/JS-URLs=20(v=3D32)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - sw.js: index.html nie aus Cache (navigation → network-first) - index.html: ?v=32 an layout.css, components.css, api/ui/app.js - sw.js STATIC_ASSETS: versionierte URLs gecacht - app.js: Sidebar-Background per getComputedStyle statt CSS-Variable-String - SW by-v31 → by-v32 --- backend/static/index.html | 12 ++++++------ backend/static/js/app.js | 7 +++++-- backend/static/sw.js | 38 ++++++++++++++++++++++---------------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/backend/static/index.html b/backend/static/index.html index a26f266..a4b68b8 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -20,10 +20,10 @@ Ban Yaro - + - - + + @@ -215,9 +215,9 @@ - - - + + + diff --git a/backend/static/js/app.js b/backend/static/js/app.js index c5620fe..eab7d16 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -196,17 +196,20 @@ const App = (() => { const sidebar = document.getElementById('sidebar'); if (!sidebar) return; // Inline-Styles: unabhängig vom CSS-Cache-Stand + // Inline-Styles: unabhängig vom CSS-Cache; Farben als Fallback hardcoded + const bg = getComputedStyle(document.documentElement) + .getPropertyValue('--c-surface').trim() || '#ffffff'; sidebar.style.cssText = [ 'display:flex', 'position:fixed', 'top:0', 'left:0', 'bottom:0', 'width:240px', 'z-index:2000', - 'background:var(--c-surface,#fff)', + `background:${bg}`, 'flex-direction:column', 'overflow:hidden', 'box-shadow:4px 0 24px rgba(0,0,0,0.22)', - 'border-right:1px solid var(--c-border-light,#eee)', + 'border-right:1px solid #e5e7eb', ].join(';'); document.getElementById('sidebar-backdrop')?.classList.add('visible'); } diff --git a/backend/static/sw.js b/backend/static/sw.js index 6f6b7c6..faf7df6 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -3,18 +3,17 @@ Offline-Cache + Push Notifications ============================================================ */ -const CACHE_VERSION = 'by-v31'; +const CACHE_VERSION = 'by-v32'; const CACHE_STATIC = `${CACHE_VERSION}-static`; -// Diese Dateien werden beim Install gecacht (App Shell) +// index.html wird NICHT pre-gecacht (immer Network-First) const STATIC_ASSETS = [ - '/', '/css/design-system.css', - '/css/layout.css', - '/css/components.css', - '/js/api.js', - '/js/ui.js', - '/js/app.js', + '/css/layout.css?v=32', + '/css/components.css?v=32', + '/js/api.js?v=32', + '/js/ui.js?v=32', + '/js/app.js?v=32', '/manifest.json', '/icons/icon-192.png', ]; @@ -40,14 +39,11 @@ self.addEventListener('activate', event => { keys.filter(k => k !== CACHE_STATIC).map(k => caches.delete(k)) )) .then(() => self.clients.claim()) - // Alle offenen Fenster neu laden, damit neues CSS/JS aktiv wird - .then(() => self.clients.matchAll({ type: 'window' })) - .then(clients => clients.forEach(c => c.navigate(c.url))) ); }); // ---------------------------------------------------------- -// FETCH — Cache-First für statische Assets, Network-First für API +// FETCH — Network-First für HTML, Cache-First für Assets, Network für API // ---------------------------------------------------------- self.addEventListener('fetch', event => { const url = new URL(event.request.url); @@ -63,12 +59,25 @@ self.addEventListener('fetch', event => { return; } + // Navigation (index.html): immer Network-First + if (event.request.mode === 'navigate') { + event.respondWith( + fetch(event.request) + .then(response => { + const clone = response.clone(); + caches.open(CACHE_STATIC).then(c => c.put(event.request, clone)); + return response; + }) + .catch(() => caches.match('/')) + ); + return; + } + // Statische Assets: Cache-First event.respondWith( caches.match(event.request) .then(cached => cached || fetch(event.request) .then(response => { - // Erfolgreiche Responses für statische Assets cachen if (response.ok && event.request.method === 'GET') { const clone = response.clone(); caches.open(CACHE_STATIC).then(c => c.put(event.request, clone)); @@ -77,7 +86,6 @@ self.addEventListener('fetch', event => { }) ) .catch(() => { - // Offline-Fallback: App Shell zurückgeben if (event.request.mode === 'navigate') { return caches.match('/'); } @@ -139,7 +147,6 @@ self.addEventListener('notificationclick', event => { event.waitUntil( clients.matchAll({ type: 'window', includeUncontrolled: true }) .then(windowClients => { - // Offenes Fenster fokussieren for (const client of windowClients) { if (client.url.includes(self.location.origin)) { client.focus(); @@ -147,7 +154,6 @@ self.addEventListener('notificationclick', event => { return; } } - // Neues Fenster öffnen return clients.openWindow(url); }) );