import { IEventWithRoomId, IResultContext, ISearchRequestBody, ISearchResponse, ISearchResult, SearchOrderBy, } from 'matrix-js-sdk'; import { useCallback } from 'react'; import { useMatrixClient } from '../../hooks/useMatrixClient'; export type ResultItem = { rank: number; event: IEventWithRoomId; context: IResultContext; }; export type ResultGroup = { roomId: string; items: ResultItem[]; }; export type SearchResult = { nextToken?: string; highlights: string[]; groups: ResultGroup[]; }; const groupSearchResult = (results: ISearchResult[]): ResultGroup[] => { const groups: ResultGroup[] = []; results.forEach((item) => { const roomId = item.result.room_id; const resultItem: ResultItem = { rank: item.rank, event: item.result, context: item.context, }; const lastAddedGroup: ResultGroup | undefined = groups[groups.length - 1]; if (lastAddedGroup && roomId === lastAddedGroup.roomId) { lastAddedGroup.items.push(resultItem); return; } groups.push({ roomId, items: [resultItem], }); }); return groups; }; const parseSearchResult = (result: ISearchResponse): SearchResult => { const roomEvents = result.search_categories.room_events; const searchResult: SearchResult = { nextToken: roomEvents?.next_batch, highlights: roomEvents?.highlights ?? [], groups: groupSearchResult(roomEvents?.results ?? []), }; return searchResult; }; export type MessageSearchParams = { term?: string; order?: string; rooms?: string[]; senders?: string[]; }; export const useMessageSearch = (params: MessageSearchParams) => { const mx = useMatrixClient(); const { term, order, rooms, senders } = params; const searchMessages = useCallback( async (nextBatch?: string) => { if (!term) return { highlights: [], groups: [], }; const limit = 20; const requestBody: ISearchRequestBody = { search_categories: { room_events: { event_context: { before_limit: 0, after_limit: 0, include_profile: false, }, filter: { limit, rooms, senders, }, include_state: false, order_by: order as SearchOrderBy.Recent, search_term: term, }, }, }; const r = await mx.search({ body: requestBody, next_batch: nextBatch === '' ? undefined : nextBatch, }); return parseSearchResult(r); }, [mx, term, order, rooms, senders] ); return searchMessages; };