diff --git a/templates/adsb_dashboard.html b/templates/adsb_dashboard.html
index b029c1d..be7234a 100644
--- a/templates/adsb_dashboard.html
+++ b/templates/adsb_dashboard.html
@@ -4,27 +4,10 @@
AIRCRAFT RADAR // INTERCEPT - See the Invisible
-
- {% if offline_settings.assets_source != 'local' %}
-
- {% endif %}
- {% if offline_settings.fonts_source != 'local' %}
-
-
- {% endif %}
-
-
- {% if offline_settings.fonts_source == 'local' %}
+
- {% else %}
-
- {% endif %}
-
- {% if offline_settings.assets_source == 'local' %}
- {% else %}
-
- {% endif %}
@@ -39,11 +22,7 @@
window.INTERCEPT_DEFAULT_LAT = {{ default_latitude | tojson }};
window.INTERCEPT_DEFAULT_LON = {{ default_longitude | tojson }};
- {% if offline_settings.assets_source == 'local' %}
- {% else %}
-
- {% endif %}
@@ -2100,6 +2079,47 @@ sudo make install
now.toISOString().substring(11, 19) + ' UTC';
}
+ function createFallbackGridLayer() {
+ const layer = L.gridLayer({
+ tileSize: 256,
+ updateWhenIdle: true,
+ attribution: 'Local fallback grid'
+ });
+ layer.createTile = function(coords) {
+ const tile = document.createElement('canvas');
+ tile.width = 256;
+ tile.height = 256;
+ const ctx = tile.getContext('2d');
+
+ ctx.fillStyle = '#08121c';
+ ctx.fillRect(0, 0, 256, 256);
+
+ ctx.strokeStyle = 'rgba(0, 212, 255, 0.14)';
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(256, 0);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 256);
+ ctx.stroke();
+
+ ctx.strokeStyle = 'rgba(0, 212, 255, 0.08)';
+ ctx.beginPath();
+ ctx.moveTo(128, 0);
+ ctx.lineTo(128, 256);
+ ctx.moveTo(0, 128);
+ ctx.lineTo(256, 128);
+ ctx.stroke();
+
+ ctx.fillStyle = 'rgba(160, 220, 255, 0.28)';
+ ctx.font = '11px "JetBrains Mono", monospace';
+ ctx.fillText(`Z${coords.z} X${coords.x} Y${coords.y}`, 12, 22);
+
+ return tile;
+ };
+ return layer;
+ }
+
async function initMap() {
// Guard against double initialization (e.g. bfcache restore)
const container = document.getElementById('radarMap');
@@ -2115,13 +2135,9 @@ sudo make install
// Use settings manager for tile layer (allows runtime changes)
window.radarMap = radarMap;
- // Add fallback tiles immediately so the map is never blank
- const fallbackTiles = L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', {
- attribution: '© OSM © CARTO',
- maxZoom: 19,
- subdomains: 'abcd',
- className: 'tile-layer-cyan'
- }).addTo(radarMap);
+ // Use a zero-network fallback so dashboard navigation stays fast even
+ // when internet map providers are slow or unreachable.
+ const fallbackTiles = createFallbackGridLayer().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 56c5017..ee50836 100644
--- a/templates/ais_dashboard.html
+++ b/templates/ais_dashboard.html
@@ -4,27 +4,10 @@
VESSEL RADAR // INTERCEPT - See the Invisible
-
- {% if offline_settings.assets_source != 'local' %}
-
- {% endif %}
- {% if offline_settings.fonts_source != 'local' %}
-
-
- {% endif %}
-
-
- {% if offline_settings.fonts_source == 'local' %}
+
- {% else %}
-
- {% endif %}
-
- {% if offline_settings.assets_source == 'local' %}
- {% else %}
-
- {% endif %}
@@ -38,11 +21,7 @@
window.INTERCEPT_DEFAULT_LAT = {{ default_latitude | tojson }};
window.INTERCEPT_DEFAULT_LON = {{ default_longitude | tojson }};
- {% if offline_settings.assets_source == 'local' %}
- {% else %}
-
- {% endif %}
@@ -409,6 +388,47 @@
};
// Initialize map
+ function createFallbackGridLayer() {
+ const layer = L.gridLayer({
+ tileSize: 256,
+ updateWhenIdle: true,
+ attribution: 'Local fallback grid'
+ });
+ layer.createTile = function(coords) {
+ const tile = document.createElement('canvas');
+ tile.width = 256;
+ tile.height = 256;
+ const ctx = tile.getContext('2d');
+
+ ctx.fillStyle = '#07131c';
+ ctx.fillRect(0, 0, 256, 256);
+
+ ctx.strokeStyle = 'rgba(0, 212, 255, 0.12)';
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(256, 0);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 256);
+ ctx.stroke();
+
+ ctx.strokeStyle = 'rgba(34, 197, 94, 0.10)';
+ ctx.beginPath();
+ ctx.moveTo(128, 0);
+ ctx.lineTo(128, 256);
+ ctx.moveTo(0, 128);
+ ctx.lineTo(256, 128);
+ ctx.stroke();
+
+ ctx.fillStyle = 'rgba(160, 220, 255, 0.28)';
+ ctx.font = '11px "JetBrains Mono", monospace';
+ ctx.fillText(`Z${coords.z} X${coords.x} Y${coords.y}`, 12, 22);
+
+ return tile;
+ };
+ return layer;
+ }
+
async function initMap() {
// Guard against double initialization (e.g. bfcache restore)
const container = document.getElementById('vesselMap');
@@ -428,13 +448,9 @@
// Use settings manager for tile layer (allows runtime changes)
window.vesselMap = vesselMap;
- // Add fallback tile layer immediately so the map is never blank
- const fallbackTiles = L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', {
- attribution: '© OSM © CARTO',
- maxZoom: 19,
- subdomains: 'abcd',
- className: 'tile-layer-cyan'
- }).addTo(vesselMap);
+ // Use a zero-network fallback so dashboard navigation stays fast even
+ // when internet map providers are slow or unreachable.
+ const fallbackTiles = createFallbackGridLayer().addTo(vesselMap);
// Then try to upgrade tiles via Settings (non-blocking)
if (typeof Settings !== 'undefined') {
diff --git a/templates/satellite_dashboard.html b/templates/satellite_dashboard.html
index c5101f2..c8ecc88 100644
--- a/templates/satellite_dashboard.html
+++ b/templates/satellite_dashboard.html
@@ -4,20 +4,11 @@
SATELLITE COMMAND // iNTERCEPT - See the Invisible
-
- {% if offline_settings.fonts_source == 'local' %}
+
- {% else %}
-
- {% endif %}
-
- {% if offline_settings.assets_source == 'local' %}
- {% else %}
-
-
- {% endif %}
@@ -903,6 +894,47 @@
now.toISOString().substring(11, 19) + ' UTC';
}
+ function createFallbackGridLayer() {
+ const layer = L.gridLayer({
+ tileSize: 256,
+ updateWhenIdle: true,
+ attribution: 'Local fallback grid'
+ });
+ layer.createTile = function(coords) {
+ const tile = document.createElement('canvas');
+ tile.width = 256;
+ tile.height = 256;
+ const ctx = tile.getContext('2d');
+
+ ctx.fillStyle = '#08121c';
+ ctx.fillRect(0, 0, 256, 256);
+
+ ctx.strokeStyle = 'rgba(0, 212, 255, 0.12)';
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ ctx.moveTo(0, 0);
+ ctx.lineTo(256, 0);
+ ctx.moveTo(0, 0);
+ ctx.lineTo(0, 256);
+ ctx.stroke();
+
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.06)';
+ ctx.beginPath();
+ ctx.moveTo(128, 0);
+ ctx.lineTo(128, 256);
+ ctx.moveTo(0, 128);
+ ctx.lineTo(256, 128);
+ ctx.stroke();
+
+ ctx.fillStyle = 'rgba(160, 220, 255, 0.28)';
+ ctx.font = '11px "JetBrains Mono", monospace';
+ ctx.fillText(`Z${coords.z} X${coords.x} Y${coords.y}`, 12, 22);
+
+ return tile;
+ };
+ return layer;
+ }
+
async function initGroundMap() {
groundMap = L.map('groundMap', {
center: [20, 0],
@@ -914,13 +946,9 @@
window.groundMap = groundMap;
- // Add fallback tiles immediately so the map is visible instantly
- const fallbackTiles = L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png', {
- attribution: '© OSM © CARTO',
- maxZoom: 19,
- subdomains: 'abcd',
- className: 'tile-layer-cyan'
- }).addTo(groundMap);
+ // Use a zero-network fallback so dashboard navigation stays fast even
+ // when internet map providers are slow or unreachable.
+ const fallbackTiles = createFallbackGridLayer().addTo(groundMap);
// Upgrade tiles in background via Settings (with timeout fallback)
if (typeof Settings !== 'undefined') {