mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-09-26 17:08:57 +03:00
Fix explore paging for non-date sorts (#24392)
* fix explore paging for non-date sorts Explore paged every sort by passing the last row's `start_time` as a `before` or `after` cursor, which only works when rows are ordered by `start_time`. For score, speed, and relevance sorts, each page dropped every match newer than that row and repeated older rows from earlier pages, so infinite scroll stopped after a few pages. `/events` and `/events/search` now accept `offset`, and Explore pages non-date sorts by offset. Date sorts keep the cursor because `useSWRInfinite` only revalidates the first page, and cursor keys for later pages follow it while offset keys don't. Score and speed sorts on `/events` break ties on `id` so offset pages stay stable. * order search ties by id and reject negative offsets `/events/search` sorted in Python over a query with no `ORDER BY`, so tied scores, speeds, or distances kept whatever order SQLite returned, which isn't guaranteed to match across page requests. The query is now ordered by id and the stable sorts keep that order for ties. `offset` also accepted negative values, which sliced from the end of the search results.
This commit is contained in:
@@ -198,7 +198,19 @@ export default function Explore() {
|
||||
|
||||
const [url, params] = searchQuery;
|
||||
|
||||
const isAscending = params.sort?.includes("date_asc");
|
||||
// a start_time cursor only works when rows are ordered by start_time,
|
||||
// so every other sort pages by offset
|
||||
const isDateSort =
|
||||
params.sort === "date_asc" ||
|
||||
params.sort === "date_desc" ||
|
||||
(!params.sort && url === "events");
|
||||
|
||||
if (pageIndex > 0 && !isDateSort) {
|
||||
return [
|
||||
url,
|
||||
{ ...params, offset: pageIndex * API_LIMIT, limit: API_LIMIT },
|
||||
];
|
||||
}
|
||||
|
||||
if (pageIndex > 0 && previousPageData) {
|
||||
const lastDate = previousPageData[previousPageData.length - 1].start_time;
|
||||
@@ -206,7 +218,8 @@ export default function Explore() {
|
||||
url,
|
||||
{
|
||||
...params,
|
||||
[isAscending ? "after" : "before"]: lastDate.toString(),
|
||||
[params.sort === "date_asc" ? "after" : "before"]:
|
||||
lastDate.toString(),
|
||||
limit: API_LIMIT,
|
||||
},
|
||||
];
|
||||
@@ -238,10 +251,17 @@ export default function Explore() {
|
||||
},
|
||||
});
|
||||
|
||||
const searchResults = useMemo(
|
||||
() => (data ? ([] as SearchResult[]).concat(...data) : []),
|
||||
[data],
|
||||
);
|
||||
// offset pages can overlap when results shift between page fetches
|
||||
const searchResults = useMemo(() => {
|
||||
if (!data) return [];
|
||||
|
||||
const seen = new Set<string>();
|
||||
return data.flat().filter((result) => {
|
||||
if (seen.has(result.id)) return false;
|
||||
seen.add(result.id);
|
||||
return true;
|
||||
});
|
||||
}, [data]);
|
||||
const isLoadingInitialData = !data && !isValidating;
|
||||
const isLoadingMore =
|
||||
isLoadingInitialData ||
|
||||
|
||||
@@ -109,6 +109,7 @@ export type SearchQueryParams = {
|
||||
max_speed?: number;
|
||||
search_type?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
in_progress?: number;
|
||||
include_thumbnails?: number;
|
||||
query?: string;
|
||||
|
||||
Reference in New Issue
Block a user