From cad7a8bb6d1986f69d093087908441dfe7da09f8 Mon Sep 17 00:00:00 2001 From: mhoennig Date: Thu, 23 Jul 2026 06:48:16 +0200 Subject: [PATCH] =?UTF-8?q?frontend:=20Update-Detection=20=C3=BCberarbeite?= =?UTF-8?q?t=20-=20nur=20anzeigen=20wenn=20User=20aktiv=20ist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Service Worker prüft im Hintergrund auf neue Versionen (jede 5 Minuten) - Update-Status wird in localStorage gespeichert - Benachrichtigung erscheint nur wenn: * User zur App zurückkommt (Page Visibility API) * Oder beim initialen Laden wenn Update verfügbar - "Später" Button zum Dismissieren, "Jetzt laden" für Reload - Keine Browser-Permission nötig - localStorage-Daten bleiben beim Reload erhalten - Pragmatisch: User sieht Updates nur wenn er arbeitet Co-Authored-By: Claude Haiku 4.5 --- frontend/src/app.js | 89 ++++++++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 38 deletions(-) diff --git a/frontend/src/app.js b/frontend/src/app.js index eedd8da..3b2c062 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -1195,9 +1195,7 @@ mountBuildBadge(); /* ---------- Service Worker für Update-Detection ---------- */ if('serviceWorker' in navigator){ - /* Service Worker als Blob registrieren (Single-File-App) */ const swCode = ` - const CACHE_NAME = 'werkbaum-v1'; self.addEventListener('install', (e) => self.skipWaiting()); self.addEventListener('activate', (e) => e.waitUntil(clients.claim())); @@ -1216,9 +1214,7 @@ if('serviceWorker' in navigator){ }); function notifyClients(msg) { - self.clients.matchAll().then(clients => - clients.forEach(c => c.postMessage(msg)) - ); + self.clients.matchAll().then(clients => clients.forEach(c => c.postMessage(msg))); } async function getStored() { @@ -1263,37 +1259,44 @@ if('serviceWorker' in navigator){ const swUrl = URL.createObjectURL(blob); navigator.serviceWorker.register(swUrl).then((registration) => { - /* Periodisch auf Updates prüfen */ - setInterval(() => { - if(registration.active){ - registration.active.postMessage({ type: 'CHECK_UPDATE' }); - } - }, 60000); /* Jede Minute */ - - /* Starte erste Prüfung nach 5 Sekunden */ + /* Starte erste Prüfung nach 2 Sekunden */ setTimeout(() => { - if(registration.active){ - registration.active.postMessage({ type: 'CHECK_UPDATE' }); - } - }, 5000); + if(registration.active) registration.active.postMessage({ type: 'CHECK_UPDATE' }); + }, 2000); + + /* Periodisch auf Updates prüfen (jede 5 Minuten) */ + setInterval(() => { + if(registration.active) registration.active.postMessage({ type: 'CHECK_UPDATE' }); + }, 300000); }).catch((error) => { console.error('Service Worker Registration fehlgeschlagen:', error); }); /* Höre auf Update-Benachrichtigungen vom Service Worker */ navigator.serviceWorker.addEventListener('message', (event) => { - if(event.data && event.data.type === 'UPDATE_AVAILABLE'){ - showUpdateNotification(); + if(event.data?.type === 'UPDATE_AVAILABLE'){ + localStorage.setItem('werkbaum-update-available', 'true'); + checkAndShowUpdateNotification(); } }); + + /* Prüfe auf Update wenn User zur App zurückkommt */ + document.addEventListener('visibilitychange', () => { + if(!document.hidden && localStorage.getItem('werkbaum-update-available')){ + checkAndShowUpdateNotification(); + } + }); + + /* Prüfe beim Laden */ + if(!document.hidden && localStorage.getItem('werkbaum-update-available')){ + checkAndShowUpdateNotification(); + } } -function showUpdateNotification(){ - /* Entferne alte Benachrichtigung, falls vorhanden */ +function checkAndShowUpdateNotification(){ const existingNotif = document.getElementById('updateNotification'); - if(existingNotif) existingNotif.remove(); + if(existingNotif) return; /* Schon angezeigt */ - /* Erstelle Benachrichtigungselement */ const notif = document.createElement('div'); notif.id = 'updateNotification'; notif.style.cssText = ` @@ -1315,26 +1318,36 @@ function showUpdateNotification(){ notif.innerHTML = ` 📦 Neue Version verfügbar - +
+ + +
`; document.body.insertBefore(notif, document.body.firstChild); - document.getElementById('updateBtn').addEventListener('click', () => { + notif.querySelector('.updateBtn').addEventListener('click', () => { window.location.reload(); }); - /* Auto-dismiss nach 30 Sekunden wenn nicht geklickt */ - setTimeout(() => { - if(notif.parentNode) notif.remove(); - }, 30000); + notif.querySelector('.dismissBtn').addEventListener('click', () => { + notif.remove(); + }); }