diff --git a/VERSION b/VERSION index 66dae0a..3352d4f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1175 \ No newline at end of file +1176 \ No newline at end of file diff --git a/backend/static/index.html b/backend/static/index.html index 52ce81c..97f3692 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -86,14 +86,14 @@ Ban Yaro - + - - - - - + + + + + @@ -617,11 +617,11 @@ - - - - - + + + + + @@ -631,7 +631,7 @@ - + diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 09a298b..533079f 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 = '1175'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '1176'; // ← 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/pages/map.js b/backend/static/js/pages/map.js index 10b30fd..86087fa 100644 --- a/backend/static/js/pages/map.js +++ b/backend/static/js/pages/map.js @@ -15,6 +15,7 @@ window.Page_map = (() => { let _placingMarker = false; let _tempMarker = null; let _tileLayer = null; + let _usingVector = false; // true wenn Vektor-Basemap (PMTiles) statt OSM-Raster let _themeObserver = null; // Standort-Tracking @@ -633,16 +634,11 @@ window.Page_map = (() => { if (!_userPos) { _frankfurtTimer = setTimeout(() => _map.flyTo(center, 14, { duration: 2.5 }), 1200); } - _tileLayer = _buildTileLayer(); - _tileLayer.addTo(_map); - - // Sofort Dark-Filter anwenden wenn nötig (nach Tile-Load) - _tileLayer.on('load', _applyTileTheme); - _applyTileTheme(); - // Theme-Wechsel → Filter aktualisieren - _themeObserver = new MutationObserver(() => _applyTileTheme()); + _addBasemap(); + // Theme-Wechsel → Basemap aktualisieren (Vektor: Layer neu bauen / Raster: CSS-Filter) + _themeObserver = new MutationObserver(() => _onThemeChange()); _themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] }); - window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', _applyTileTheme); + window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', _onThemeChange); setTimeout(() => _map.invalidateSize(), 100); setTimeout(() => _map.invalidateSize(), 600); @@ -742,8 +738,52 @@ window.Page_map = (() => { return L.tileLayer(_OSM_URL, { maxZoom: 19 }); } + // Basemap hinzufügen: Vektor-PMTiles (Feature-Flag) mit sauberem Raster-Fallback. + // Marker/Cluster/Overlays/Scan bleiben in beiden Fällen identisch. + function _addBasemap() { + const _addRaster = () => { + _usingVector = false; + _tileLayer = _buildTileLayer(); + _tileLayer.addTo(_map); + _tileLayer.on('load', _applyTileTheme); + _applyTileTheme(); + }; + if (window.UI && UI.map.vectorEnabled && UI.map.vectorEnabled()) { + UI.map.vectorLayer({ dark: _isDarkMode() }).then(layer => { + if (!_map) return; + _usingVector = true; + _tileLayer = layer; + layer.addTo(_map); + _applyTileTheme(); // no-op bei Vektor (Theme steckt in den Tile-Farben) + if (!_map._byVectorAttr) { + _map._byVectorAttr = L.control.attribution({ prefix: false }).addTo(_map) + .addAttribution('© OpenStreetMap contributors'); + } + }).catch(err => { + console.warn('Vektor-Basemap nicht verfügbar — Fallback auf Raster:', err); + if (_map) _addRaster(); + }); + } else { + _addRaster(); + } + } + + // Theme-Wechsel: Vektor → Layer mit passendem Flavor neu bauen; Raster → CSS-Filter. + function _onThemeChange() { + if (_usingVector && _map && _tileLayer) { + UI.map.vectorLayer({ dark: _isDarkMode() }).then(layer => { + if (!_map) return; + if (_tileLayer) _map.removeLayer(_tileLayer); + _tileLayer = layer; + layer.addTo(_map); + }).catch(() => {}); + } else { + _applyTileTheme(); + } + } + function _applyTileTheme() { - if (!_map) return; + if (!_map || _usingVector) return; // bei Vektor kein CSS-Filter (würde doppelt abdunkeln) const tilePaneEl = _map.getPane('tilePane'); if (tilePaneEl) tilePaneEl.style.filter = _isDarkMode() ? _DARK_FILTER : ''; } diff --git a/backend/static/js/ui.js b/backend/static/js/ui.js index 4ce52ac..7dd0f12 100644 --- a/backend/static/js/ui.js +++ b/backend/static/js/ui.js @@ -491,6 +491,17 @@ const UI = (() => { }); return L.marker([lat, lon], { icon }); }, + + // Feature-Flag-Status der Vektor-Basemap (für Karten, die ihren Basemap-Layer + // selbst verwalten, z.B. pages/map.js). + vectorEnabled() { return _vectorMapEnabled(); }, + + // Lädt protomaps-leaflet + Regeln und liefert den fertigen Vektor-Basemap-Layer + // (Promise). dark=true → dunkles Theme. + async vectorLayer(opts = {}) { + await loadProtomaps(); + return MapVector.basemapLayer(opts); + }, }; // ---------------------------------------------------------- diff --git a/backend/static/landing.html b/backend/static/landing.html index 81ff8c5..2cf65fe 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 551d669..6035887 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 = '1175'; +const VER = '1176'; const CACHE_VERSION = `by-v${VER}`; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten