From 98adead8346fd2a983b21b94af6f402271bee2ca Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 17 Aug 2023 15:35:59 +0300 Subject: [PATCH] Fuzzy searching debouncing (#1506) * Add debouncer to room list fuzzy searching * Fix function_body_length violation * Filter out search query changes if fuzzy searching is not enabled --- .../Screens/HomeScreen/HomeScreenModels.swift | 1 - .../HomeScreen/HomeScreenViewModel.swift | 113 ++++++++++-------- .../Screens/HomeScreen/View/HomeScreen.swift | 11 +- 3 files changed, 65 insertions(+), 60 deletions(-) diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift index 55b5b5e91..19aee6ffb 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenModels.swift @@ -47,7 +47,6 @@ enum HomeScreenViewAction { case skipSessionVerification case updateVisibleItemRange(range: Range, isScrolling: Bool) case selectInvites - case updatedSearchQuery } enum HomeScreenRoomListMode: CustomStringConvertible { diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift index ef9cb7ed3..1f776aa66 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift @@ -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 @@ -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 } } @@ -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 diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift index eedf3e0af..8220d338b 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreen.swift @@ -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 }