Auto deploy: 2025-12-09 03:38:30
This commit is contained in:
parent
71368d4a5e
commit
c755c0c9c0
|
|
@ -100,7 +100,7 @@ const CATEGORY_MAP = {
|
||||||
export default function MapView() {
|
export default function MapView() {
|
||||||
const containerRef = useRef(null);
|
const containerRef = useRef(null);
|
||||||
const mapRef = useRef(null);
|
const mapRef = useRef(null);
|
||||||
const markersRef = useRef([]);
|
const markersRef = useRef([]); // [{ id, marker, el, compactHTML, expandedHTML }]
|
||||||
const expandedElRef = useRef(null);
|
const expandedElRef = useRef(null);
|
||||||
|
|
||||||
const [status, setStatus] = useState("Loading posts...");
|
const [status, setStatus] = useState("Loading posts...");
|
||||||
|
|
@ -110,7 +110,6 @@ export default function MapView() {
|
||||||
const [subFilter, setSubFilter] = useState(null); // sous-catégorie du bas
|
const [subFilter, setSubFilter] = useState(null); // sous-catégorie du bas
|
||||||
|
|
||||||
const [userPosition, setUserPosition] = useState(null); // [lng, lat]
|
const [userPosition, setUserPosition] = useState(null); // [lng, lat]
|
||||||
const [reloadToken, setReloadToken] = useState(0);
|
|
||||||
|
|
||||||
const [viewParams, setViewParams] = useState({
|
const [viewParams, setViewParams] = useState({
|
||||||
center: null,
|
center: null,
|
||||||
|
|
@ -307,44 +306,22 @@ export default function MapView() {
|
||||||
}
|
}
|
||||||
}, [mainFilter, bottomCategories, subFilter]);
|
}, [mainFilter, bottomCategories, subFilter]);
|
||||||
|
|
||||||
/* ------------ LOAD POSTS POUR LA ZONE COURANTE + FILTRES -------------- */
|
/* ------------ FACTEUR EN COMMUN: CREATION D'UN MARKER POUR UN POST -------------- */
|
||||||
useEffect(() => {
|
const createMarkerForPost = (post) => {
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
if (!map) return;
|
if (!map) return;
|
||||||
if (!viewParams.center) return;
|
|
||||||
|
|
||||||
let cancelled = false;
|
|
||||||
|
|
||||||
async function load() {
|
|
||||||
try {
|
|
||||||
setStatus("Loading posts...");
|
|
||||||
|
|
||||||
const [lng, lat] = viewParams.center;
|
|
||||||
const radiusKm = viewParams.radiusKm || 250;
|
|
||||||
|
|
||||||
const catCode = categoryCode(mainFilter);
|
|
||||||
const subCatParam =
|
|
||||||
subFilter && subFilter.toUpperCase() !== "ALL" ? subFilter : "";
|
|
||||||
|
|
||||||
const posts = await fetchPosts({
|
|
||||||
category: catCode,
|
|
||||||
subCategory: subCatParam,
|
|
||||||
time: timeFilter,
|
|
||||||
lat,
|
|
||||||
lon: lng,
|
|
||||||
radiusKm,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (cancelled) return;
|
|
||||||
|
|
||||||
markersRef.current.forEach((m) => m.marker.remove());
|
|
||||||
markersRef.current = [];
|
|
||||||
expandedElRef.current = null;
|
|
||||||
|
|
||||||
posts.forEach((post) => {
|
|
||||||
const coords = getCoords(post);
|
const coords = getCoords(post);
|
||||||
if (!coords) return;
|
if (!coords) return;
|
||||||
|
|
||||||
|
// évite les doublons (même id déjà affiché)
|
||||||
|
if (
|
||||||
|
typeof post.id === "number" &&
|
||||||
|
markersRef.current.some((m) => m.id === post.id)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const [lngP, latP] = coords;
|
const [lngP, latP] = coords;
|
||||||
if (
|
if (
|
||||||
typeof lngP !== "number" ||
|
typeof lngP !== "number" ||
|
||||||
|
|
@ -387,7 +364,13 @@ export default function MapView() {
|
||||||
.setLngLat(coords)
|
.setLngLat(coords)
|
||||||
.addTo(map);
|
.addTo(map);
|
||||||
|
|
||||||
const meta = { marker, el, compactHTML, expandedHTML };
|
const meta = {
|
||||||
|
id: post.id ?? null,
|
||||||
|
marker,
|
||||||
|
el,
|
||||||
|
compactHTML,
|
||||||
|
expandedHTML,
|
||||||
|
};
|
||||||
markersRef.current.push(meta);
|
markersRef.current.push(meta);
|
||||||
|
|
||||||
const toggle = () => {
|
const toggle = () => {
|
||||||
|
|
@ -417,6 +400,45 @@ export default function MapView() {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
toggle();
|
toggle();
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ------------ LOAD POSTS POUR LA ZONE COURANTE + FILTRES -------------- */
|
||||||
|
useEffect(() => {
|
||||||
|
const map = mapRef.current;
|
||||||
|
if (!map) return;
|
||||||
|
if (!viewParams.center) return;
|
||||||
|
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
async function load() {
|
||||||
|
try {
|
||||||
|
setStatus("Loading posts...");
|
||||||
|
|
||||||
|
const [lng, lat] = viewParams.center;
|
||||||
|
const radiusKm = viewParams.radiusKm || 250;
|
||||||
|
|
||||||
|
const catCode = categoryCode(mainFilter);
|
||||||
|
const subCatParam =
|
||||||
|
subFilter && subFilter.toUpperCase() !== "ALL" ? subFilter : "";
|
||||||
|
|
||||||
|
const posts = await fetchPosts({
|
||||||
|
category: catCode,
|
||||||
|
subCategory: subCatParam,
|
||||||
|
time: timeFilter,
|
||||||
|
lat,
|
||||||
|
lon: lng,
|
||||||
|
radiusKm,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cancelled) return;
|
||||||
|
|
||||||
|
// ici on recharge la vue => on enlève tout puis on remet
|
||||||
|
markersRef.current.forEach((m) => m.marker.remove());
|
||||||
|
markersRef.current = [];
|
||||||
|
expandedElRef.current = null;
|
||||||
|
|
||||||
|
posts.forEach((post) => {
|
||||||
|
createMarkerForPost(post);
|
||||||
});
|
});
|
||||||
|
|
||||||
setStatus(posts.length ? "" : "No posts found.");
|
setStatus(posts.length ? "" : "No posts found.");
|
||||||
|
|
@ -431,9 +453,9 @@ export default function MapView() {
|
||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
};
|
};
|
||||||
}, [viewParams, mainFilter, timeFilter, subFilter, reloadToken]);
|
}, [viewParams, mainFilter, timeFilter, subFilter]);
|
||||||
|
|
||||||
/* ------------ WEBSOCKET : RELOAD SUR new_post -------------- */
|
/* ------------ WEBSOCKET : AJOUTER JUSTE LE NOUVEAU POST -------------- */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const proto = window.location.protocol === "https:" ? "wss" : "ws";
|
const proto = window.location.protocol === "https:" ? "wss" : "ws";
|
||||||
const host =
|
const host =
|
||||||
|
|
@ -454,10 +476,35 @@ export default function MapView() {
|
||||||
ws.onmessage = (ev) => {
|
ws.onmessage = (ev) => {
|
||||||
try {
|
try {
|
||||||
const msg = JSON.parse(ev.data);
|
const msg = JSON.parse(ev.data);
|
||||||
if (msg.type === "new_post") {
|
if (msg.type === "new_post" && msg.post) {
|
||||||
setReloadToken((n) => n + 1);
|
const p = msg.post;
|
||||||
|
|
||||||
|
// Optionnel: respecter les filtres actuels
|
||||||
|
const catCode = categoryCode(mainFilter);
|
||||||
|
if (catCode && p.category && p.category.toUpperCase() !== catCode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Position: ne l'afficher que s'il est dans le rayon courant
|
||||||
|
if (viewParams.center && viewParams.radiusKm) {
|
||||||
|
const coords = getCoords(p);
|
||||||
|
if (coords) {
|
||||||
|
const [lngP, latP] = coords;
|
||||||
|
const [lngC, latC] = viewParams.center;
|
||||||
|
const dKm = haversineKm(latC, lngC, latP, lngP);
|
||||||
|
if (dKm > viewParams.radiusKm * 1.2) {
|
||||||
|
// trop loin de la vue actuelle → on ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On ajoute juste ce post, sans effacer les autres
|
||||||
|
createMarkerForPost(p);
|
||||||
|
}
|
||||||
|
} catch (_) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
} catch (_) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onerror = (e) => {
|
ws.onerror = (e) => {
|
||||||
|
|
@ -469,7 +516,7 @@ export default function MapView() {
|
||||||
ws.close();
|
ws.close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, []);
|
}, [mainFilter, viewParams]);
|
||||||
|
|
||||||
/* ------------ ACTIONS UI -------------- */
|
/* ------------ ACTIONS UI -------------- */
|
||||||
|
|
||||||
|
|
@ -479,7 +526,7 @@ export default function MapView() {
|
||||||
map.flyTo({
|
map.flyTo({
|
||||||
center: userPosition,
|
center: userPosition,
|
||||||
zoom: 9,
|
zoom: 9,
|
||||||
speed: 1.1,
|
speed: 1.2,
|
||||||
curve: 1.5,
|
curve: 1.5,
|
||||||
essential: true,
|
essential: true,
|
||||||
});
|
});
|
||||||
|
|
@ -550,7 +597,7 @@ export default function MapView() {
|
||||||
await createPost(payload);
|
await createPost(payload);
|
||||||
setIsSaving(false);
|
setIsSaving(false);
|
||||||
setIsCreating(false);
|
setIsCreating(false);
|
||||||
setReloadToken((n) => n + 1);
|
// On ne refetch pas tout ici, on laisse le WS rajouter le nouveau
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("createPost error:", e);
|
console.error("createPost error:", e);
|
||||||
setIsSaving(false);
|
setIsSaving(false);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue