Room List Filters implementation (#2423)

This commit is contained in:
Mauro
2024-02-08 16:50:44 +01:00
committed by GitHub
parent e1d1e99ad4
commit 224e4e4881
18 changed files with 292 additions and 128 deletions
@@ -49,14 +49,13 @@ class RoomProxy: RoomProxyProtocol {
var ownUserID: String {
room.ownUserId()
}
init?(roomListItem: RoomListItemProtocol,
room: RoomProtocol,
backgroundTaskService: BackgroundTaskServiceProtocol) async {
self.roomListItem = roomListItem
self.room = room
self.backgroundTaskService = backgroundTaskService
do {
timeline = try await TimelineProxy(timeline: room.timeline(), backgroundTaskService: backgroundTaskService)
} catch {
@@ -130,7 +129,7 @@ class RoomProxy: RoomProxyProtocol {
var canonicalAlias: String? {
room.canonicalAlias()
}
var avatarURL: URL? {
roomListItem.avatarUrl().flatMap(URL.init(string:))
}
@@ -25,6 +25,7 @@ enum MockRoomSummaryProviderState {
class MockRoomSummaryProvider: RoomSummaryProviderProtocol {
private let initialRooms: [RoomSummary]
private(set) var currentFilter: RoomSummaryProviderFilter?
private let roomListSubject: CurrentValueSubject<[RoomSummary], Never>
var roomListPublisher: CurrentValuePublisher<[RoomSummary], Never> {
@@ -60,17 +61,16 @@ class MockRoomSummaryProvider: RoomSummaryProviderProtocol {
func updateVisibleRange(_ range: Range<Int>) { }
func setFilter(_ filter: RoomSummaryProviderFilter) {
currentFilter = filter
switch filter {
case .all:
roomListSubject.send(initialRooms)
case .none:
roomListSubject.send([])
case .normalizedMatchRoomName(let filter):
if filter.isEmpty {
roomListSubject.send(initialRooms)
case let .include(predicate):
if let query = predicate.query, !query.isEmpty {
roomListSubject.send(initialRooms.filter { $0.name?.localizedCaseInsensitiveContains(query) ?? false })
} else {
roomListSubject.send(initialRooms.filter { $0.name?.localizedCaseInsensitiveContains(filter) ?? false })
roomListSubject.send(initialRooms)
}
case .excludeAll:
roomListSubject.send([])
}
}
}
@@ -102,7 +102,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
})
// Forces the listener above to be called with the current state
setFilter(.all)
setFilter(.include(.all))
listUpdatesTaskHandle = listUpdatesSubscriptionResult?.entriesStream
@@ -151,12 +151,16 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
func setFilter(_ filter: RoomSummaryProviderFilter) {
switch filter {
case .none:
case .excludeAll:
_ = listUpdatesSubscriptionResult?.controller.setFilter(kind: .none)
case .all:
_ = listUpdatesSubscriptionResult?.controller.setFilter(kind: .allNonLeft)
case .normalizedMatchRoomName(let query):
_ = listUpdatesSubscriptionResult?.controller.setFilter(kind: .normalizedMatchRoomName(pattern: query.lowercased()))
case let .include(predicate):
var filters = predicate.filters.compactMap(\.rustFilter)
if let query = predicate.query {
filters.append(.normalizedMatchRoomName(pattern: query.lowercased()))
}
// We never want to show left rooms.
filters.append(.nonLeft)
_ = listUpdatesSubscriptionResult?.controller.setFilter(kind: .all(filters: filters))
}
}
@@ -87,10 +87,28 @@ enum RoomSummary: CustomStringConvertible, Equatable {
}
}
enum RoomSummaryProviderFilter {
case none
case all
case normalizedMatchRoomName(String)
enum RoomSummaryProviderFilter: Equatable {
struct Predicate: Equatable {
let query: String?
let filters: Set<RoomListFilter>
static var all: Predicate {
Predicate()
}
/// - Parameters:
/// - query: If provided the filter will do a normalized search, default is nil
/// - filters: Additional filters that can be provided for further filtering the room list, default is empty which means no additional filtering is done
init(query: String? = nil, filters: Set<RoomListFilter> = []) {
self.query = query
self.filters = filters
}
}
/// Filters out everything
case excludeAll
/// Includes only the items that satisfy the predicate logic
case include(Predicate)
}
protocol RoomSummaryProviderProtocol {
@@ -92,8 +92,9 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
}
func sendReadReceipt(for itemID: TimelineItemIdentifier) async -> Result<Void, RoomTimelineControllerError> {
guard let eventID = itemID.eventID
else { return .success(()) }
guard let eventID = itemID.eventID else {
return .failure(.generic)
}
switch await roomProxy.timeline.sendReadReceipt(for: eventID,
type: appSettings.sendReadReceiptsEnabled ? .read : .readPrivate) {