Offline-Karten Follow-ups: Staging-Default AN, Karten-Download-Button, Glyph-Persistenz

- by_offline_tiles Default AN auf staging.banyaro.app (localStorage/?tilesoffline=1/0 uebersteuert)
- Speed-Dial 'Karte offline speichern': GL -> MapOffline.downloadAround(Kartenmitte, 5km),
  Leaflet -> alter Raster-Prefetch (_cacheTiles war seit FAB-Redesign verwaist)
- Glyphs in IndexedDB (Key-Praefix f/) + byt://f/-Protokoll: ueberlebt App-Updates
- OSM-Raster-Prefetch im Offline-Tiles-Modus uebersprungen (GL nutzt das Raster nicht)
- Button-Sichtbarkeit gated: GL ohne Offline-Flag (= Production) zeigt ihn nicht
This commit is contained in:
rene 2026-06-06 11:03:46 +02:00
parent 30e82b7931
commit 70a1f5856a
5 changed files with 109 additions and 16 deletions

View file

@ -257,6 +257,11 @@ window.Page_map = (() => {
<span class="map-sd-label">Marker setzen</span>
<button class="map-sd-btn map-fab--pin" id="map-pin-btn" title="Marker setzen"><svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#push-pin"></use></svg></button>
</div>
${(!_useGL() || _offlineTilesEnabled()) ? `
<div class="map-sd-item">
<span class="map-sd-label">Karte offline speichern</span>
<button class="map-sd-btn" id="map-offline-btn" title="Karte offline speichern"><svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#cloud-arrow-down"></use></svg></button>
</div>` : ''}
${App.hasPro(_appState?.user) ? `
<div class="map-sd-item">
<span class="map-sd-label">Regenradar</span>
@ -368,6 +373,11 @@ window.Page_map = (() => {
_sdEl?.classList.remove('open');
_togglePlacementMode();
});
document.getElementById('map-offline-btn')?.addEventListener('click', () => {
_sdEl?.classList.remove('open');
if (_engineGL) _downloadVectorRegion(); // GL: Vektorkacheln → IndexedDB (byt://)
else _cacheTiles(); // Leaflet: OSM-Raster → SW-Cache
});
document.getElementById('map-radar-btn')?.addEventListener('click', () => {
_sdEl?.classList.remove('open');
_toggleRadar();
@ -763,6 +773,18 @@ window.Page_map = (() => {
} catch (e) { return false; }
}
// Offline-Vektorkacheln-Flag — gleiche Default-Logik wie map-gl-style.js _offlineEnabled()
// (dupliziert, weil map-gl-style.js erst mit der GL-Karte lazy lädt, das Markup aber sofort rendert).
// Steuert nur die Button-Sichtbarkeit: im GL-Modus ohne byt://-Quelle wäre der Download nutzlos.
function _offlineTilesEnabled() {
try {
const flag = localStorage.getItem('by_offline_tiles');
if (flag === '1') return true;
if (flag === '0') return false;
return location.hostname === 'staging.banyaro.app';
} catch (e) { return false; }
}
function loadMapLibre() {
if (_maplibreLoaded) return Promise.resolve();
const v = '?v=' + (window.APP_VER || '');
@ -2115,6 +2137,31 @@ window.Page_map = (() => {
return urls;
}
// GL-Modus: Vektorkacheln (5 km um die Kartenmitte) + Glyphs → IndexedDB (byt://).
// Gegenstück zum Welten-FAB-Download (GPS-Position) — hier zählt die KARTENMITTE,
// damit man eine entfernte Gegend (Urlaubsort) vorab speichern kann. docs/OFFLINE_MAPS_PLAN.md
async function _downloadVectorRegion() {
if (!_map || !window.MapOffline) return;
const btn = document.getElementById('map-offline-btn');
if (btn?.classList.contains('loading')) return; // läuft bereits
const c = _map.getCenter();
btn?.classList.add('loading');
_setOsmStatus('Offline: 0 %…');
try {
const res = await MapOffline.downloadAround(c.lat, c.lng, 5, p => {
_setOsmStatus(`Offline: ${Math.round(p.done / p.total * 100)} %…`);
});
_setOsmStatus('');
UI.toast.success(`Gegend offline gespeichert — ${res.tiles} Kacheln, ${(res.bytes / 1048576).toFixed(1)} MB.`);
window.OfflineIndicator?.refresh(); // Pfoten-Segment 5 sofort grün
} catch (e) {
_setOsmStatus('');
UI.toast.error('Offline-Download fehlgeschlagen — bitte erneut versuchen.');
} finally {
btn?.classList.remove('loading');
}
}
async function _cacheTiles() {
if (!_map) return;
if (!('serviceWorker' in navigator) || !navigator.serviceWorker.controller) {