diff --git a/static/js/core/settings-manager.js b/static/js/core/settings-manager.js index e9b26fd..d4593af 100644 --- a/static/js/core/settings-manager.js +++ b/static/js/core/settings-manager.js @@ -20,13 +20,13 @@ const Settings = { subdomains: 'abc' }, cartodb_dark: { - url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png?v=2', - attribution: '© OpenStreetMap contributors © CARTO', + url: 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', + attribution: '© OSM © CARTO', subdomains: 'abcd' }, cartodb_light: { - url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', - attribution: '© OpenStreetMap contributors © CARTO', + url: 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', + attribution: '© OSM © CARTO', subdomains: 'abcd' }, esri_world: { @@ -36,6 +36,9 @@ const Settings = { } }, + // Registry of maps that can be updated + _registeredMaps: [], + // Current settings cache _cache: {}, @@ -178,7 +181,44 @@ const Settings = { }; } - return this.tileProviders[provider] || this.tileProviders.openstreetmap; + return this.tileProviders[provider] || this.tileProviders.cartodb_dark; + }, + + /** + * Register a map to receive tile updates when settings change + * @param {L.Map} map - Leaflet map instance + */ + registerMap(map) { + if (map && typeof map.eachLayer === 'function' && !this._registeredMaps.includes(map)) { + this._registeredMaps.push(map); + } + }, + + /** + * Unregister a map + * @param {L.Map} map - Leaflet map instance + */ + unregisterMap(map) { + const idx = this._registeredMaps.indexOf(map); + if (idx > -1) { + this._registeredMaps.splice(idx, 1); + } + }, + + /** + * Create a tile layer using current settings + * @returns {L.TileLayer} Configured tile layer + */ + createTileLayer() { + const config = this.getTileConfig(); + const options = { + attribution: config.attribution, + maxZoom: 19 + }; + if (config.subdomains) { + options.subdomains = config.subdomains; + } + return L.tileLayer(config.url, options); }, /** @@ -277,22 +317,30 @@ const Settings = { }, /** - * Update map tiles if a map exists + * Update map tiles on all known maps */ _updateMapTiles() { - // Look for common map variable names - const maps = [ + // Combine registered maps with common window map variables + const windowMaps = [ window.map, window.leafletMap, window.aprsMap, - window.adsbMap + window.adsbMap, + window.radarMap, + window.vesselMap, + window.groundMap, + window.groundTrackMap, + window.meshMap ].filter(m => m && typeof m.eachLayer === 'function'); - if (maps.length === 0) return; + // Combine with registered maps, removing duplicates + const allMaps = [...new Set([...this._registeredMaps, ...windowMaps])]; + + if (allMaps.length === 0) return; const config = this.getTileConfig(); - maps.forEach(map => { + allMaps.forEach(map => { // Remove existing tile layers map.eachLayer(layer => { if (layer instanceof L.TileLayer) { @@ -302,7 +350,8 @@ const Settings = { // Add new tile layer const options = { - attribution: config.attribution + attribution: config.attribution, + maxZoom: 19 }; if (config.subdomains) { options.subdomains = config.subdomains; diff --git a/static/js/modes/meshtastic.js b/static/js/modes/meshtastic.js index 308d303..1ddec95 100644 --- a/static/js/modes/meshtastic.js +++ b/static/js/modes/meshtastic.js @@ -92,12 +92,19 @@ const Meshtastic = (function() { const defaultLon = -98.5795; meshMap = L.map('meshMap').setView([defaultLat, defaultLon], 4); + window.meshMap = meshMap; - // Dark themed map tiles - L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png?v=2', { - attribution: '© OSM © CARTO', - maxZoom: 19 - }).addTo(meshMap); + // Use settings manager for tile layer (allows runtime changes) + if (typeof Settings !== 'undefined' && Settings.createTileLayer) { + Settings.createTileLayer().addTo(meshMap); + Settings.registerMap(meshMap); + } else { + L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', { + attribution: '© OSM © CARTO', + maxZoom: 19, + subdomains: 'abcd' + }).addTo(meshMap); + } // Handle resize setTimeout(() => { diff --git a/templates/adsb_dashboard.html b/templates/adsb_dashboard.html index 6f4a8a8..920d1e9 100644 --- a/templates/adsb_dashboard.html +++ b/templates/adsb_dashboard.html @@ -2340,10 +2340,18 @@ sudo make install maxZoom: 15 }); - L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png?v=2', { - attribution: '© OSM © CARTO', - maxZoom: 19 - }).addTo(radarMap); + // Use settings manager for tile layer (allows runtime changes) + window.radarMap = radarMap; + if (typeof Settings !== 'undefined' && Settings.createTileLayer) { + Settings.createTileLayer().addTo(radarMap); + Settings.registerMap(radarMap); + } else { + L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', { + attribution: '© OSM © CARTO', + maxZoom: 19, + subdomains: 'abcd' + }).addTo(radarMap); + } // Draw range rings after map is ready setTimeout(() => drawRangeRings(), 100); diff --git a/templates/ais_dashboard.html b/templates/ais_dashboard.html index 4ac60b2..2c9e54b 100644 --- a/templates/ais_dashboard.html +++ b/templates/ais_dashboard.html @@ -390,11 +390,18 @@ zoomControl: true }); - // Dark themed map tiles - L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png?v=2', { - attribution: '© OSM © CARTO', - maxZoom: 19 - }).addTo(vesselMap); + // Use settings manager for tile layer (allows runtime changes) + window.vesselMap = vesselMap; + if (typeof Settings !== 'undefined' && Settings.createTileLayer) { + Settings.createTileLayer().addTo(vesselMap); + Settings.registerMap(vesselMap); + } else { + L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', { + attribution: '© OSM © CARTO', + maxZoom: 19, + subdomains: 'abcd' + }).addTo(vesselMap); + } // Add observer marker observerMarker = L.circleMarker([observerLocation.lat, observerLocation.lon], { diff --git a/templates/index.html b/templates/index.html index 87c1405..0c79d2a 100644 --- a/templates/index.html +++ b/templates/index.html @@ -7590,12 +7590,19 @@ const initialZoom = (aprsUserLocation.lat || gpsLastPosition?.latitude) ? 8 : 4; aprsMap = L.map('aprsMap').setView([initialLat, initialLon], initialZoom); + window.aprsMap = aprsMap; - // Dark themed map tiles - L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png?v=2', { - attribution: '© OSM © CARTO', - maxZoom: 19 - }).addTo(aprsMap); + // Use settings manager for tile layer (allows runtime changes) + if (typeof Settings !== 'undefined' && Settings.createTileLayer) { + Settings.createTileLayer().addTo(aprsMap); + Settings.registerMap(aprsMap); + } else { + L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', { + attribution: '© OSM © CARTO', + maxZoom: 19, + subdomains: 'abcd' + }).addTo(aprsMap); + } // Add user marker if GPS position is already available if (gpsConnected && gpsLastPosition && gpsLastPosition.latitude && gpsLastPosition.longitude) { @@ -8494,11 +8501,19 @@ zoomControl: true, attributionControl: false }); + window.groundTrackMap = groundTrackMap; - L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png?v=2', { - attribution: '© OSM © CARTO', - maxZoom: 19 - }).addTo(groundTrackMap); + // Use settings manager for tile layer (allows runtime changes) + if (typeof Settings !== 'undefined' && Settings.createTileLayer) { + Settings.createTileLayer().addTo(groundTrackMap); + Settings.registerMap(groundTrackMap); + } else { + L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', { + attribution: '© OSM © CARTO', + maxZoom: 19, + subdomains: 'abcd' + }).addTo(groundTrackMap); + } // Add observer marker const lat = parseFloat(document.getElementById('obsLat').value) || 51.5; diff --git a/templates/satellite_dashboard.html b/templates/satellite_dashboard.html index df54564..74d56a9 100644 --- a/templates/satellite_dashboard.html +++ b/templates/satellite_dashboard.html @@ -416,10 +416,18 @@ worldCopyJump: true }); - L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png?v=2', { - attribution: '© OSM © CARTO', - maxZoom: 19 - }).addTo(groundMap); + // Use settings manager for tile layer (allows runtime changes) + window.groundMap = groundMap; + if (typeof Settings !== 'undefined' && Settings.createTileLayer) { + Settings.createTileLayer().addTo(groundMap); + Settings.registerMap(groundMap); + } else { + L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', { + attribution: '© OSM © CARTO', + maxZoom: 19, + subdomains: 'abcd' + }).addTo(groundMap); + } } function getLocation() {