diff --git a/VERSION b/VERSION index 8118744..125a103 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1235 \ No newline at end of file +1236 \ No newline at end of file diff --git a/backend/static/index.html b/backend/static/index.html index cab567b..b4cd336 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 04a0e05..512e11d 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 = '1235'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '1236'; // ← 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/js/map-offline.js b/backend/static/js/map-offline.js index 4324bda..d743721 100644 --- a/backend/static/js/map-offline.js +++ b/backend/static/js/map-offline.js @@ -598,13 +598,21 @@ window.MapOffline = (function () { if (opts.onProgress) opts.onProgress({ bytes: state.bytes, done: state.done, total: total }); }).then(function () { return chunkLoop(idx + 64); }); } + // Vereinfachten Track (≤60 Punkte) in der Region-Meta ablegen: damit kann clear() + // die Korridor-Keep-Keys SELBST aus IndexedDB bauen — ohne API/Login/GPS + // (Gerätetest René 2026-06-08: leeres Keep-Set = Komplett-Wipe trotz Routen). + var step = Math.max(1, Math.ceil(track.length / 60)); + var slim = track.filter(function (p, i) { return i % step === 0; }); + if (slim[slim.length - 1] !== track[track.length - 1]) slim.push(track[track.length - 1]); + slim = slim.map(function (p) { return { lat: p.lat, lon: p.lon }; }); + return chunkLoop(0) .then(function () { return _cacheGlyphs(); }) .then(function (gb) { state.bytes += gb; return _cachePois(bb); }) .then(function (pc) { poiCount = pc; return _addRegion({ type: 'korridor', name: opts.name || null, lat: track[0].lat, lon: track[0].lon, - tiles: state.stored, bytes: state.bytes, pois: poiCount, savedAt: Date.now() }); + track: slim, tiles: state.stored, bytes: state.bytes, pois: poiCount, savedAt: Date.now() }); }) .then(function () { return _bumpTotal(state.bytes); }) .then(function () { return { tiles: state.stored, bytes: state.bytes, pois: poiCount, capped: state.bytes >= cap }; }); @@ -797,8 +805,18 @@ window.MapOffline = (function () { var keptRegions = regions.filter(function (r) { return r.type === 'standort' || r.type === 'korridor'; }); regions.forEach(function (r) { if (r.type === 'standort' && r.radiusKm) _keepRegionKeys(r.lat, r.lon, r.radiusKm, keep); + // Korridor-Keep direkt aus der Region-Meta (r.track) — unabhängig von API/Login. + if (r.type === 'korridor' && r.track && r.track.length >= 2) _keepCorridorKeys(r.track, 1, keep); }); - if (opts.center) _keepRegionKeys(opts.center.lat, opts.center.lon, 5, keep); + if (opts.center) { + _keepRegionKeys(opts.center.lat, opts.center.lon, 5, keep); + // Standort-ADOPTION: Bestandsdaten haben evtl. keine standort-Region (Gebiet wurde + // vor Runde 6 geladen) — Eintrag synthetisch anlegen, damit Folge-Läufe ihn kennen. + if (!keptRegions.some(function (r) { return r.type === 'standort'; })) { + keptRegions.push({ type: 'standort', lat: opts.center.lat, lon: opts.center.lon, + radiusKm: 5, tiles: 0, bytes: 0, pois: 0, savedAt: Date.now() }); + } + } (opts.keepTracks || []).forEach(function (t) { if (t && t.length >= 2) _keepCorridorKeys(t, 1, keep); }); diff --git a/backend/static/js/pages/map.js b/backend/static/js/pages/map.js index dc25e0d..9adc8e0 100644 --- a/backend/static/js/pages/map.js +++ b/backend/static/js/pages/map.js @@ -2310,15 +2310,21 @@ window.Page_map = (() => { } // SELEKTIV löschen (René 2026-06-08, spart Vorladezeit): Standort-Gebiet + Korridore // der gespeicherten Routen bleiben einfach stehen statt löschen-und-neu-laden. + // (Korridor-Keep kommt primär aus der Region-Meta; API-Tracks sind Ergänzung.) let keepTracks = []; try { keepTracks = ((await API.routes.list()) || []) .map(r => r.preview_track).filter(t => (t || []).length >= 2); } catch (e) {} - await MapOffline.clear({ - center: _userPos ? { lat: _userPos.lat, lon: _userPos.lon } : null, - keepTracks, - }).catch(() => {}); + // Position: GPS-Fix, sonst letzte bekannte Position (wetter.js et al.) + let center = _userPos ? { lat: _userPos.lat, lon: _userPos.lon } : null; + if (!center) { + try { + const p = JSON.parse(localStorage.getItem('by_last_position') || 'null'); + if (p?.lat != null) center = { lat: p.lat, lon: p.lon }; + } catch (e) {} + } + await MapOffline.clear({ center, keepTracks }).catch(() => {}); _setCoverage(false); UI.modal.close(); UI.toast.success('Offline-Karten gelöscht — Standort-Gebiet und Routen-Korridore bleiben erhalten.'); diff --git a/backend/static/landing.html b/backend/static/landing.html index dbf53df..7e2b317 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 c9ef6c8..b9d41dc 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 = '1235'; +const VER = '1236'; const CACHE_VERSION = `by-v${VER}`; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten diff --git a/tests/js/test-map-offline-r7.js b/tests/js/test-map-offline-r7.js index 20d64a6..75c4ee1 100644 --- a/tests/js/test-map-offline-r7.js +++ b/tests/js/test-map-offline-r7.js @@ -54,11 +54,19 @@ const MO = global.window.MapOffline; const regs = stores.meta.get('regions') || []; if (!regs.length || regs.some(r => r.type === 'gebiet')) throw new Error('Regions-Meta falsch gefiltert'); - // 2. Komplett-Wipe ohne Keep-Kandidaten: alles weg (auch p/ + f/), Zonen bleiben + // 2. clear() OHNE keepTracks: Korridor-Keep kommt aus der Region-Meta (r.track) + const afterSel = stores.tiles.size; + await MO.clear(); + console.log('clear ohne Optionen: tiles', afterSel, '→', stores.tiles.size, '(Korridor aus Meta gehalten)'); + if (stores.tiles.size === 0) throw new Error('Korridor-Keep aus Region-Meta fehlt'); + const gj2 = await MO.coverage(); + if (!gj2.features.length) throw new Error('Korridor-Coverage leer'); + + // 3. Komplett-Wipe: Regionen-Meta manuell leeren → kein Keep-Kandidat → alles weg await MO.markDeadZone(48.2, 12.1); + stores.meta.delete('regions'); await MO.clear(); console.log('Komplett-Wipe: tiles =', stores.tiles.size, '— Zonen:', (stores.meta.get('deadzones') || []).length); - // Korridor-Region hat keinen Track in der Meta → kein Keep-Set → echter Wipe if (stores.tiles.size !== 0) throw new Error('Komplett-Wipe unvollständig'); if ((stores.meta.get('deadzones') || []).length !== 1) throw new Error('Zonen weg');