diff --git a/VERSION b/VERSION
index 2b7e609..fb9a769 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1232
\ No newline at end of file
+1233
\ No newline at end of file
diff --git a/backend/static/index.html b/backend/static/index.html
index f047c3f..3b4a4bc 100644
--- a/backend/static/index.html
+++ b/backend/static/index.html
@@ -86,14 +86,14 @@
Ban Yaro
-
+
-
-
-
-
-
+
+
+
+
+
@@ -612,11 +612,11 @@
-
-
-
-
-
+
+
+
+
+
@@ -626,7 +626,7 @@
-
+
diff --git a/backend/static/js/app.js b/backend/static/js/app.js
index 8991e1d..513603f 100644
--- a/backend/static/js/app.js
+++ b/backend/static/js/app.js
@@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
-const APP_VER = '1232'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
+const APP_VER = '1233'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.6.0'; // ← semantische Version, wird bei make release gesetzt
window.APP_VER = APP_VER; // global verfügbar für andere Module (z.B. offline-indicator)
window.APP_VERSION = APP_VERSION;
diff --git a/backend/static/landing.html b/backend/static/landing.html
index 86f1ed8..31aadcf 100644
--- a/backend/static/landing.html
+++ b/backend/static/landing.html
@@ -4,7 +4,7 @@
-
+
Ban Yaro — Die Hunde-App für Deutschland, Österreich & Schweiz
diff --git a/backend/static/sw.js b/backend/static/sw.js
index 9fc4eac..e514ca9 100644
--- a/backend/static/sw.js
+++ b/backend/static/sw.js
@@ -4,7 +4,7 @@
============================================================ */
// ← EINZIGE Stelle für die Version — STATIC_ASSETS und CACHE_VERSION leiten sich ab
-const VER = '1232';
+const VER = '1233';
const CACHE_VERSION = `by-v${VER}`;
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
@@ -23,6 +23,15 @@ const PRIORITY_PAGES = [
'/js/pages/routes.js',
'/js/pages/poison.js',
'/js/pages/lost.js',
+ // GL-Karten-Stack: ohne diese Dateien ist die Karte offline TOT, obwohl
+ // Kacheln/Marker in IndexedDB liegen (Gerätetest 2026-06-08).
+ '/js/vendor/maplibre-gl.js',
+ '/js/vendor/maplibre-gl.css',
+ '/js/vendor/pmtiles.js',
+ '/js/map-gl-style.js',
+ '/js/map-offline.js',
+ '/js/map-gl-markers.js',
+ '/js/map-gl-mini.js',
];
// index.html wird NICHT pre-gecacht (immer Network-First)
@@ -236,9 +245,36 @@ self.addEventListener('install', event => {
// ----------------------------------------------------------
// ACTIVATE — alte Caches aufräumen (CACHE_TILES + CACHE_API behalten)
// ----------------------------------------------------------
+// Carry-Over VOR dem Löschen: Einträge der alten Static-Caches in den neuen übernehmen,
+// die dort noch fehlen. Sonst reißt ein Versions-Update ein Offline-Loch — alte Caches
+// weg, neuer erst teilweise befüllt (Hintergrund-Precache) → Karte offline tot, obwohl
+// die Pfote „ready" zeigt (Gerätetest 2026-06-08). Network-First ersetzt die übernommenen
+// Einträge online sukzessive durch frische.
+async function _migrateStaticCaches() {
+ const names = (await caches.keys()).filter(k => /^by-v\d+-static$/.test(k) && k !== CACHE_STATIC);
+ if (!names.length) return;
+ const fresh = await caches.open(CACHE_STATIC);
+ const have = new Set((await fresh.keys()).map(r => r.url.split('?')[0]));
+ for (const name of names) {
+ const oldCache = await caches.open(name);
+ for (const req of await oldCache.keys()) {
+ const bare = req.url.split('?')[0];
+ if (have.has(bare)) continue; // neue Version schon vorhanden
+ const resp = await oldCache.match(req);
+ if (resp) {
+ // Unter NACKTEM Key (ohne ?v=) ablegen: der Online-Refresh (PRIORITY_PAGES /
+ // Network-First) überschreibt genau diesen Key — keine Versions-Duplikate.
+ try { await fresh.put(bare, resp); have.add(bare); } catch (e) {}
+ }
+ }
+ }
+}
+
self.addEventListener('activate', event => {
event.waitUntil(
- caches.keys()
+ _migrateStaticCaches()
+ .catch(() => {})
+ .then(() => caches.keys())
.then(keys => Promise.all(
keys
.filter(k => k !== CACHE_STATIC && k !== CACHE_TILES && k !== CACHE_API)
@@ -411,23 +447,28 @@ self.addEventListener('fetch', event => {
return;
}
- // Statische Assets: Cache-First
- event.respondWith(
- caches.match(event.request)
- .then(cached => cached || fetch(event.request)
- .then(response => {
- if (response.ok && event.request.method === 'GET') {
- const clone = response.clone();
- caches.open(CACHE_STATIC).then(c => c.put(event.request, clone));
- }
- return response;
- })
- )
- .catch(() => {
- if (event.request.mode === 'navigate') return caches.match('/');
- return new Response('', { status: 503 });
- })
- );
+ // Statische Assets: Cache-First. Für eigene /js/ + /css/ zusätzlich ignoreSearch-
+ // Fallback — Lazy-Loads hängen ?v=APP_VER an, Carry-Over-Einträge tragen aber den
+ // alten ?v= bzw. gar keinen (PRIORITY_PAGES). Online ersetzt der Fetch sie frisch.
+ event.respondWith((async () => {
+ let cached = await caches.match(event.request);
+ if (!cached && url.origin === self.location.origin &&
+ (url.pathname.startsWith('/js/') || url.pathname.startsWith('/css/'))) {
+ cached = await caches.match(event.request, { ignoreSearch: true });
+ }
+ if (cached) return cached;
+ try {
+ const response = await fetch(event.request);
+ if (response.ok && event.request.method === 'GET') {
+ const clone = response.clone();
+ caches.open(CACHE_STATIC).then(c => c.put(event.request, clone)).catch(() => {});
+ }
+ return response;
+ } catch (e) {
+ if (event.request.mode === 'navigate') return caches.match('/');
+ return new Response('', { status: 503 });
+ }
+ })());
});
// ----------------------------------------------------------