Offline-Karten Runde 3: Puls-Icon, rollendes Vorausladen, Ausschnitt-Download, Speicher-Cap

- Offline-Indikator: pulsierendes 32px-Icon oben rechts (unter Kopfzeilen-Hoehe)
  statt Leiste ueber die volle Breite — verdeckte '<- Zurueck' in der
  Routennavigation (Geraetetest Rene)
- Rollendes Vorausladen: setGps laedt alle ~400m still fehlende z14+-2-Kacheln
  um die Position — deckt den Weg schon beim ERSTEN Funkloch-Besuch ab
- Bereichsauswahl light: 'Sichtbaren Ausschnitt speichern' im Offline-Modal
  (downloadBbox, Cap 40 MB, Zu-gross-Schutz)
- Speicher-Cap 250 MB als Soft-Guard fuer automatische Pfade + totalBytes-Zaehler
  + navigator.storage.persist() best-effort; echte LRU vertagt (Refcounting noetig)
- Auto-OSM-Raster-Prefetch entfernt (manueller Leaflet-Pfad bleibt)
- Logik-Tests (Node-Stubs) fuer Bbox/Cap/Throttle/persist bestanden
Bump v1229
This commit is contained in:
rene 2026-06-06 12:34:48 +02:00
parent 3426d2b7c8
commit 763108fa7c
10 changed files with 214 additions and 40 deletions

View file

@ -2190,6 +2190,34 @@ window.Page_map = (() => {
}
}
// Bereichsauswahl: den SICHTBAREN Karten-Ausschnitt komplett speichern (z.B. fürs
// Urlaubsziel: hinzoomen/-schieben, speichern). Cap 40 MB, Zu-groß-Schutz in MapOffline.
async function _downloadViewport() {
if (!_map || !window.MapOffline) return;
const btn = document.getElementById('map-offline-btn');
if (btn?.classList.contains('loading')) return;
const p = _mapPaddedBounds(0.02);
btn?.classList.add('loading');
_setOsmStatus('Offline: 0 MB…');
try {
const res = await MapOffline.downloadBbox(
{ south: p.south, west: p.west, north: p.north, east: p.east },
{ capMB: 40, onProgress: pr => {
_setOsmStatus(`Offline: ${(pr.bytes / 1048576).toFixed(1)} MB (${Math.round(pr.done / pr.total * 100)} %)…`);
} });
_setOsmStatus('');
UI.toast.success(`Ausschnitt offline gespeichert — ${res.pois || 0} Marker, ${(res.bytes / 1048576).toFixed(1)} MB.`
+ `${res.capped ? ' (40-MB-Limit erreicht)' : ''}`);
window.OfflineIndicator?.refresh();
if (_covOn) _setCoverage(true);
} catch (e) {
_setOsmStatus('');
UI.toast.error(e?.message?.includes('zu groß') ? e.message : 'Offline-Download fehlgeschlagen — bitte erneut versuchen.');
} finally {
btn?.classList.remove('loading');
}
}
// ----------------------------------------------------------
// Offline-Bereiche-Layer (gespeicherte z14-Kacheln) + Verwaltungs-Modal
// ----------------------------------------------------------
@ -2226,7 +2254,7 @@ window.Page_map = (() => {
let s = { regions: [] };
try { s = await MapOffline.stats(); } catch (e) {}
const regions = s.regions || [];
const totalBytes = regions.reduce((a, r) => a + (r.bytes || 0), 0);
const totalBytes = s.totalBytes || regions.reduce((a, r) => a + (r.bytes || 0), 0);
const totalPois = regions.reduce((a, r) => a + (r.pois || 0), 0);
UI.modal.open({
title: '🗺️ Offline-Karten',
@ -2238,6 +2266,7 @@ window.Page_map = (() => {
</p>
<div class="flex flex-col gap-2">
<button class="btn btn-primary" id="off-dl">${UI.icon('download-simple')} Dieses Gebiet speichern (~5 MB)</button>
<button class="btn btn-secondary" id="off-bbox">${UI.icon('squares-four')} Sichtbaren Ausschnitt speichern</button>
<button class="btn btn-secondary" id="off-cov">${UI.icon('stack')} Gespeicherte Bereiche ${_covOn ? 'ausblenden' : 'anzeigen'}</button>
${regions.length ? `<button class="btn btn-secondary" id="off-clear" style="color:var(--c-danger)">${UI.icon('trash')} Alles löschen</button>` : ''}
</div>
@ -2245,6 +2274,7 @@ window.Page_map = (() => {
footer: `<button class="btn btn-secondary" data-modal-close style="width:100%">Schließen</button>`,
});
document.getElementById('off-dl')?.addEventListener('click', () => { UI.modal.close(); _downloadVectorRegion(); });
document.getElementById('off-bbox')?.addEventListener('click', () => { UI.modal.close(); _downloadViewport(); });
document.getElementById('off-cov')?.addEventListener('click', async () => { UI.modal.close(); await _setCoverage(!_covOn); });
document.getElementById('off-clear')?.addEventListener('click', async e => {
const btn = e.currentTarget;