Auto deploy: 2025-12-09 06:00:27

This commit is contained in:
Your Name 2025-12-09 06:00:31 +00:00
parent 4b7d8c3965
commit ae2be1a71b
2 changed files with 143 additions and 126 deletions

View File

@ -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 = `
<div class="marker-inner">
<div class="marker-dot"></div>
<span class="marker-text">${short}</span>
</div>
`;
const inner = document.createElement("div");
inner.className = "marker-inner";
const expandedHTML = `
<div class="marker-expanded-inner">
<div class="marker-expanded-header">
<div class="marker-dot"></div>
<span class="marker-expanded-title">${title}</span>
</div>
<div class="marker-expanded-body">
${body}
</div>
</div>
`;
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);
}

View File

@ -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) */