update frontend
This commit is contained in:
parent
e113123cca
commit
9c5de18421
|
|
@ -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 10–1000 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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue