mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
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
This commit is contained in:
@@ -47,7 +47,6 @@ enum HomeScreenViewAction {
|
|||||||
case skipSessionVerification
|
case skipSessionVerification
|
||||||
case updateVisibleItemRange(range: Range<Int>, isScrolling: Bool)
|
case updateVisibleItemRange(range: Range<Int>, isScrolling: Bool)
|
||||||
case selectInvites
|
case selectInvites
|
||||||
case updatedSearchQuery
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum HomeScreenRoomListMode: CustomStringConvertible {
|
enum HomeScreenRoomListMode: CustomStringConvertible {
|
||||||
|
|||||||
@@ -78,6 +78,66 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
.weakAssign(to: \.state.fuzzySearchEnabled, on: self)
|
.weakAssign(to: \.state.fuzzySearchEnabled, on: self)
|
||||||
.store(in: &cancellables)
|
.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 {
|
guard let roomSummaryProvider, let inviteSummaryProvider else {
|
||||||
MXLog.error("Room summary provider unavailable")
|
MXLog.error("Room summary provider unavailable")
|
||||||
return
|
return
|
||||||
@@ -119,11 +179,11 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
// Delay user profile detail loading until after the initial room list loads
|
// Delay user profile detail loading until after the initial room list loads
|
||||||
if roomListMode == .rooms {
|
if roomListMode == .rooms {
|
||||||
Task {
|
Task {
|
||||||
await userSession.clientProxy.loadUserAvatarURL()
|
await self.userSession.clientProxy.loadUserAvatarURL()
|
||||||
}
|
}
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
if case let .success(userDisplayName) = await userSession.clientProxy.loadUserDisplayName() {
|
if case let .success(userDisplayName) = await self.userSession.clientProxy.loadUserDisplayName() {
|
||||||
self.state.userDisplayName = userDisplayName
|
self.state.userDisplayName = userDisplayName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,57 +216,8 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.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() {
|
private func installListRangeModifiers() {
|
||||||
guard visibleItemRangeObservationToken == nil else {
|
guard visibleItemRangeObservationToken == nil else {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -79,14 +79,9 @@ struct HomeScreen: View {
|
|||||||
.onReceive(scrollViewAdapter.isScrolling) { _ in
|
.onReceive(scrollViewAdapter.isScrolling) { _ in
|
||||||
updateVisibleRange()
|
updateVisibleRange()
|
||||||
}
|
}
|
||||||
.onChange(of: context.searchQuery) { searchQuery in
|
.onChange(of: context.searchQuery) { _ in
|
||||||
if context.viewState.fuzzySearchEnabled {
|
// Dispatch allows the view to update after changing the query
|
||||||
context.send(viewAction: .updatedSearchQuery)
|
DispatchQueue.main.async { updateVisibleRange() }
|
||||||
} else {
|
|
||||||
guard searchQuery.isEmpty else { return }
|
|
||||||
// Dispatch allows the view to update after changing the query
|
|
||||||
DispatchQueue.main.async { updateVisibleRange() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.onReceive(scrollViewAdapter.scrollDirection) { direction in
|
.onReceive(scrollViewAdapter.scrollDirection) { direction in
|
||||||
withAnimation(.elementDefault) { lastScrollDirection = direction }
|
withAnimation(.elementDefault) { lastScrollDirection = direction }
|
||||||
|
|||||||
Reference in New Issue
Block a user