Adopt fuzzy searching through the RoomListService's dynamic filter

This commit is contained in:
Stefan Ceriu 2023-08-11 17:26:45 +03:00 committed by Stefan Ceriu
parent 4503e6e0cc
commit e13e97400b
7 changed files with 27 additions and 16 deletions

View File

@ -47,6 +47,7 @@ enum HomeScreenViewAction {
case skipSessionVerification
case updateVisibleItemRange(range: Range<Int>, isScrolling: Bool)
case selectInvites
case updatedSearchQuery
}
enum HomeScreenRoomListMode: CustomStringConvertible {
@ -84,11 +85,7 @@ struct HomeScreenViewState: BindableState {
return placeholderRooms
}
if bindings.searchQuery.isEmpty {
return rooms
}
return rooms.filter { $0.name.localizedStandardContains(bindings.searchQuery) }
return rooms
}
var bindings = HomeScreenViewStateBindings()

View File

@ -187,6 +187,8 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
callback?(.presentStartChatScreen)
case .selectInvites:
callback?(.presentInvitesScreen)
case .updatedSearchQuery:
roomSummaryProvider?.updateFilterPattern(state.bindings.searchQuery)
}
}

View File

@ -79,8 +79,9 @@ struct HomeScreen: View {
.onReceive(scrollViewAdapter.isScrolling) { _ in
updateVisibleRange()
}
.onChange(of: context.searchQuery) { searchQuery in
guard searchQuery.isEmpty else { return }
.onChange(of: context.searchQuery) { _ in
context.send(viewAction: .updatedSearchQuery)
// Dispatch allows the view to update after changing the query
DispatchQueue.main.async { updateVisibleRange() }
}

View File

@ -45,6 +45,8 @@ class MockRoomSummaryProvider: RoomSummaryProviderProtocol {
func setRoomList(_ roomList: RoomList) { }
func updateVisibleRange(_ range: Range<Int>) { }
func updateFilterPattern(_ pattern: String?) { }
}
extension Array where Element == RoomSummary {

View File

@ -28,6 +28,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
private var roomList: RoomListProtocol?
private var cancellables = Set<AnyCancellable>()
private var listUpdatesSubscriptionResult: RoomListEntriesWithDynamicFilterResult?
private var listUpdatesTaskHandle: TaskHandle?
private var stateUpdatesTaskHandle: TaskHandle?
@ -73,21 +74,17 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
self.roomList = roomList
do {
let listUpdatesSubscriptionResult = roomList.entries(listener: RoomListEntriesListenerProxy { [weak self] updates in
listUpdatesSubscriptionResult = roomList.entriesWithDynamicFilter(listener: RoomListEntriesListenerProxy { [weak self] updates in
guard let self else { return }
MXLog.info("\(name): Received list update")
diffsPublisher.send(updates)
})
listUpdatesTaskHandle = listUpdatesSubscriptionResult.entriesStream
rooms = listUpdatesSubscriptionResult.entries.map { roomListEntry in
buildSummaryForRoomListEntry(roomListEntry)
}
// Manually call it here as the didSet doesn't work from constructors
roomListSubject.send(rooms)
listUpdatesTaskHandle = listUpdatesSubscriptionResult?.entriesStream
// Forces the listener above to be called with the current state
updateFilterPattern(nil)
let stateUpdatesSubscriptionResult = try roomList.loadingState(listener: RoomListStateObserver { [weak self] state in
guard let self else { return }
MXLog.info("\(name): Received state update: \(state)")
@ -113,6 +110,15 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
}
}
func updateFilterPattern(_ pattern: String?) {
guard let pattern, !pattern.isEmpty else {
_ = listUpdatesSubscriptionResult?.dynamicFilter.set(kind: .all)
return
}
_ = listUpdatesSubscriptionResult?.dynamicFilter.set(kind: .fuzzyMatchRoomName(pattern: pattern.lowercased()))
}
// MARK: - Private
fileprivate func updateRoomsWithDiffs(_ diffs: [RoomListEntriesUpdate]) {

View File

@ -99,4 +99,6 @@ protocol RoomSummaryProviderProtocol {
func setRoomList(_ roomList: RoomList)
func updateVisibleRange(_ range: Range<Int>)
func updateFilterPattern(_ pattern: String?)
}

View File

@ -0,0 +1 @@
Allow fuzzy searching for room list rooms