Cap smart feed results and add search fetch
This commit is contained in:
parent
80b266ca56
commit
40b1924a77
|
|
@ -1,5 +1,5 @@
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import { fetchPosts, fetchSmartFeed } from "../../api/client";
|
import { fetchPosts, fetchSmartFeed, fetchUnifiedSearch } from "../../api/client";
|
||||||
import { categoryCode, matchesSubFilter, matchesTimeFilter } from "./mapFilter";
|
import { categoryCode, matchesSubFilter, matchesTimeFilter } from "./mapFilter";
|
||||||
import { getCoords, getViewFromMap, haversineKm } from "./mapGeo";
|
import { getCoords, getViewFromMap, haversineKm } from "./mapGeo";
|
||||||
import { createMarkerForPost, createSimpleMarkerForPost } from "./markerManager";
|
import { createMarkerForPost, createSimpleMarkerForPost } from "./markerManager";
|
||||||
|
|
@ -105,6 +105,32 @@ function filterByBounds(posts, map) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPostTimeMs(p) {
|
||||||
|
const raw = p?.created_at || p?.CreatedAt || p?.createdAt || p?.published_at;
|
||||||
|
if (!raw) return 0;
|
||||||
|
const d = raw instanceof Date ? raw : new Date(String(raw));
|
||||||
|
if (Number.isNaN(d.getTime())) return 0;
|
||||||
|
return d.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
function prunePosts(posts, center, maxCount) {
|
||||||
|
if (!Array.isArray(posts) || posts.length <= maxCount) return posts || [];
|
||||||
|
const [centerLon, centerLat] = center || [];
|
||||||
|
const now = Date.now();
|
||||||
|
const scored = posts.map((p) => {
|
||||||
|
const coords = getCoords(p);
|
||||||
|
let dist = 99999;
|
||||||
|
if (coords && Number.isFinite(centerLat) && Number.isFinite(centerLon)) {
|
||||||
|
dist = haversineKm(centerLat, centerLon, coords[1], coords[0]);
|
||||||
|
}
|
||||||
|
const ageH = Math.max(0, (now - getPostTimeMs(p)) / 3600000);
|
||||||
|
const score = dist + ageH * 0.4;
|
||||||
|
return { p, score };
|
||||||
|
});
|
||||||
|
scored.sort((a, b) => a.score - b.score);
|
||||||
|
return scored.slice(0, maxCount).map((x) => x.p);
|
||||||
|
}
|
||||||
|
|
||||||
export function usePostsEngine({
|
export function usePostsEngine({
|
||||||
mapRef,
|
mapRef,
|
||||||
viewParams,
|
viewParams,
|
||||||
|
|
@ -541,6 +567,7 @@ export function usePostsEngine({
|
||||||
const resolvedView =
|
const resolvedView =
|
||||||
viewParams && viewParams.center ? viewParams : getViewFromMap(mapObj);
|
viewParams && viewParams.center ? viewParams : getViewFromMap(mapObj);
|
||||||
if (!resolvedView?.center) return;
|
if (!resolvedView?.center) return;
|
||||||
|
if ((searchQuery || "").trim()) return;
|
||||||
|
|
||||||
// If expanded overlay is open: delay fetch (do NOT disturb UI)
|
// If expanded overlay is open: delay fetch (do NOT disturb UI)
|
||||||
if (expandedElRef?.current) {
|
if (expandedElRef?.current) {
|
||||||
|
|
@ -621,7 +648,7 @@ export function usePostsEngine({
|
||||||
lat,
|
lat,
|
||||||
lon: lng,
|
lon: lng,
|
||||||
radius_km: radiusKm,
|
radius_km: radiusKm,
|
||||||
limit: 80,
|
limit: 50,
|
||||||
bounds,
|
bounds,
|
||||||
username: username || undefined,
|
username: username || undefined,
|
||||||
});
|
});
|
||||||
|
|
@ -662,7 +689,7 @@ export function usePostsEngine({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allPostsRef.current = Array.from(byId.values());
|
allPostsRef.current = prunePosts(Array.from(byId.values()), [lng, lat], 180);
|
||||||
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
|
||||||
|
|
@ -698,6 +725,41 @@ export function usePostsEngine({
|
||||||
};
|
};
|
||||||
}, [viewParams, mapReady, mainFilter, subFilter, mapRef, timeFilter, expandedElRef, refreshVisibleAndMarkers, computeVisible, onAutoWidenTimeFilter, syncMarkers, username]);
|
}, [viewParams, mapReady, mainFilter, subFilter, mapRef, timeFilter, expandedElRef, refreshVisibleAndMarkers, computeVisible, onAutoWidenTimeFilter, syncMarkers, username]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const q = (searchQuery || "").trim();
|
||||||
|
if (!q) return;
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
async function runSearch() {
|
||||||
|
try {
|
||||||
|
const map = mapRef.current;
|
||||||
|
let lat;
|
||||||
|
let lon;
|
||||||
|
try {
|
||||||
|
const center = map?.getCenter?.();
|
||||||
|
lat = center?.lat;
|
||||||
|
lon = center?.lng;
|
||||||
|
} catch {}
|
||||||
|
const data = await fetchUnifiedSearch(q, {
|
||||||
|
type: "posts",
|
||||||
|
lat,
|
||||||
|
lon,
|
||||||
|
radius_km: viewParams?.radiusKm,
|
||||||
|
limit: 80,
|
||||||
|
});
|
||||||
|
if (cancelled) return;
|
||||||
|
const posts = Array.isArray(data?.posts) ? data.posts : [];
|
||||||
|
allPostsRef.current = prunePosts(posts, [lon, lat], 120);
|
||||||
|
refreshVisibleAndMarkers(timeFilter);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
runSearch();
|
||||||
|
return () => {
|
||||||
|
cancelled = true;
|
||||||
|
};
|
||||||
|
}, [searchQuery, viewParams, mapRef, refreshVisibleAndMarkers, timeFilter]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
if (!map) return;
|
if (!map) return;
|
||||||
|
|
@ -720,7 +782,9 @@ export function usePostsEngine({
|
||||||
const exists = (allPostsRef.current || []).some((x) => getPostKey(x) === key);
|
const exists = (allPostsRef.current || []).some((x) => getPostKey(x) === key);
|
||||||
if (exists) return;
|
if (exists) return;
|
||||||
}
|
}
|
||||||
allPostsRef.current = [p, ...allPostsRef.current];
|
const map = mapRef.current;
|
||||||
|
const center = map?.getCenter?.();
|
||||||
|
allPostsRef.current = prunePosts([p, ...allPostsRef.current], [center?.lng, center?.lat], 200);
|
||||||
|
|
||||||
const catCode = categoryCode(mainFilter);
|
const catCode = categoryCode(mainFilter);
|
||||||
if (catCode) {
|
if (catCode) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue