Dynamically adjusting the visibleRoomsView's timeline limit based on the app state

This commit is contained in:
Stefan Ceriu
2023-01-31 15:43:15 +02:00
committed by Stefan Ceriu
parent a8f154740e
commit 8f3842f74a
9 changed files with 64 additions and 25 deletions
@@ -14,6 +14,7 @@
// limitations under the License.
//
import Combine
import Foundation
import UIKit
@@ -90,6 +91,8 @@ struct HomeScreenViewState: BindableState {
struct HomeScreenViewStateBindings {
var searchQuery = ""
var isScrolling = false
var alertInfo: AlertInfo<UUID>?
}
@@ -35,7 +35,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
var callback: ((HomeScreenViewModelAction) -> Void)?
// swiftlint:disable:next function_body_length
// swiftlint:disable:next function_body_length cyclomatic_complexity
init(userSession: UserSessionProtocol, attributedStringBuilder: AttributedStringBuilderProtocol) {
self.userSession = userSession
self.attributedStringBuilder = attributedStringBuilder
@@ -64,7 +64,17 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
.debounce(for: 0.1, scheduler: DispatchQueue.main)
.removeDuplicates()
.sink { [weak self] range in
self?.updateVisibleRange(range)
guard let self else { return }
guard self.state.bindings.searchQuery.isEmpty else {
return
}
if self.state.bindings.isScrolling {
self.updateVisibleRange(range, timelineLimit: SlidingSyncConstants.lastMessageTimelineLimit)
} else {
self.updateVisibleRange(range, timelineLimit: SlidingSyncConstants.timelinePrecachingTimelineLimit)
}
}
.store(in: &cancellables)
@@ -234,7 +244,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
return room
}
private func updateVisibleRange(_ range: Range<Int>) {
private func updateVisibleRange(_ range: Range<Int>, timelineLimit: UInt) {
guard visibleRoomsSummaryProvider?.statePublisher.value == .live,
!range.isEmpty else { return }
@@ -246,6 +256,6 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
let lowerBound = max(0, range.lowerBound - Constants.slidingWindowBoundsPadding)
let upperBound = min(Int(visibleRoomsSummaryProvider.countPublisher.value), range.upperBound + Constants.slidingWindowBoundsPadding)
visibleRoomsSummaryProvider.updateVisibleRange(lowerBound..<upperBound)
visibleRoomsSummaryProvider.updateVisibleRange(lowerBound..<upperBound, timelineLimit: timelineLimit)
}
}
@@ -19,14 +19,10 @@ import SwiftUI
struct HomeScreen: View {
@ObservedObject var context: HomeScreenViewModel.Context
@State private var scrollViewAdapter = ScrollViewAdapter()
@State private var showingLogoutConfirmation = false
@State private var visibleItemIdentifiers = Set<String>() {
didSet {
if visibleItemIdentifiers != oldValue {
updateVisibleRange()
}
}
}
@State private var visibleItemIdentifiers = Set<String>()
@State private var hasTriggeredInitialVisibleItemUpdate = false
var body: some View {
ScrollView {
@@ -65,6 +61,10 @@ struct HomeScreen: View {
.disableAutocorrection(true)
}
}
.introspectScrollView { scrollView in
guard scrollView != scrollViewAdapter.scrollView else { return }
scrollViewAdapter.scrollView = scrollView
}
.scrollDismissesKeyboard(.immediately)
.disabled(context.viewState.roomListMode == .skeletons)
.animation(.elementDefault, value: context.viewState.showSessionVerificationBanner)
@@ -76,6 +76,17 @@ struct HomeScreen: View {
userMenuButton
}
}
.onChange(of: visibleItemIdentifiers) { _ in
if !hasTriggeredInitialVisibleItemUpdate {
updateVisibleRange()
hasTriggeredInitialVisibleItemUpdate = true
}
}
.onReceive(scrollViewAdapter.isScrolling) { isScrolling in
context.isScrolling = isScrolling
updateVisibleRange()
}
.background(Color.element.background)
}