From ae2be1a71b4215cb2d24217a19007b7a0e9a97d3 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 9 Dec 2025 06:00:31 +0000 Subject: [PATCH] Auto deploy: 2025-12-09 06:00:27 --- src/components/Map/markerManager.js | 210 ++++++++++++++++++---------- src/styles/mapMarkers.css | 59 +------- 2 files changed, 143 insertions(+), 126 deletions(-) diff --git a/src/components/Map/markerManager.js b/src/components/Map/markerManager.js index b2e7648..51942ec 100644 --- a/src/components/Map/markerManager.js +++ b/src/components/Map/markerManager.js @@ -1,108 +1,170 @@ import maplibregl from "maplibre-gl"; -import { getCoords } from "./mapGeo"; -import { extractPostText } from "./mapFilter"; -// Supprime tous les markers actuels +/** + * Supprime tous les marqueurs de la carte + */ export function clearAllMarkers(markersRef, expandedElRef) { - markersRef.current.forEach((m) => m.marker.remove()); + if (markersRef.current) { + for (const item of markersRef.current) { + try { + item.marker.remove(); + } catch { + // ignore + } + } + } markersRef.current = []; if (expandedElRef) { expandedElRef.current = null; } } -// Crée un marker pour un post +/** + * Crée un DOM marker pour un post et l'ancre sur sa coordonnée. + * - mapRef : ref vers la map MapLibre + * - markersRef : ref vers la liste [{ id, marker, el, post }] + * - expandedElRef : ref vers l'élément DOM du post actuellement "grand" + */ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) { const map = mapRef.current; if (!map) return; - const coords = getCoords(post); - if (!coords) return; + // Récupère les coords (lat/lon / Lat/Lon / latitude/longitude) + const lat = + typeof post.lat === "number" + ? post.lat + : typeof post.Lat === "number" + ? post.Lat + : typeof post.latitude === "number" + ? post.latitude + : null; - // évite les doublons (même id déjà affiché) - if ( - typeof post.id === "number" && - markersRef.current.some((m) => m.id === post.id) - ) { + const lon = + typeof post.lon === "number" + ? post.lon + : typeof post.Lon === "number" + ? post.Lon + : typeof post.longitude === "number" + ? post.longitude + : null; + + if (lat == null || lon == null) { + console.warn("Post sans coordonnée valide:", post); return; } - const [lngP, latP] = coords; - if ( - typeof lngP !== "number" || - typeof latP !== "number" || - Number.isNaN(lngP) || - Number.isNaN(latP) - ) { - return; - } + // Petit texte (on garde court) + const title = (post.title || post.Title || "").trim() || "Untitled"; + const snippet = + (post.snippet || post.Snippet || "").trim() || + (post.body || post.Body || "").trim() || + title; - const { title, body, short } = extractPostText(post); + // ELEMENT DOM DU MARKER + const root = document.createElement("div"); + root.className = "post-marker post-marker-compact"; - const compactHTML = ` -
-
- ${short} -
- `; + const inner = document.createElement("div"); + inner.className = "marker-inner"; - const expandedHTML = ` -
-
-
- ${title} -
-
- ${body} -
-
- `; + const dot = document.createElement("div"); + dot.className = "marker-dot"; - const el = document.createElement("div"); - el.className = "post-marker post-marker-compact"; - el.innerHTML = compactHTML; + const text = document.createElement("div"); + text.className = "marker-text"; + text.textContent = title; + inner.appendChild(dot); + inner.appendChild(text); + root.appendChild(inner); + + // Marker MapLibre -> POSITION = [lon, lat] SANS OFFSET const marker = new maplibregl.Marker({ - element: el, - anchor: "bottom", + element: root, + anchor: "bottom", // le bas du marker pointe sur la coordonnée }) - .setLngLat(coords) + .setLngLat([lon, lat]) .addTo(map); - const meta = { - id: typeof post.id === "number" ? post.id : null, - marker, - el, - compactHTML, - expandedHTML, - }; - markersRef.current.push(meta); + // Sauvegarde pour pouvoir les nettoyer + const entry = { id: post.id, marker, el: root, post }; + markersRef.current.push(entry); - const toggle = () => { - if (expandedElRef.current && expandedElRef.current !== el) { - const prev = markersRef.current.find( - (m) => m.el === expandedElRef.current - ); - if (prev) { - prev.el.className = "post-marker post-marker-compact"; - prev.el.innerHTML = prev.compactHTML; - } + // Quand on clique -> on ouvre le gros post par-dessus, mais à la même coordonnée + root.addEventListener("click", (ev) => { + ev.stopPropagation(); + + // Fermer le précédent gros post + if (expandedElRef.current && expandedElRef.current !== root) { + collapseMarkerElement(expandedElRef.current); } - if (expandedElRef.current === el) { - el.className = "post-marker post-marker-compact"; - el.innerHTML = compactHTML; + // Toggle compact/expanded sur ce marker + if (root.classList.contains("post-marker-expanded")) { + collapseMarkerElement(root); expandedElRef.current = null; } else { - el.className = "post-marker post-marker-expanded"; - el.innerHTML = expandedHTML; - expandedElRef.current = el; + expandMarkerElement(root, { title, snippet }); + expandedElRef.current = root; } - }; - - el.addEventListener("click", toggle); - el.addEventListener("touchend", (e) => { - e.preventDefault(); - toggle(); }); } + +/** + * Passe un marker en mode "grand post" + */ +function expandMarkerElement(root, { title, snippet }) { + root.classList.remove("post-marker-compact"); + root.classList.add("post-marker-expanded"); + + // Nettoie l'intérieur et reconstruit + root.innerHTML = ""; + + const container = document.createElement("div"); + container.className = "marker-expanded-inner"; + + const header = document.createElement("div"); + header.className = "marker-expanded-header"; + + const dot = document.createElement("div"); + dot.className = "marker-dot"; + + const titleEl = document.createElement("div"); + titleEl.className = "marker-expanded-title"; + titleEl.textContent = title; + + header.appendChild(dot); + header.appendChild(titleEl); + + const bodyEl = document.createElement("div"); + bodyEl.className = "marker-expanded-body"; + bodyEl.textContent = snippet; + + container.appendChild(header); + container.appendChild(bodyEl); + + root.appendChild(container); +} + +/** + * Repasse un marker en mode petit post + */ +function collapseMarkerElement(root) { + root.classList.remove("post-marker-expanded"); + root.classList.add("post-marker-compact"); + root.innerHTML = ""; + + const inner = document.createElement("div"); + inner.className = "marker-inner"; + + const dot = document.createElement("div"); + dot.className = "marker-dot"; + + const text = document.createElement("div"); + text.className = "marker-text"; + text.textContent = "…"; + + inner.appendChild(dot); + inner.appendChild(text); + root.appendChild(inner); +} diff --git a/src/styles/mapMarkers.css b/src/styles/mapMarkers.css index 999f791..3a9a52a 100644 --- a/src/styles/mapMarkers.css +++ b/src/styles/mapMarkers.css @@ -1,22 +1,12 @@ +/* IMPORTANT: on ne touche pas au transform du marker : + MapLibre l'utilise pour placer le point. */ + .post-marker { - position: relative; - transform: none !important; /* pas de translate chelou */ - display: flex; - align-items: center; - justify-content: center; pointer-events: auto; } -/* Petit post */ -.post-marker-compact { - padding: 2px 4px; -} - -.post-marker-expanded { - padding: 0; -} - -.marker-inner { +/* Petit post compact */ +.post-marker-compact .marker-inner { display: flex; align-items: center; padding: 4px 8px; @@ -27,25 +17,8 @@ max-width: 220px; } -.marker-dot { - width: 10px; - height: 10px; - border-radius: 999px; - background: #3ec6ff; - margin-right: 6px; -} - -.marker-text { - color: #e8f5ff; - font-size: 11px; - font-weight: 500; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - /* Gros post */ -.marker-expanded-inner { +.post-marker-expanded .marker-expanded-inner { display: flex; flex-direction: column; padding: 8px 10px; @@ -56,22 +29,4 @@ max-width: 260px; } -.marker-expanded-header { - display: flex; - align-items: center; - margin-bottom: 6px; -} - -.marker-expanded-title { - color: #f5fbff; - font-size: 12px; - font-weight: 600; -} - -.marker-expanded-body { - color: #c7e3ff; - font-size: 11px; - line-height: 1.35; - max-height: 120px; - overflow: hidden; -} +/* Etc… (le reste de ton style peut rester pareil) */