Adjust map radius and fetch limits

This commit is contained in:
Your Name 2025-12-29 22:25:59 -05:00
parent a9bc4d02e6
commit 0bd4988ad7
5 changed files with 70 additions and 23 deletions

View File

@ -384,6 +384,9 @@ export async function fetchSmartFeed(params = {}) {
if (typeof params.radius_km === "number") qs.set("radius_km", String(params.radius_km)); if (typeof params.radius_km === "number") qs.set("radius_km", String(params.radius_km));
if (typeof params.limit === "number") qs.set("limit", String(params.limit)); if (typeof params.limit === "number") qs.set("limit", String(params.limit));
if (typeof params.zoom === "number") qs.set("zoom", String(params.zoom)); if (typeof params.zoom === "number") qs.set("zoom", String(params.zoom));
if (params.category) qs.set("category", String(params.category));
if (params.sub_category) qs.set("sub_category", String(params.sub_category));
if (params.time_filter) qs.set("time_filter", String(params.time_filter));
// NEW: Screen bounds for on-screen prioritization // NEW: Screen bounds for on-screen prioritization
if (params.bounds) { if (params.bounds) {

View File

@ -59,12 +59,12 @@ export function matchesTimeFilter(createdAt, timeFilter) {
if (timeFilter === "PAST") return true; if (timeFilter === "PAST") return true;
const d = parseCreatedAt(createdAt); const d = parseCreatedAt(createdAt);
if (!d) return true; if (!d) return false;
const now = Date.now(); const now = Date.now();
const diffMs = now - d.getTime(); const diffMs = now - d.getTime();
if (!Number.isFinite(diffMs)) return true; if (!Number.isFinite(diffMs)) return true;
if (diffMs < 0) return true; if (diffMs < 0) return false;
const diffHours = diffMs / 3600000; const diffHours = diffMs / 3600000;
const diffDays = diffMs / 86400000; const diffDays = diffMs / 86400000;
@ -81,6 +81,19 @@ export function matchesTimeFilter(createdAt, timeFilter) {
} }
} }
export function effectivePostTime(post) {
const published =
post?.published_at ||
post?.publishedAt ||
post?.PublishedAt ||
"";
const d = parseCreatedAt(published);
if (!d) return "";
const now = Date.now();
if (d.getTime() > now + 5 * 60 * 1000) return "";
return published;
}
export function isInViewRadius(post, center, radiusKm) { export function isInViewRadius(post, center, radiusKm) {
if (!center || !radiusKm) return true; if (!center || !radiusKm) return true;
const [lngC, latC] = center; const [lngC, latC] = center;

View File

@ -31,7 +31,7 @@ export function getViewFromMap(map) {
radiusKm = 750; radiusKm = 750;
} }
radiusKm = Math.min(Math.max(radiusKm * 1.2, 25), 1000); radiusKm = Math.min(Math.max(radiusKm * 1.2, 25), 2500);
return { return {
center: [center.lng, center.lat], center: [center.lng, center.lat],

View File

@ -623,13 +623,25 @@ function formatRelativeTime(createdAt) {
} }
function getPostTime(post) { function getPostTime(post) {
return ( const published =
post?.published_at || post?.published_at ||
post?.publishedAt || post?.publishedAt ||
post?.PublishedAt || post?.PublishedAt ||
"";
if (published) {
const d = new Date(String(published));
if (!Number.isNaN(d.getTime())) {
const now = Date.now();
if (d.getTime() <= now + 5 * 60 * 1000) {
return published;
}
}
}
return (
post?.created_at || post?.created_at ||
post?.CreatedAt || post?.CreatedAt ||
post?.createdAt post?.createdAt ||
published
); );
} }

View File

@ -1,6 +1,6 @@
import { useCallback, useEffect, useRef, useState } from "react"; import { useCallback, useEffect, useRef, useState } from "react";
import { fetchPosts, fetchSmartFeed, fetchUnifiedSearch } from "../../api/client"; import { fetchPosts, fetchSmartFeed, fetchUnifiedSearch } from "../../api/client";
import { categoryCode, matchesSubFilter, matchesTimeFilter } from "./mapFilter"; import { categoryCode, matchesSubFilter, matchesTimeFilter, effectivePostTime } from "./mapFilter";
import { getCoords, getViewFromMap, haversineKm } from "./mapGeo"; import { getCoords, getViewFromMap, haversineKm } from "./mapGeo";
import { createMarkerForPost, createSimpleMarkerForPost } from "./markerManager"; import { createMarkerForPost, createSimpleMarkerForPost } from "./markerManager";
import { getTemplateKeyForPost } from "./templateSpecs"; import { getTemplateKeyForPost } from "./templateSpecs";
@ -277,7 +277,7 @@ function buildClusterAreaFeatures(posts) {
return features; return features;
} }
const MAX_POOL_POSTS = 75; const MAX_POOL_POSTS = 160;
const MAX_VISIBLE_POSTS = 45; const MAX_VISIBLE_POSTS = 45;
function prunePosts(posts, center, maxCount) { function prunePosts(posts, center, maxCount) {
@ -326,6 +326,7 @@ export function usePostsEngine({
const initialFetchKickRef = useRef(false); const initialFetchKickRef = useRef(false);
const autoWidenRef = useRef(false); const autoWidenRef = useRef(false);
const searchResultsRef = useRef(false); const searchResultsRef = useRef(false);
const replacePoolRef = useRef(false);
const retryRef = useRef({ key: "", count: 0, ts: 0 }); const retryRef = useRef({ key: "", count: 0, ts: 0 });
const [mapReady, setMapReady] = useState(false); const [mapReady, setMapReady] = useState(false);
const clusterModeRef = useRef(false); const clusterModeRef = useRef(false);
@ -370,6 +371,14 @@ export function usePostsEngine({
}, 120); }, 120);
}, [mapReady, mapRef]); }, [mapReady, mapRef]);
useEffect(() => {
const map = mapRef.current;
replacePoolRef.current = true;
if (map) {
map.__swForceFetchAt = Date.now();
}
}, [mainFilter, subFilter, timeFilter, mapRef]);
const priorityOpts = { const priorityOpts = {
maxFullCards: 15, maxFullCards: 15,
clusterRadius: 0.002, clusterRadius: 0.002,
@ -667,18 +676,13 @@ export function usePostsEngine({
const searchActive = (searchQuery || "").trim().length > 0; const searchActive = (searchQuery || "").trim().length > 0;
let fullCardPosts = []; let fullCardPosts = [];
let simpleMarkerPosts = []; let simpleMarkerPosts = [];
if (searchActive) { const prioritized = prioritizePosts(visible, viewCenter, {
fullCardPosts = visible || []; maxFullCards: 15, // 10-15 cartes complètes selon le zoom
simpleMarkerPosts = []; clusterRadius: 0.002, // ~200m clustering radius (augmenté pour plus de groupement)
} else { minScoreForCard: 50, // Score minimum pour carte complète (augmenté de 35 à 50)
const prioritized = prioritizePosts(visible, viewCenter, { });
maxFullCards: 15, // 10-15 cartes complètes selon le zoom fullCardPosts = prioritized.fullCardPosts;
clusterRadius: 0.002, // ~200m clustering radius (augmenté pour plus de groupement) simpleMarkerPosts = prioritized.simpleMarkerPosts;
minScoreForCard: 50, // Score minimum pour carte complète (augmenté de 35 à 50)
});
fullCardPosts = prioritized.fullCardPosts;
simpleMarkerPosts = prioritized.simpleMarkerPosts;
}
console.log('[usePostsEngine] Prioritized:', { console.log('[usePostsEngine] Prioritized:', {
total: visible.length, total: visible.length,
@ -792,7 +796,7 @@ export function usePostsEngine({
if (pc !== catCode) return false; if (pc !== catCode) return false;
} }
if (!matchesSubFilter(p, subFilter)) return false; if (!matchesSubFilter(p, subFilter)) return false;
if (!matchesTimeFilter(p.created_at || p.CreatedAt || p.createdAt, tf)) return false; if (!matchesTimeFilter(effectivePostTime(p), tf)) return false;
if (!searchResultsRef.current && !matchesSearch(p, searchQuery)) return false; if (!searchResultsRef.current && !matchesSearch(p, searchQuery)) return false;
return true; return true;
}); });
@ -960,19 +964,33 @@ export function usePostsEngine({
// Use smart feed for personalized, trending posts // Use smart feed for personalized, trending posts
const zoom = typeof mapObj?.getZoom === "function" ? mapObj.getZoom() : undefined; const zoom = typeof mapObj?.getZoom === "function" ? mapObj.getZoom() : undefined;
let limit = 50;
if (typeof zoom === "number") {
if (zoom <= 6) limit = 90;
else if (zoom <= 8) limit = 70;
else if (zoom <= 10) limit = 60;
}
if (radiusKm > 800) {
limit = Math.max(limit, 80);
}
if (limit > 120) limit = 120;
let newPosts = await fetchSmartFeed({ let newPosts = await fetchSmartFeed({
lat, lat,
lon: lng, lon: lng,
radius_km: radiusKm, radius_km: radiusKm,
limit: 50, limit,
zoom, zoom,
bounds, bounds,
username: username || undefined, username: username || undefined,
time_filter: timeFilter || undefined,
category: catCode || undefined,
sub_category: subCatParam || undefined,
}); });
if (cancelled) return; if (cancelled) return;
const existing = allPostsRef.current || []; const existing = replacePoolRef.current ? [] : allPostsRef.current || [];
const byId = new Map(); const byId = new Map();
for (const p of existing) { for (const p of existing) {
const normalized = normalizePostId(p); const normalized = normalizePostId(p);
@ -994,6 +1012,7 @@ export function usePostsEngine({
} }
allPostsRef.current = prunePosts(Array.from(byId.values()), [lng, lat], MAX_POOL_POSTS); allPostsRef.current = prunePosts(Array.from(byId.values()), [lng, lat], MAX_POOL_POSTS);
replacePoolRef.current = false;
lastFetchRef.current = { center: [...resolvedView.center], radiusKm, filterKey, timeFilter, bounds }; lastFetchRef.current = { center: [...resolvedView.center], radiusKm, filterKey, timeFilter, bounds };
// Smooth update: sync markers/clusters + wall without clearing everything // Smooth update: sync markers/clusters + wall without clearing everything
@ -1145,7 +1164,7 @@ export function usePostsEngine({
if (pc !== catCode) return; if (pc !== catCode) return;
} }
if (!matchesSubFilter(p, subFilter)) return; if (!matchesSubFilter(p, subFilter)) return;
if (!matchesTimeFilter(p.created_at || p.CreatedAt || p.createdAt, timeFilter)) return; if (!matchesTimeFilter(effectivePostTime(p), timeFilter)) return;
if (!matchesSearch(p, searchQuery)) return; if (!matchesSearch(p, searchQuery)) return;
if (clusterModeRef.current) { if (clusterModeRef.current) {