frontend: Update-Detection überarbeitet - nur anzeigen wenn User aktiv ist
- 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
a9d2cf3054
commit
cad7a8bb6d
+51
-38
@@ -1195,9 +1195,7 @@ mountBuildBadge();
|
|||||||
|
|
||||||
/* ---------- Service Worker für Update-Detection ---------- */
|
/* ---------- Service Worker für Update-Detection ---------- */
|
||||||
if('serviceWorker' in navigator){
|
if('serviceWorker' in navigator){
|
||||||
/* Service Worker als Blob registrieren (Single-File-App) */
|
|
||||||
const swCode = `
|
const swCode = `
|
||||||
const CACHE_NAME = 'werkbaum-v1';
|
|
||||||
self.addEventListener('install', (e) => self.skipWaiting());
|
self.addEventListener('install', (e) => self.skipWaiting());
|
||||||
self.addEventListener('activate', (e) => e.waitUntil(clients.claim()));
|
self.addEventListener('activate', (e) => e.waitUntil(clients.claim()));
|
||||||
|
|
||||||
@@ -1216,9 +1214,7 @@ if('serviceWorker' in navigator){
|
|||||||
});
|
});
|
||||||
|
|
||||||
function notifyClients(msg) {
|
function notifyClients(msg) {
|
||||||
self.clients.matchAll().then(clients =>
|
self.clients.matchAll().then(clients => clients.forEach(c => c.postMessage(msg)));
|
||||||
clients.forEach(c => c.postMessage(msg))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getStored() {
|
async function getStored() {
|
||||||
@@ -1263,37 +1259,44 @@ if('serviceWorker' in navigator){
|
|||||||
const swUrl = URL.createObjectURL(blob);
|
const swUrl = URL.createObjectURL(blob);
|
||||||
|
|
||||||
navigator.serviceWorker.register(swUrl).then((registration) => {
|
navigator.serviceWorker.register(swUrl).then((registration) => {
|
||||||
/* Periodisch auf Updates prüfen */
|
/* Starte erste Prüfung nach 2 Sekunden */
|
||||||
setInterval(() => {
|
|
||||||
if(registration.active){
|
|
||||||
registration.active.postMessage({ type: 'CHECK_UPDATE' });
|
|
||||||
}
|
|
||||||
}, 60000); /* Jede Minute */
|
|
||||||
|
|
||||||
/* Starte erste Prüfung nach 5 Sekunden */
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if(registration.active){
|
if(registration.active) registration.active.postMessage({ type: 'CHECK_UPDATE' });
|
||||||
registration.active.postMessage({ type: 'CHECK_UPDATE' });
|
}, 2000);
|
||||||
}
|
|
||||||
}, 5000);
|
/* Periodisch auf Updates prüfen (jede 5 Minuten) */
|
||||||
|
setInterval(() => {
|
||||||
|
if(registration.active) registration.active.postMessage({ type: 'CHECK_UPDATE' });
|
||||||
|
}, 300000);
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
console.error('Service Worker Registration fehlgeschlagen:', error);
|
console.error('Service Worker Registration fehlgeschlagen:', error);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Höre auf Update-Benachrichtigungen vom Service Worker */
|
/* Höre auf Update-Benachrichtigungen vom Service Worker */
|
||||||
navigator.serviceWorker.addEventListener('message', (event) => {
|
navigator.serviceWorker.addEventListener('message', (event) => {
|
||||||
if(event.data && event.data.type === 'UPDATE_AVAILABLE'){
|
if(event.data?.type === 'UPDATE_AVAILABLE'){
|
||||||
showUpdateNotification();
|
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(){
|
function checkAndShowUpdateNotification(){
|
||||||
/* Entferne alte Benachrichtigung, falls vorhanden */
|
|
||||||
const existingNotif = document.getElementById('updateNotification');
|
const existingNotif = document.getElementById('updateNotification');
|
||||||
if(existingNotif) existingNotif.remove();
|
if(existingNotif) return; /* Schon angezeigt */
|
||||||
|
|
||||||
/* Erstelle Benachrichtigungselement */
|
|
||||||
const notif = document.createElement('div');
|
const notif = document.createElement('div');
|
||||||
notif.id = 'updateNotification';
|
notif.id = 'updateNotification';
|
||||||
notif.style.cssText = `
|
notif.style.cssText = `
|
||||||
@@ -1315,26 +1318,36 @@ function showUpdateNotification(){
|
|||||||
|
|
||||||
notif.innerHTML = `
|
notif.innerHTML = `
|
||||||
<span>📦 Neue Version verfügbar</span>
|
<span>📦 Neue Version verfügbar</span>
|
||||||
<button id="updateBtn" style="
|
<div style="display: flex; gap: 8px;">
|
||||||
background: white;
|
<button class="dismissBtn" style="
|
||||||
color: var(--or, #0F766E);
|
background: transparent;
|
||||||
border: none;
|
color: white;
|
||||||
padding: 6px 12px;
|
border: 1px solid white;
|
||||||
border-radius: 4px;
|
padding: 4px 8px;
|
||||||
cursor: pointer;
|
border-radius: 4px;
|
||||||
font-weight: 500;
|
cursor: pointer;
|
||||||
font-size: 13px;
|
font-size: 12px;
|
||||||
">Jetzt laden</button>
|
">Später</button>
|
||||||
|
<button class="updateBtn" style="
|
||||||
|
background: white;
|
||||||
|
color: var(--or, #0F766E);
|
||||||
|
border: none;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 12px;
|
||||||
|
">Jetzt laden</button>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
document.body.insertBefore(notif, document.body.firstChild);
|
document.body.insertBefore(notif, document.body.firstChild);
|
||||||
|
|
||||||
document.getElementById('updateBtn').addEventListener('click', () => {
|
notif.querySelector('.updateBtn').addEventListener('click', () => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Auto-dismiss nach 30 Sekunden wenn nicht geklickt */
|
notif.querySelector('.dismissBtn').addEventListener('click', () => {
|
||||||
setTimeout(() => {
|
notif.remove();
|
||||||
if(notif.parentNode) notif.remove();
|
});
|
||||||
}, 30000);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user