Skip to content

Commit

Permalink
Fuzzy searching debouncing (#1506)
Browse files Browse the repository at this point in the history
* Add debouncer to room list fuzzy searching

* Fix function_body_length violation

* Filter out search query changes if fuzzy searching is not enabled
  • Loading branch information
stefanceriu authored Aug 17, 2023
1 parent 22e4f21 commit a11325b
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 60 deletions.
1 change: 0 additions & 1 deletion ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ enum HomeScreenViewAction {
case skipSessionVerification
case updateVisibleItemRange(range: Range<Int>, isScrolling: Bool)
case selectInvites
case updatedSearchQuery
}

enum HomeScreenRoomListMode: CustomStringConvertible {
Expand Down
113 changes: 62 additions & 51 deletions ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,66 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
.weakAssign(to: \.state.fuzzySearchEnabled, on: self)
.store(in: &cancellables)

context.$viewState
.filter { _ in appSettings.fuzzySearchEnabled }
.map(\.bindings.searchQuery)
.debounceAndRemoveDuplicates()
.sink { [weak self] searchQuery in
self?.roomSummaryProvider?.updateFilterPattern(searchQuery)
}
.store(in: &cancellables)

setupRoomSummaryProviderSubscriptions()

updateRooms()
}

// MARK: - Public

override func process(viewAction: HomeScreenViewAction) {
switch viewAction {
case .selectRoom(let roomIdentifier):
callback?(.presentRoom(roomIdentifier: roomIdentifier))
case .showRoomDetails(roomIdentifier: let roomIdentifier):
callback?(.presentRoomDetails(roomIdentifier: roomIdentifier))
case .leaveRoom(roomIdentifier: let roomIdentifier):
startLeaveRoomProcess(roomId: roomIdentifier)
case .confirmLeaveRoom(roomIdentifier: let roomIdentifier):
leaveRoom(roomId: roomIdentifier)
case .userMenu(let action):
switch action {
case .feedback:
callback?(.presentFeedbackScreen)
case .settings:
callback?(.presentSettingsScreen)
case .signOut:
callback?(.signOut)
}
case .verifySession:
callback?(.presentSessionVerificationScreen)
case .skipSessionVerification:
state.showSessionVerificationBanner = false
case .updateVisibleItemRange(let range, let isScrolling):
visibleItemRangePublisher.send((range, isScrolling))
case .startChat:
callback?(.presentStartChatScreen)
case .selectInvites:
callback?(.presentInvitesScreen)
}
}

func presentCrashedLastRunAlert() {
state.bindings.alertInfo = AlertInfo(id: UUID(),
title: L10n.crashDetectionDialogContent(InfoPlistReader.main.bundleDisplayName),
primaryButton: .init(title: L10n.actionNo, action: nil),
secondaryButton: .init(title: L10n.actionYes) { [weak self] in
self?.callback?(.presentFeedbackScreen)
})
}

// MARK: - Private

private func setupRoomSummaryProviderSubscriptions() {
guard let roomSummaryProvider, let inviteSummaryProvider else {
MXLog.error("Room summary provider unavailable")
return
Expand Down Expand Up @@ -119,11 +179,11 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
// Delay user profile detail loading until after the initial room list loads
if roomListMode == .rooms {
Task {
await userSession.clientProxy.loadUserAvatarURL()
await self.userSession.clientProxy.loadUserAvatarURL()
}

Task {
if case let .success(userDisplayName) = await userSession.clientProxy.loadUserDisplayName() {
if case let .success(userDisplayName) = await self.userSession.clientProxy.loadUserDisplayName() {
self.state.userDisplayName = userDisplayName
}
}
Expand Down Expand Up @@ -156,57 +216,8 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
})
}
.store(in: &cancellables)

updateRooms()
}

// MARK: - Public

override func process(viewAction: HomeScreenViewAction) {
switch viewAction {
case .selectRoom(let roomIdentifier):
callback?(.presentRoom(roomIdentifier: roomIdentifier))
case .showRoomDetails(roomIdentifier: let roomIdentifier):
callback?(.presentRoomDetails(roomIdentifier: roomIdentifier))
case .leaveRoom(roomIdentifier: let roomIdentifier):
startLeaveRoomProcess(roomId: roomIdentifier)
case .confirmLeaveRoom(roomIdentifier: let roomIdentifier):
leaveRoom(roomId: roomIdentifier)
case .userMenu(let action):
switch action {
case .feedback:
callback?(.presentFeedbackScreen)
case .settings:
callback?(.presentSettingsScreen)
case .signOut:
callback?(.signOut)
}
case .verifySession:
callback?(.presentSessionVerificationScreen)
case .skipSessionVerification:
state.showSessionVerificationBanner = false
case .updateVisibleItemRange(let range, let isScrolling):
visibleItemRangePublisher.send((range, isScrolling))
case .startChat:
callback?(.presentStartChatScreen)
case .selectInvites:
callback?(.presentInvitesScreen)
case .updatedSearchQuery:
roomSummaryProvider?.updateFilterPattern(state.bindings.searchQuery)
}
}

func presentCrashedLastRunAlert() {
state.bindings.alertInfo = AlertInfo(id: UUID(),
title: L10n.crashDetectionDialogContent(InfoPlistReader.main.bundleDisplayName),
primaryButton: .init(title: L10n.actionNo, action: nil),
secondaryButton: .init(title: L10n.actionYes) { [weak self] in
self?.callback?(.presentFeedbackScreen)
})
}

// MARK: - Private

private func installListRangeModifiers() {
guard visibleItemRangeObservationToken == nil else {
return
Expand Down
11 changes: 3 additions & 8 deletions ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,9 @@ struct HomeScreen: View {
.onReceive(scrollViewAdapter.isScrolling) { _ in
updateVisibleRange()
}
.onChange(of: context.searchQuery) { searchQuery in
if context.viewState.fuzzySearchEnabled {
context.send(viewAction: .updatedSearchQuery)
} else {
guard searchQuery.isEmpty else { return }
// Dispatch allows the view to update after changing the query
DispatchQueue.main.async { updateVisibleRange() }
}
.onChange(of: context.searchQuery) { _ in
// Dispatch allows the view to update after changing the query
DispatchQueue.main.async { updateVisibleRange() }
}
.onReceive(scrollViewAdapter.scrollDirection) { direction in
withAnimation(.elementDefault) { lastScrollDirection = direction }
Expand Down

0 comments on commit a11325b

Please sign in to comment.