Add a Messages tab to global search

Split global search into Rooms and Messages tabs. The Messages tab lists
matching events with the room's name and avatar, a sender-prefixed preview,
rich media (image/video/audio/file) previews, and a loading indicator, then
paginates as you scroll. Queries are debounced and the previous one is
superseded so late results can't clobber a newer search.
This commit is contained in:
Stefan Ceriu
2026-07-02 13:25:56 +03:00
parent 5851100f07
commit 4fbfc87551
13 changed files with 727 additions and 81 deletions
@@ -5,6 +5,7 @@
// Please see LICENSE files in the repository root for full details.
//
import Combine
@testable import ElementX
import Testing
@@ -16,7 +17,14 @@ struct SearchScreenViewModelTests {
}
init() {
let searchService = SearchServiceProxyMock()
searchService.underlyingResultsPublisher = CurrentValueSubject<[SearchServiceResult], Never>([]).asCurrentValuePublisher()
searchService.underlyingPaginationStatePublisher = CurrentValueSubject(.idle(endReached: true)).asCurrentValuePublisher()
searchService.setQueryReturnValue = .success(())
viewModel = SearchScreenViewModel(roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))),
searchService: searchService,
clientProxy: ClientProxyMock(.init()),
mediaProvider: MediaProviderMock(.init()))
}
@@ -31,7 +39,7 @@ struct SearchScreenViewModelTests {
func roomSelection() async throws {
let deferred = deferFulfillment(viewModel.actionsPublisher) { action in
switch action {
case .presentRoom(let roomID):
case .presentRoom(let roomID, _):
roomID == "2"
case .cancel:
false