Ladebalken bei Layer-Aktivierung + Ortsnamen-Rendering verbessert

- Animierter Ladebalken unter jedem Layer-Toggle bei Datenabruf
- Status-Text (Lade Daten.../Fehler beim Laden)
- Fetch-Wrapper: nur 401 redirected zum Login, nicht 403
- Ortsnamen: minimumLevel, tileWidth/Height, LINEAR Texture-Filter
  fuer konsistente Schriftgroessen beim Laden
Dieser Commit ist enthalten in:
Claude Dev
2026-03-24 12:22:21 +01:00
Ursprung 01f0b375e7
Commit 6f4c5ab3a6
7 geänderte Dateien mit 74 neuen und 5 gelöschten Zeilen

Datei anzeigen

@@ -112,3 +112,40 @@ html, body { height: 100%; overflow: hidden; background: var(--bg-primary); colo
.cesium-selection-wrapper {
border-color: var(--accent) !important;
}
/* === Loading Indicator === */
.layer-loading {
display: none;
height: 2px;
background: var(--accent);
position: relative;
overflow: hidden;
border-radius: 1px;
margin: 4px 0 0;
}
.layer-loading.active {
display: block;
}
.layer-loading::after {
content: '';
position: absolute;
left: -40%;
width: 40%;
height: 100%;
background: linear-gradient(90deg, transparent, #00ff88, transparent);
animation: layer-loading-slide 1s ease-in-out infinite;
}
@keyframes layer-loading-slide {
0% { left: -40%; }
100% { left: 100%; }
}
.layer-status {
font-size: 9px;
color: var(--text-dim);
margin-top: 2px;
display: none;
}
.layer-status.active {
display: block;
}

Datei anzeigen

@@ -21,7 +21,7 @@
opts.headers['Authorization'] = 'Bearer ' + localStorage.getItem('globe_token');
}
return _origFetch(url, opts).then(function(r) {
if (r.status === 401 || r.status === 403) { localStorage.removeItem('globe_token'); window.location.href = '/login'; }
if (r.status === 401) { localStorage.removeItem('globe_token'); window.location.href = '/login'; }
return r;
});
};
@@ -52,24 +52,32 @@
<span class="layer-name">Flugverkehr</span>
<span class="layer-count" id="count-flights">-</span>
</label>
<div class="layer-loading" id="loading-flights"></div>
<div class="layer-status" id="status-flights"></div>
<label class="layer-toggle">
<input type="checkbox" id="layer-ships" checked>
<span class="layer-dot dot-ships"></span>
<span class="layer-name">Schiffsverkehr</span>
<span class="layer-count" id="count-ships">-</span>
</label>
<div class="layer-loading" id="loading-ships"></div>
<div class="layer-status" id="status-ships"></div>
<label class="layer-toggle">
<input type="checkbox" id="layer-quakes">
<span class="layer-dot dot-quakes"></span>
<span class="layer-name">Erdbeben</span>
<span class="layer-count" id="count-quakes">-</span>
</label>
<div class="layer-loading" id="loading-quakes"></div>
<div class="layer-status" id="status-quakes"></div>
<label class="layer-toggle">
<input type="checkbox" id="layer-gdelt">
<span class="layer-dot dot-gdelt"></span>
<span class="layer-name">Nachrichten</span>
<span class="layer-count" id="count-gdelt">-</span>
</label>
<div class="layer-loading" id="loading-gdelt"></div>
<div class="layer-status" id="status-gdelt"></div>
</div>
<div class="panel-divider"></div>
<div class="panel-section">

Datei anzeigen

@@ -89,11 +89,16 @@ const Globe = {
this._labelsLayer = this.viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
minimumLevel: 1,
maximumLevel: 18,
tileWidth: 256,
tileHeight: 256,
credit: 'Esri',
})
);
this._labelsLayer.alpha = 0.9;
this._labelsLayer.alpha = 0.95;
this._labelsLayer.minificationFilter = Cesium.TextureMinificationFilter.LINEAR;
this._labelsLayer.magnificationFilter = Cesium.TextureMagnificationFilter.LINEAR;
} else if (!on && this._labelsLayer) {
this.viewer.imageryLayers.remove(this._labelsLayer);
this._labelsLayer = null;

Datei anzeigen

@@ -28,6 +28,10 @@ const FlightsLayer = {
_fetch() {
var self = this;
var loadEl = document.getElementById('loading-flights');
var statusEl = document.getElementById('status-flights');
if (loadEl) loadEl.classList.add('active');
if (statusEl) { statusEl.textContent = 'Lade Daten...'; statusEl.classList.add('active'); }
fetch('/api/flights')
.then(function(r) { return r.json(); })
.then(function(data) {
@@ -72,6 +76,7 @@ const FlightsLayer = {
});
});
})
.catch(function(e) { console.warn('Flights fetch error:', e); });
.catch(function(e) { console.warn('Flights fetch error:', e); if (statusEl) { statusEl.textContent = 'Fehler beim Laden'; } })
.finally(function() { if (loadEl) loadEl.classList.remove('active'); setTimeout(function() { if (statusEl) statusEl.classList.remove('active'); }, 3000); });
},
};

Datei anzeigen

@@ -28,6 +28,10 @@ const GdeltLayer = {
_fetch() {
var self = this;
var loadEl = document.getElementById('loading-gdelt');
var statusEl = document.getElementById('status-gdelt');
if (loadEl) loadEl.classList.add('active');
if (statusEl) { statusEl.textContent = 'Lade Daten...'; statusEl.classList.add('active'); }
fetch('/api/gdelt')
.then(function(r) { return r.json(); })
.then(function(data) {

Datei anzeigen

@@ -28,6 +28,10 @@ const QuakesLayer = {
_fetch() {
var self = this;
var loadEl = document.getElementById('loading-quakes');
var statusEl = document.getElementById('status-quakes');
if (loadEl) loadEl.classList.add('active');
if (statusEl) { statusEl.textContent = 'Lade Daten...'; statusEl.classList.add('active'); }
fetch('/api/quakes')
.then(function(r) { return r.json(); })
.then(function(data) {
@@ -66,6 +70,7 @@ const QuakesLayer = {
});
});
})
.catch(function(e) { console.warn('Quakes fetch error:', e); });
.catch(function(e) { console.warn('Quakes fetch error:', e); if (statusEl) { statusEl.textContent = 'Fehler beim Laden'; } })
.finally(function() { if (loadEl) loadEl.classList.remove('active'); setTimeout(function() { if (statusEl) statusEl.classList.remove('active'); }, 3000); });
},
};

Datei anzeigen

@@ -28,6 +28,10 @@ const ShipsLayer = {
_fetch() {
var self = this;
var loadEl = document.getElementById('loading-ships');
var statusEl = document.getElementById('status-ships');
if (loadEl) loadEl.classList.add('active');
if (statusEl) { statusEl.textContent = 'Lade Daten...'; statusEl.classList.add('active'); }
fetch('/api/ships')
.then(function(r) { return r.json(); })
.then(function(data) {
@@ -72,6 +76,7 @@ const ShipsLayer = {
});
});
})
.catch(function(e) { console.warn('Ships fetch error:', e); });
.catch(function(e) { console.warn('Ships fetch error:', e); if (statusEl) { statusEl.textContent = 'Fehler beim Laden'; } })
.finally(function() { if (loadEl) loadEl.classList.remove('active'); setTimeout(function() { if (statusEl) statusEl.classList.remove('active'); }, 3000); });
},
};