baustelle-pwa/index.html
Eduard Wisch f2c41059a6
All checks were successful
Deploy baustelle-pwa / deploy (push) Successful in 1s
fix: Service Worker nach claude-db #31 Pattern (Network-First + Auto-Update)
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]
2026-04-09 01:17:57 +02:00

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>