update frontend

This commit is contained in:
Your Name 2025-12-13 02:51:04 -05:00
parent e113123cca
commit 9c5de18421
3 changed files with 63 additions and 18 deletions

View File

@ -19,11 +19,17 @@ export function getViewFromMap(map) {
const bounds = map.getBounds(); const bounds = map.getBounds();
const center = bounds.getCenter(); const center = bounds.getCenter();
const ne = bounds.getNorthEast(); const ne = bounds.getNorthEast();
let radiusKm = haversineKm(center.lat, center.lng, ne.lat, ne.lng); let radiusKm = haversineKm(center.lat, center.lng, ne.lat, ne.lng);
// si calcul weird
if (!Number.isFinite(radiusKm) || radiusKm <= 0) { if (!Number.isFinite(radiusKm) || radiusKm <= 0) {
radiusKm = 250; radiusKm = 750; // ✅ fallback plus large
} }
radiusKm = Math.min(Math.max(radiusKm, 10), 1000); // clamp 101000 km
// clamp (si ton backend limite à 1000, mets 1000 ici)
radiusKm = Math.min(Math.max(radiusKm, 25), 1500);
return { return {
center: [center.lng, center.lat], center: [center.lng, center.lat],
radiusKm, radiusKm,

View File

@ -4,6 +4,7 @@ import { LAST_VIEW_KEY } from "./mapConfig";
import { getViewFromMap } from "./mapGeo"; import { getViewFromMap } from "./mapGeo";
import { clearAllMarkers, applyOcclusionForExpanded } from "./markerManager"; import { clearAllMarkers, applyOcclusionForExpanded } from "./markerManager";
// renvoie le style MapLibre en fonction du thème
function getBaseStyle(theme) { function getBaseStyle(theme) {
const t = theme || "dark"; const t = theme || "dark";
let tiles; let tiles;
@ -31,7 +32,13 @@ function getBaseStyle(theme) {
attribution: "© OpenStreetMap contributors © CARTO", 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 markersRef = useRef([]);
const expandedElRef = useRef(null); 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); const [hasLastView, setHasLastView] = useState(false);
function closeExpandedIfAny() { function closeExpandedIfAny() {
const el = expandedElRef.current; const el = expandedElRef.current;
if (el && el.__renderCompact) { if (el && el.__setExpanded) {
el.__renderCompact(); el.__setExpanded(false);
} }
expandedElRef.current = null; expandedElRef.current = null;
} }
@ -66,7 +77,7 @@ export function useMapCore(theme) {
antialias: true, antialias: true,
}); });
// restore last view // Reprise dernière vue
let hadLastView = false; let hadLastView = false;
try { try {
const raw = localStorage.getItem(LAST_VIEW_KEY); const raw = localStorage.getItem(LAST_VIEW_KEY);
@ -88,7 +99,7 @@ export function useMapCore(theme) {
map.addControl(new maplibregl.NavigationControl(), "top-right"); map.addControl(new maplibregl.NavigationControl(), "top-right");
mapRef.current = map; 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 reOcclude = () => {
const el = expandedElRef.current; const el = expandedElRef.current;
if (el) applyOcclusionForExpanded(markersRef, el); if (el) applyOcclusionForExpanded(markersRef, el);
@ -96,8 +107,18 @@ export function useMapCore(theme) {
map.on("move", reOcclude); map.on("move", reOcclude);
map.on("zoom", 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", () => { map.on("load", () => {
setViewParams(getViewFromMap(map)); const vp = getViewFromMap(map);
setViewParams(vp);
}); });
map.on("moveend", () => { map.on("moveend", () => {
@ -107,12 +128,16 @@ export function useMapCore(theme) {
const center = vp.center; const center = vp.center;
localStorage.setItem( localStorage.setItem(
LAST_VIEW_KEY, 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 {} } catch {}
}); });
// ✅ close expanded when clicking/dragging map // IMPORTANT: click/drag sur la map => fermer le gros post
map.on("click", () => closeExpandedIfAny()); map.on("click", () => closeExpandedIfAny());
map.on("dragstart", () => closeExpandedIfAny()); map.on("dragstart", () => closeExpandedIfAny());
@ -124,7 +149,6 @@ export function useMapCore(theme) {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
// theme switch
useEffect(() => { useEffect(() => {
const map = mapRef.current; const map = mapRef.current;
if (!map) return; if (!map) return;
@ -139,4 +163,4 @@ export function useMapCore(theme) {
viewParams, viewParams,
hasLastView, hasLastView,
}; };
} }

View File

@ -70,7 +70,7 @@ export function usePostsEngine({
rebuildMarkersForFilters(timeFilter); rebuildMarkersForFilters(timeFilter);
}, [timeFilter, mainFilter, subFilter, rebuildMarkersForFilters]); }, [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(() => { useEffect(() => {
const map = mapRef.current; const map = mapRef.current;
if (!map) return; if (!map) return;
@ -80,7 +80,7 @@ export function usePostsEngine({
async function load() { async function load() {
const [lng, lat] = viewParams.center; const [lng, lat] = viewParams.center;
const radiusKm = viewParams.radiusKm || 250; const radiusKm = viewParams.radiusKm || 750;
const filterKey = `${mainFilter}|${subFilter}`; const filterKey = `${mainFilter}|${subFilter}`;
const last = lastFetchRef.current; const last = lastFetchRef.current;
@ -89,8 +89,16 @@ export function usePostsEngine({
const [lastLng, lastLat] = last.center; const [lastLng, lastLat] = last.center;
const distKm = haversineKm(lastLat, lastLng, viewParams.center[1], lng); const distKm = haversineKm(lastLat, lastLng, viewParams.center[1], lng);
const minMoveKm = Math.max(100, radiusKm * 0.4); // ✅ refetch si le radius change pas mal (zoom in/out)
if (distKm < minMoveKm) { 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; return;
} }
} }
@ -160,7 +168,14 @@ export function usePostsEngine({
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [viewParams, mainFilter, subFilter, mapRef, rebuildMarkersForFilters, timeFilter]); }, [
viewParams,
mainFilter,
subFilter,
mapRef,
rebuildMarkersForFilters,
timeFilter,
]);
// Nouveau post reçu via WebSocket // Nouveau post reçu via WebSocket
const handleIncomingPost = useCallback( const handleIncomingPost = useCallback(