Karten: Mitglieder-Karte (Forum) auf GL + verwaiste Orte-Seite gelöscht
Mitglieder-Karte (forum.js): L.map/L.tileLayer(OSM) → UI.map.create, Cluster + Marker über die Facade (UI.map.clusterGroup/svgMarker), eigenes Leaflet-/ MarkerCluster-Nachladen raus. destroy() gibt Karte+Gruppe beim Verlassen frei. Headless verifiziert: GL-Canvas, 2 Mitglieder-Marker, keine Fehler. places.js (separate 'Hundefreundliche Orte'-Seite) war verwaist — in keiner Navigation/keinem pages-Registry, nicht erreichbar. Die hundefreundlichen Orte laufen längst als POI-Marker auf der zentralen GL-Karte (map.js). Auf Renés Entscheidung gelöscht (JS + CSS-Block in components.css). Damit laufen ALLE erreichbaren Karten der App auf MapLibre GL.
This commit is contained in:
parent
720971d252
commit
da6451a1c7
8 changed files with 32 additions and 650 deletions
|
|
@ -13,8 +13,6 @@ window.Page_forum = (() => {
|
|||
let _offset = 0;
|
||||
let _searchTimer = null;
|
||||
let _searching = false;
|
||||
let _mapLoaded = false;
|
||||
let _leafletLoaded = false;
|
||||
let _map = null;
|
||||
let _clusterGroup = null;
|
||||
let _activeSection = 'list'; // 'list' | 'map'
|
||||
|
|
@ -1237,15 +1235,11 @@ function _fmtDate(iso) {
|
|||
}
|
||||
});
|
||||
|
||||
await _loadLeaflet();
|
||||
const mapEl = document.getElementById('forum-map');
|
||||
if (!mapEl) return;
|
||||
|
||||
_map = L.map(mapEl, { zoomControl: true }).setView([51.0, 10.0], 6);
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap',
|
||||
maxZoom: 18,
|
||||
}).addTo(_map);
|
||||
// GL über die Facade (gleicher Style wie die zentrale Karte), Fallback Leaflet.
|
||||
_map = await UI.map.create(mapEl, { center: [51.0, 10.0], zoom: 6, zoomControl: true, attributionControl: false });
|
||||
|
||||
_loadMembersOnMap();
|
||||
}
|
||||
|
|
@ -1253,37 +1247,20 @@ function _fmtDate(iso) {
|
|||
async function _loadMembersOnMap() {
|
||||
if (!_map) return;
|
||||
try {
|
||||
// MarkerCluster laden falls nicht vorhanden
|
||||
if (!window.L.markerClusterGroup) {
|
||||
await Promise.all([
|
||||
new Promise((res, rej) => {
|
||||
if (document.querySelector('link[href*="MarkerCluster"]')) { res(); return; }
|
||||
const l1 = document.createElement('link'); l1.rel='stylesheet'; l1.href='/css/MarkerCluster.css'; l1.onload=res; l1.onerror=rej; document.head.appendChild(l1);
|
||||
}),
|
||||
new Promise((res, rej) => {
|
||||
const s = document.createElement('script'); s.src='/js/leaflet.markercluster.js'; s.onload=res; s.onerror=rej; document.head.appendChild(s);
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
const members = await API.forum.membersMap();
|
||||
|
||||
// Alte Cluster-Gruppe sauber entfernen
|
||||
if (_clusterGroup) { _map.removeLayer(_clusterGroup); _clusterGroup = null; }
|
||||
// Alte Gruppe sauber entfernen
|
||||
if (_clusterGroup) { try { _map.removeLayer(_clusterGroup); } catch (e) {} _clusterGroup = null; }
|
||||
|
||||
_clusterGroup = L.markerClusterGroup({ maxClusterRadius: 60 });
|
||||
_clusterGroup = UI.map.clusterGroup({ maxClusterRadius: 60 });
|
||||
members.forEach(m => {
|
||||
const icon = L.divIcon({
|
||||
className: '',
|
||||
html: `<div style="width:32px;height:32px;border-radius:50%;
|
||||
const html = `<div style="width:32px;height:32px;border-radius:50%;
|
||||
background:var(--c-primary);color:#fff;font-size:13px;font-weight:700;
|
||||
display:flex;align-items:center;justify-content:center;
|
||||
box-shadow:0 2px 5px rgba(0,0,0,0.35);
|
||||
border:2px solid rgba(255,255,255,0.8)">${UI.escape((m.vorname||'?')[0].toUpperCase())}</div>`,
|
||||
iconSize: [32, 32], iconAnchor: [16, 16],
|
||||
});
|
||||
border:2px solid rgba(255,255,255,0.8)">${UI.escape((m.vorname||'?')[0].toUpperCase())}</div>`;
|
||||
_clusterGroup.addLayer(
|
||||
L.marker([m.lat, m.lon], { icon })
|
||||
UI.map.svgMarker(m.lat, m.lon, html, { size: 32, anchorY: 16 })
|
||||
.bindPopup(`<strong>${UI.escape(m.vorname || '?')}</strong>`)
|
||||
);
|
||||
});
|
||||
|
|
@ -1293,30 +1270,6 @@ function _fmtDate(iso) {
|
|||
}
|
||||
}
|
||||
|
||||
async function _loadLeaflet() {
|
||||
if (_leafletLoaded || window.L) { _leafletLoaded = true; return; }
|
||||
|
||||
// CSS
|
||||
if (!document.querySelector('link[href*="leaflet.css"]')) {
|
||||
const lCss = document.createElement('link');
|
||||
lCss.rel = 'stylesheet';
|
||||
lCss.href = '/css/leaflet.css';
|
||||
document.head.appendChild(lCss);
|
||||
}
|
||||
|
||||
// JS
|
||||
await new Promise((resolve, reject) => {
|
||||
if (window.L) { resolve(); return; }
|
||||
const s = document.createElement('script');
|
||||
s.src = '/js/leaflet.js';
|
||||
s.onload = resolve;
|
||||
s.onerror = reject;
|
||||
document.head.appendChild(s);
|
||||
});
|
||||
|
||||
_leafletLoaded = true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Moderations-Panel
|
||||
// ----------------------------------------------------------
|
||||
|
|
@ -1469,6 +1422,13 @@ function _fmtDate(iso) {
|
|||
document.body.appendChild(lb);
|
||||
}
|
||||
|
||||
return { init, refresh, onDogChange, openNew, openThread: _openThread };
|
||||
// Karte beim Verlassen freigeben (WebGL-Kontext-Leak vermeiden).
|
||||
function destroy() {
|
||||
try { _clusterGroup && _clusterGroup.remove && _clusterGroup.remove(); } catch (e) {}
|
||||
try { _map && _map.remove && _map.remove(); } catch (e) {}
|
||||
_map = null; _clusterGroup = null;
|
||||
}
|
||||
|
||||
return { init, refresh, onDogChange, openNew, openThread: _openThread, destroy };
|
||||
|
||||
})();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue