Fixes 1864 - Message forwarding room list filtering and pagination problems (#1867)

* Fixes 1864 - Message forwarding room list filtering and pagination problems

* Fix SwiftFormat redundant closures body error

* Prevent crashes when writing to the localization bundle cache from different threads

* Fix unit tests

* Fix unit tests

* Address PR comments
This commit is contained in:
Stefan Ceriu
2023-10-09 14:59:31 +03:00
committed by GitHub
parent 8270a868a7
commit 1f12a7cb2f
14 changed files with 139 additions and 41 deletions
@@ -24,8 +24,17 @@ enum MockRoomSummaryProviderState {
}
class MockRoomSummaryProvider: RoomSummaryProviderProtocol {
let roomListPublisher: CurrentValuePublisher<[RoomSummary], Never>
let statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never>
private let initialRooms: [RoomSummary]
private let roomListSubject: CurrentValueSubject<[RoomSummary], Never>
var roomListPublisher: CurrentValuePublisher<[RoomSummary], Never> {
roomListSubject.asCurrentValuePublisher()
}
private let stateSuject: CurrentValueSubject<RoomSummaryProviderState, Never>
var statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never> {
stateSuject.asCurrentValuePublisher()
}
convenience init() {
self.init(state: .loading)
@@ -34,11 +43,15 @@ class MockRoomSummaryProvider: RoomSummaryProviderProtocol {
init(state: MockRoomSummaryProviderState) {
switch state {
case .loading:
roomListPublisher = .init([])
statePublisher = .init(.notLoaded)
initialRooms = []
roomListSubject = .init(initialRooms)
roomListSubject.send(initialRooms)
stateSuject = .init(.notLoaded)
case .loaded(let rooms):
roomListPublisher = .init(rooms)
statePublisher = .init(.loaded(totalNumberOfRooms: UInt(rooms.count)))
initialRooms = rooms
roomListSubject = .init(initialRooms)
roomListSubject.send(initialRooms)
stateSuject = .init(.loaded(totalNumberOfRooms: UInt(initialRooms.count)))
}
}
@@ -46,7 +59,20 @@ class MockRoomSummaryProvider: RoomSummaryProviderProtocol {
func updateVisibleRange(_ range: Range<Int>) { }
func setFilter(_ filter: RoomSummaryProviderFilter) { }
func setFilter(_ filter: RoomSummaryProviderFilter) {
switch filter {
case .all:
roomListSubject.send(initialRooms)
case .none:
roomListSubject.send([])
case .normalizedMatchRoomName(let filter):
if filter.isEmpty {
roomListSubject.send(initialRooms)
} else {
roomListSubject.send(initialRooms.filter { $0.name?.localizedCaseInsensitiveContains(filter) ?? false })
}
}
}
}
extension Array where Element == RoomSummary {
@@ -22,6 +22,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
private let roomListService: RoomListServiceProtocol
private let eventStringBuilder: RoomEventStringBuilder
private let name: String
private let shouldUpdateVisibleRange: Bool
private let notificationSettings: NotificationSettingsProxyProtocol
private let backgroundTaskService: BackgroundTaskServiceProtocol
@@ -56,15 +57,22 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
}
}
/// Build a new summary provider with the given parameters
/// - Parameters:
/// - shouldUpdateVisibleRange: whether this summary provider should foward visible ranges
/// to the room list service through the `applyInput(input: .viewport(ranges` api. Only useful for
/// lists that need to update the visible range on Sliding Sync
init(roomListService: RoomListServiceProtocol,
eventStringBuilder: RoomEventStringBuilder,
name: String,
shouldUpdateVisibleRange: Bool = false,
notificationSettings: NotificationSettingsProxyProtocol,
backgroundTaskService: BackgroundTaskServiceProtocol) {
self.roomListService = roomListService
serialDispatchQueue = DispatchQueue(label: "io.element.elementx.roomsummaryprovider", qos: .default)
self.eventStringBuilder = eventStringBuilder
self.name = name
self.shouldUpdateVisibleRange = shouldUpdateVisibleRange
self.notificationSettings = notificationSettings
self.backgroundTaskService = backgroundTaskService
@@ -110,6 +118,16 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
}
func updateVisibleRange(_ range: Range<Int>) {
if range.upperBound >= rooms.count {
listUpdatesSubscriptionResult?.controller.addOnePage()
} else if range.lowerBound == 0 {
listUpdatesSubscriptionResult?.controller.resetToOnePage()
}
guard shouldUpdateVisibleRange else {
return
}
Task {
do {
// The scroll view content size based visible range calculations might create large ranges
@@ -126,12 +144,6 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
MXLog.error("Failed updating visible range with error: \(error)")
}
}
if range.upperBound >= rooms.count {
listUpdatesSubscriptionResult?.controller.addOnePage()
} else if range.lowerBound == 0 {
listUpdatesSubscriptionResult?.controller.resetToOnePage()
}
}
func setFilter(_ filter: RoomSummaryProviderFilter) {