fix(search): apply the date range to server results client-side
from_ts/to_ts are not Matrix filter fields; the server dropped them, so the range only worked for the local encrypted-room search. Stop sending them and post-filter server results by origin_server_ts with the same inclusive predicate. Unit-tested; docs corrected. Fixes #13 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -71,6 +71,31 @@ export const filterGroupsByPinned = (
|
||||
.filter((group) => group.items.length > 0);
|
||||
};
|
||||
|
||||
/** Inclusive-range predicate, mirrored from `inRange` in useLocalMessageSearch.ts. */
|
||||
export const inTsRange = (ts: number, fromTs?: number, toTs?: number): boolean =>
|
||||
(fromTs === undefined || ts >= fromTs) && (toTs === undefined || ts <= toTs);
|
||||
|
||||
/**
|
||||
* Filter result groups to items whose `origin_server_ts` falls within
|
||||
* [fromTs, toTs] (inclusive, either bound optional). The Matrix search API
|
||||
* has no timestamp filter fields, so server results must be post-filtered
|
||||
* here — the same predicate the local/encrypted search already applies.
|
||||
* Now-empty groups are dropped.
|
||||
*/
|
||||
export const filterGroupsByDateRange = (
|
||||
groups: ResultGroup[],
|
||||
fromTs?: number,
|
||||
toTs?: number,
|
||||
): ResultGroup[] => {
|
||||
if (fromTs === undefined && toTs === undefined) return groups;
|
||||
return groups
|
||||
.map((group) => ({
|
||||
...group,
|
||||
items: group.items.filter((item) => inTsRange(item.event.origin_server_ts, fromTs, toTs)),
|
||||
}))
|
||||
.filter((group) => group.items.length > 0);
|
||||
};
|
||||
|
||||
const groupSearchResult = (results: ISearchResult[]): ResultGroup[] => {
|
||||
const groups: ResultGroup[] = [];
|
||||
|
||||
@@ -119,7 +144,9 @@ export type MessageSearchParams = {
|
||||
};
|
||||
export const useMessageSearch = (params: MessageSearchParams) => {
|
||||
const mx = useMatrixClient();
|
||||
const { term, order, rooms, senders, fromTs, toTs, containsUrl } = params;
|
||||
// fromTs/toTs are intentionally not sent to the server (see comment below) —
|
||||
// callers post-filter results with filterGroupsByDateRange instead.
|
||||
const { term, order, rooms, senders, containsUrl } = params;
|
||||
|
||||
const searchMessages = useCallback(
|
||||
async (nextBatch?: string) => {
|
||||
@@ -142,9 +169,10 @@ export const useMessageSearch = (params: MessageSearchParams) => {
|
||||
limit,
|
||||
rooms,
|
||||
senders,
|
||||
// from_ts / to_ts and contains_url are valid Matrix spec fields not yet in SDK types
|
||||
...(fromTs !== undefined && { from_ts: fromTs }),
|
||||
...(toTs !== undefined && { to_ts: toTs }),
|
||||
// `RoomEventFilter` has no timestamp bounds — from_ts/to_ts are not
|
||||
// Matrix filter fields and the homeserver silently drops them, so the
|
||||
// date range is instead enforced client-side (see filterGroupsByDateRange).
|
||||
// contains_url is a valid spec field not yet in SDK types.
|
||||
...(containsUrl !== undefined && { contains_url: containsUrl }),
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} as any,
|
||||
@@ -161,7 +189,7 @@ export const useMessageSearch = (params: MessageSearchParams) => {
|
||||
});
|
||||
return parseSearchResult(r);
|
||||
},
|
||||
[mx, term, order, rooms, senders, fromTs, toTs, containsUrl],
|
||||
[mx, term, order, rooms, senders, containsUrl],
|
||||
);
|
||||
|
||||
return searchMessages;
|
||||
|
||||
Reference in New Issue
Block a user