From 9c5de184213da3a1256a7b63e428292a4bb6de77 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sat, 13 Dec 2025 02:51:04 -0500 Subject: [PATCH] update frontend --- src/components/Map/mapGeo.js | 10 ++++-- src/components/Map/useMapCore.js | 46 +++++++++++++++++++++------- src/components/Map/usePostsEngine.js | 25 ++++++++++++--- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/components/Map/mapGeo.js b/src/components/Map/mapGeo.js index ee37712..9b8a805 100644 --- a/src/components/Map/mapGeo.js +++ b/src/components/Map/mapGeo.js @@ -19,11 +19,17 @@ export function getViewFromMap(map) { const bounds = map.getBounds(); const center = bounds.getCenter(); const ne = bounds.getNorthEast(); + let radiusKm = haversineKm(center.lat, center.lng, ne.lat, ne.lng); + + // si calcul weird if (!Number.isFinite(radiusKm) || radiusKm <= 0) { - radiusKm = 250; + radiusKm = 750; // ✅ fallback plus large } - radiusKm = Math.min(Math.max(radiusKm, 10), 1000); // clamp 10–1000 km + + // clamp (si ton backend limite à 1000, mets 1000 ici) + radiusKm = Math.min(Math.max(radiusKm, 25), 1500); + return { center: [center.lng, center.lat], radiusKm, diff --git a/src/components/Map/useMapCore.js b/src/components/Map/useMapCore.js index 166546c..7261fed 100644 --- a/src/components/Map/useMapCore.js +++ b/src/components/Map/useMapCore.js @@ -4,6 +4,7 @@ import { LAST_VIEW_KEY } from "./mapConfig"; import { getViewFromMap } from "./mapGeo"; import { clearAllMarkers, applyOcclusionForExpanded } from "./markerManager"; +// renvoie le style MapLibre en fonction du thème function getBaseStyle(theme) { const t = theme || "dark"; let tiles; @@ -31,7 +32,13 @@ function getBaseStyle(theme) { attribution: "© OpenStreetMap contributors © CARTO", }, }, - layers: [{ id: "carto-base-layer", type: "raster", source: "carto-base" }], + layers: [ + { + id: "carto-base-layer", + type: "raster", + source: "carto-base", + }, + ], }; } @@ -42,13 +49,17 @@ export function useMapCore(theme) { const markersRef = useRef([]); const expandedElRef = useRef(null); - const [viewParams, setViewParams] = useState({ center: null, radiusKm: 250 }); + // ✅ default plus large + const [viewParams, setViewParams] = useState({ + center: null, + radiusKm: 750, + }); const [hasLastView, setHasLastView] = useState(false); function closeExpandedIfAny() { const el = expandedElRef.current; - if (el && el.__renderCompact) { - el.__renderCompact(); + if (el && el.__setExpanded) { + el.__setExpanded(false); } expandedElRef.current = null; } @@ -66,7 +77,7 @@ export function useMapCore(theme) { antialias: true, }); - // restore last view + // Reprise dernière vue let hadLastView = false; try { const raw = localStorage.getItem(LAST_VIEW_KEY); @@ -88,7 +99,7 @@ export function useMapCore(theme) { map.addControl(new maplibregl.NavigationControl(), "top-right"); mapRef.current = map; - // re-apply occlusion during move/zoom (only hides below overlapping ones) + // If a post is expanded, re-apply occlusion on zoom/move (only hides overlapping ones) const reOcclude = () => { const el = expandedElRef.current; if (el) applyOcclusionForExpanded(markersRef, el); @@ -96,8 +107,18 @@ export function useMapCore(theme) { map.on("move", reOcclude); map.on("zoom", reOcclude); + // Close expanded post when clicking on the map (outside markers) + map.on("click", () => { + const el = expandedElRef.current; + if (el && el.__renderCompact) { + el.__renderCompact(); + expandedElRef.current = null; + } + }); + map.on("load", () => { - setViewParams(getViewFromMap(map)); + const vp = getViewFromMap(map); + setViewParams(vp); }); map.on("moveend", () => { @@ -107,12 +128,16 @@ export function useMapCore(theme) { const center = vp.center; localStorage.setItem( LAST_VIEW_KEY, - JSON.stringify({ lat: center[1], lon: center[0], zoom: map.getZoom() }) + JSON.stringify({ + lat: center[1], + lon: center[0], + zoom: map.getZoom(), + }) ); } catch {} }); - // ✅ close expanded when clicking/dragging map + // IMPORTANT: click/drag sur la map => fermer le gros post map.on("click", () => closeExpandedIfAny()); map.on("dragstart", () => closeExpandedIfAny()); @@ -124,7 +149,6 @@ export function useMapCore(theme) { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - // theme switch useEffect(() => { const map = mapRef.current; if (!map) return; @@ -139,4 +163,4 @@ export function useMapCore(theme) { viewParams, hasLastView, }; -} \ No newline at end of file +} diff --git a/src/components/Map/usePostsEngine.js b/src/components/Map/usePostsEngine.js index 985448d..2e15616 100644 --- a/src/components/Map/usePostsEngine.js +++ b/src/components/Map/usePostsEngine.js @@ -70,7 +70,7 @@ export function usePostsEngine({ rebuildMarkersForFilters(timeFilter); }, [timeFilter, mainFilter, subFilter, rebuildMarkersForFilters]); - // Fetch backend quand la vue bouge assez + // Fetch backend quand la vue bouge assez (OU quand le zoom change beaucoup le radius) useEffect(() => { const map = mapRef.current; if (!map) return; @@ -80,7 +80,7 @@ export function usePostsEngine({ async function load() { const [lng, lat] = viewParams.center; - const radiusKm = viewParams.radiusKm || 250; + const radiusKm = viewParams.radiusKm || 750; const filterKey = `${mainFilter}|${subFilter}`; const last = lastFetchRef.current; @@ -89,8 +89,16 @@ export function usePostsEngine({ const [lastLng, lastLat] = last.center; const distKm = haversineKm(lastLat, lastLng, viewParams.center[1], lng); - const minMoveKm = Math.max(100, radiusKm * 0.4); - if (distKm < minMoveKm) { + // ✅ refetch si le radius change pas mal (zoom in/out) + const lastR = last.radiusKm || 0; + const radiusChanged = + !lastR || Math.abs(radiusKm - lastR) / Math.max(lastR, 1) >= 0.25; // 25% + + // move threshold moins agressif + const minMoveKm = Math.max(50, radiusKm * 0.25); + + // Si ni zoom ni move significatif => skip + if (!radiusChanged && distKm < minMoveKm) { return; } } @@ -160,7 +168,14 @@ export function usePostsEngine({ return () => { cancelled = true; }; - }, [viewParams, mainFilter, subFilter, mapRef, rebuildMarkersForFilters, timeFilter]); + }, [ + viewParams, + mainFilter, + subFilter, + mapRef, + rebuildMarkersForFilters, + timeFilter, + ]); // Nouveau post reçu via WebSocket const handleIncomingPost = useCallback(