All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
Problem: User sehen alte Version weil der SW Cache-First ausliefert und neue Versionen nur nach App-Neustart aktiv werden. Fix (Pattern aus PWA Best Practices in claude-db #31): - Network-First für alle eigenen Assets (fetch → ok → cache update, bei offline Fallback zum Cache). Vorher: Cache-First. - self.skipWaiting() direkt nach Install - self.clients.claim() nach Activate - updatefound-Listener im index.html → bei neuem SW SKIP_WAITING senden, dann controllerchange-Event löst einmaligen Reload aus - CSS/JS haben jetzt ?v=9 Query-String (Cache-Buster) - Cache-Version 'baustelle-v9' Damit zieht sich jede PWA beim nächsten Start automatisch die neueste Version ohne manuellen Reinstall. Das Share-Target-Manifest-Caching ist ein separates Android-Thema (dafür braucht's weiterhin Reinstall der PWA beim ersten Mal). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> [deploy]
70 lines
2.6 KiB
HTML
70 lines
2.6 KiB
HTML
<!doctype html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
|
<meta name="theme-color" content="#1a1a1f">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
<title>Baustelle</title>
|
|
<link rel="manifest" href="manifest.webmanifest">
|
|
<link rel="icon" type="image/svg+xml" href="icons/icon.svg">
|
|
<link rel="icon" type="image/png" sizes="192x192" href="icons/icon-192.png">
|
|
<link rel="icon" type="image/png" sizes="512x512" href="icons/icon-512.png">
|
|
<link rel="apple-touch-icon" href="icons/icon-192.png">
|
|
<link rel="stylesheet" href="app.css?v=9">
|
|
</head>
|
|
<body>
|
|
|
|
<div id="app">
|
|
<header id="topbar">
|
|
<button id="back-btn" class="icon-btn" style="display:none">←</button>
|
|
<h1 id="page-title">Baustelle</h1>
|
|
<button id="help-btn" class="icon-btn" title="Hilfe">❓</button>
|
|
<span id="status-badge">🟢</span>
|
|
</header>
|
|
|
|
<main id="main"></main>
|
|
|
|
<nav id="bottom-nav" style="display:none">
|
|
<button data-route="orders" class="active">📋 Aufträge</button>
|
|
<button data-route="reports">📑 Berichte</button>
|
|
<button data-route="settings">⚙️</button>
|
|
</nav>
|
|
</div>
|
|
|
|
<div id="toast-container"></div>
|
|
|
|
<script src="lib/idb.js?v=9"></script>
|
|
<script src="lib/api.js?v=9"></script>
|
|
<script src="lib/offline.js?v=9"></script>
|
|
<script src="lib/router.js?v=9"></script>
|
|
<script src="app.js?v=9"></script>
|
|
<script>
|
|
if ('serviceWorker' in navigator) {
|
|
window.addEventListener('load', () => {
|
|
navigator.serviceWorker.register('sw.js').then(reg => {
|
|
// Update-Check: wenn ein neuer SW wartet, sofort aktivieren
|
|
reg.addEventListener('updatefound', () => {
|
|
const nw = reg.installing;
|
|
if (!nw) return;
|
|
nw.addEventListener('statechange', () => {
|
|
if (nw.state === 'installed' && navigator.serviceWorker.controller) {
|
|
// Neue Version ist bereit — sofort übernehmen
|
|
nw.postMessage({ type: 'SKIP_WAITING' });
|
|
}
|
|
});
|
|
});
|
|
// Beim Controller-Change einmal neu laden (damit neuer SW aktive Clients kontrolliert)
|
|
let refreshed = false;
|
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
|
if (refreshed) return;
|
|
refreshed = true;
|
|
window.location.reload();
|
|
});
|
|
}).catch(e => console.warn('SW reg failed', e));
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|