update frontend
This commit is contained in:
parent
a77d1e60d4
commit
b5babb5d50
|
|
@ -8,28 +8,45 @@ export function clearAllMarkers(markersRef, expandedElRef) {
|
|||
for (const m of markersRef.current) {
|
||||
try {
|
||||
m.marker.remove();
|
||||
} catch {}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
markersRef.current = [];
|
||||
if (expandedElRef) expandedElRef.current = null;
|
||||
if (expandedElRef) {
|
||||
expandedElRef.current = null;
|
||||
}
|
||||
}
|
||||
|
||||
function shortText(s, max = 22) {
|
||||
const t = String(s || "").trim();
|
||||
if (!t) return "Post";
|
||||
return t.length > max ? t.slice(0, max - 3) + "..." : t;
|
||||
/**
|
||||
* Helper: hide/show all markers except one element
|
||||
*/
|
||||
function setOthersVisibility(markersRef, exceptEl, visible) {
|
||||
const list = markersRef.current || [];
|
||||
for (const item of list) {
|
||||
const el = item?.el;
|
||||
if (!el || el === exceptEl) continue;
|
||||
el.style.visibility = visible ? "visible" : "hidden";
|
||||
el.style.pointerEvents = visible ? "auto" : "none";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un marqueur pour un post :
|
||||
* - compact : bulle + pointe
|
||||
* - expanded : carte + pointe
|
||||
* - état compact : petite bulle + pointe
|
||||
* - état étendu : gros post (carte)
|
||||
*
|
||||
* Règles:
|
||||
* - 1 seul post ouvert à la fois
|
||||
* - clic sur la map => ferme (géré dans useMapCore)
|
||||
* - quand un post est ouvert => on cache les autres markers pour éviter les overlaps
|
||||
*/
|
||||
export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
||||
const map = mapRef.current;
|
||||
if (!map) return;
|
||||
|
||||
// --- coordonnées ---
|
||||
const lat =
|
||||
typeof post.lat === "number"
|
||||
? post.lat
|
||||
|
|
@ -48,11 +65,12 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
|||
? post.longitude
|
||||
: null;
|
||||
|
||||
if (lat == null || lon == null) return;
|
||||
if (lat == null || lon == null) {
|
||||
console.warn("post sans coordonnée:", post);
|
||||
return;
|
||||
}
|
||||
|
||||
const title = (post.title || post.Title || "").trim() || "Untitled";
|
||||
const titleShort = shortText(title, 22);
|
||||
|
||||
const body =
|
||||
(post.snippet || post.Snippet || "").trim() ||
|
||||
(post.body || post.Body || "").trim() ||
|
||||
|
|
@ -66,7 +84,6 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
|||
|
||||
const root = document.createElement("div");
|
||||
root.className = "post-pin post-pin--compact";
|
||||
// base z-index (compact)
|
||||
root.style.zIndex = "1";
|
||||
|
||||
function renderCompact() {
|
||||
|
|
@ -75,16 +92,17 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
|||
root.innerHTML = `
|
||||
<div class="post-pin-bubble">
|
||||
<div class="post-pin-dot"></div>
|
||||
<div class="post-pin-text">${escapeHtml(titleShort)}</div>
|
||||
<div class="post-pin-text">${escapeHtml(title)}</div>
|
||||
</div>
|
||||
<div class="post-pin-pointer-small"></div>
|
||||
`;
|
||||
// remettre les autres markers visibles
|
||||
setOthersVisibility(markersRef, root, true);
|
||||
}
|
||||
|
||||
function renderExpanded() {
|
||||
root.className = "post-pin post-pin--expanded";
|
||||
// ALWAYS on top
|
||||
root.style.zIndex = "99999";
|
||||
root.style.zIndex = "999999";
|
||||
root.innerHTML = `
|
||||
<div class="post-card">
|
||||
<div class="post-card-header">
|
||||
|
|
@ -99,15 +117,21 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
|||
|
||||
<div class="post-card-main">
|
||||
<div class="post-card-media">
|
||||
<div class="post-card-media-label">Image / Vidéo</div>
|
||||
<div class="post-card-media-label">
|
||||
Image / Vidéo
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="post-card-info">
|
||||
<div class="post-card-title">${escapeHtml(title)}</div>
|
||||
<div class="post-card-title">
|
||||
${escapeHtml(title)}
|
||||
</div>
|
||||
<div class="post-card-meta">
|
||||
by ${escapeHtml(author)} · lat ${lat.toFixed(3)} · lon ${lon.toFixed(3)}
|
||||
</div>
|
||||
<div class="post-card-body">${escapeHtml(body)}</div>
|
||||
<div class="post-card-body">
|
||||
${escapeHtml(body)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -124,19 +148,17 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
|||
</div>
|
||||
<div class="post-card-pointer"></div>
|
||||
`;
|
||||
|
||||
// cacher les autres markers pendant que celui-ci est ouvert
|
||||
setOthersVisibility(markersRef, root, false);
|
||||
}
|
||||
|
||||
function setExpanded(next) {
|
||||
if (next) renderExpanded();
|
||||
else renderCompact();
|
||||
}
|
||||
|
||||
// expose pour useMapCore (close on map click)
|
||||
root.__setExpanded = setExpanded;
|
||||
|
||||
// état initial
|
||||
// état initial : compact
|
||||
renderCompact();
|
||||
|
||||
// IMPORTANT: garder une ref stable pour useMapCore (clic sur map => ferme)
|
||||
root.__renderCompact = renderCompact;
|
||||
|
||||
const marker = new maplibregl.Marker({
|
||||
element: root,
|
||||
anchor: "bottom",
|
||||
|
|
@ -149,24 +171,27 @@ export function createMarkerForPost(post, mapRef, markersRef, expandedElRef) {
|
|||
root.addEventListener("click", (ev) => {
|
||||
ev.stopPropagation();
|
||||
|
||||
// ferme l'autre expanded
|
||||
// Fermer l'ancien gros post
|
||||
if (expandedElRef.current && expandedElRef.current !== root) {
|
||||
expandedElRef.current.__setExpanded &&
|
||||
expandedElRef.current.__setExpanded(false);
|
||||
if (expandedElRef.current.__renderCompact) {
|
||||
expandedElRef.current.__renderCompact();
|
||||
}
|
||||
expandedElRef.current = null;
|
||||
}
|
||||
|
||||
// Toggle pour ce post
|
||||
const isExpanded = root.classList.contains("post-pin--expanded");
|
||||
if (isExpanded) {
|
||||
setExpanded(false);
|
||||
renderCompact();
|
||||
expandedElRef.current = null;
|
||||
} else {
|
||||
setExpanded(true);
|
||||
renderExpanded();
|
||||
expandedElRef.current = root;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* petite fonction pour éviter d’injecter du HTML sale */
|
||||
function escapeHtml(str) {
|
||||
return String(str)
|
||||
.replace(/&/g, "&")
|
||||
|
|
|
|||
Loading…
Reference in New Issue