mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:31:27 +00:00
Space filters (#4977)
* Add support for SpaceFilters on the SpaceServiceProxy level and a screen that renders them * Add aliases to a couple of space room mocks * Update translations and related snapshots * Add a feature flag for space filters * Add a new room summary provider filter that takes a list of room identifiers next to the normal state filters This will take the SpaceFilter's descendants and combine it with the normal filters to reduce the rooms shown * Add a new space filter button to the home screen and link it to the SpaceFiltersScreen and the actual RoomSummaryProvider room list filters * Bump the RustSDK to v26.01.20-2 for SpaceFilter support. * Add a cancellation button to the space filters screen * Make the filter presentation mode liquidy, move the sheet to within the home screen. * Address PR comments
This commit is contained in:
@@ -133,6 +133,18 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
||||
[.normalizedMatchRoomName(pattern: query)] + baseFilter
|
||||
}
|
||||
_ = listUpdatesSubscriptionResult?.controller().setFilter(kind: .all(filters: filters))
|
||||
case .rooms(let roomIDs, let filters):
|
||||
var rustFilters = filters.map(\.rustFilter) + baseFilter
|
||||
|
||||
if !roomIDs.isEmpty {
|
||||
rustFilters.append(.identifiers(identifiers: Array(roomIDs)))
|
||||
}
|
||||
|
||||
if !filters.contains(.lowPriority), appSettings.lowPriorityFilterEnabled {
|
||||
rustFilters.append(.nonLowPriority)
|
||||
}
|
||||
|
||||
_ = listUpdatesSubscriptionResult?.controller().setFilter(kind: .all(filters: rustFilters))
|
||||
case let .all(filters):
|
||||
var rustFilters = filters.map(\.rustFilter) + baseFilter
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ enum RoomSummaryProviderFilter: Equatable {
|
||||
case search(query: String)
|
||||
/// Includes only what satisfies the filters used
|
||||
case all(filters: Set<RoomListFilter>)
|
||||
/// Include only rooms from the given that satisfy the given filters
|
||||
case rooms(roomsIDs: Set<String>, filters: Set<RoomListFilter>)
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
|
||||
@@ -19,6 +19,12 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
spacesSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
private var spaceFilterHandle: TaskHandle?
|
||||
private let spaceFilterSubject = CurrentValueSubject<[SpaceServiceFilter], Never>([])
|
||||
var spaceFilterPublisher: CurrentValuePublisher<[SpaceServiceFilter], Never> {
|
||||
spaceFilterSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
init(spaceService: SpaceServiceProtocol) {
|
||||
self.spaceService = spaceService
|
||||
|
||||
@@ -27,7 +33,11 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
|
||||
private func setupSubscriptions() async {
|
||||
topLevelSpacesHandle = await spaceService.subscribeToTopLevelJoinedSpaces(listener: SDKListener { [weak self] updates in
|
||||
self?.handleUpdates(updates)
|
||||
self?.handleSpaceListUpdates(updates)
|
||||
})
|
||||
|
||||
spaceFilterHandle = await spaceService.subscribeToSpaceFilters(listener: SDKListener { [weak self] updates in
|
||||
self?.handleSpaceFilterUpdates(updates)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -87,7 +97,7 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func handleUpdates(_ updates: [SpaceListUpdate]) {
|
||||
private func handleSpaceListUpdates(_ updates: [SpaceListUpdate]) {
|
||||
var spaces = spacesSubject.value
|
||||
|
||||
for update in updates {
|
||||
@@ -119,4 +129,37 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
|
||||
spacesSubject.send(spaces)
|
||||
}
|
||||
|
||||
private func handleSpaceFilterUpdates(_ updates: [SpaceFilterUpdate]) {
|
||||
var filters = spaceFilterSubject.value
|
||||
|
||||
for update in updates {
|
||||
switch update {
|
||||
case .append(let spaceFilters):
|
||||
filters.append(contentsOf: spaceFilters.map(SpaceServiceFilter.init))
|
||||
case .clear:
|
||||
filters.removeAll()
|
||||
case .pushFront(let filter):
|
||||
filters.insert(SpaceServiceFilter(filter: filter), at: 0)
|
||||
case .pushBack(let filter):
|
||||
filters.append(SpaceServiceFilter(filter: filter))
|
||||
case .popFront:
|
||||
filters.removeFirst()
|
||||
case .popBack:
|
||||
filters.removeLast()
|
||||
case .insert(let index, let filter):
|
||||
filters.insert(SpaceServiceFilter(filter: filter), at: Int(index))
|
||||
case .set(let index, let filter):
|
||||
filters[Int(index)] = SpaceServiceFilter(filter: filter)
|
||||
case .remove(let index):
|
||||
filters.remove(at: Int(index))
|
||||
case .truncate(let length):
|
||||
filters.removeSubrange(Int(length)..<filters.count)
|
||||
case .reset(let spaceFilters):
|
||||
filters = spaceFilters.map(SpaceServiceFilter.init)
|
||||
}
|
||||
}
|
||||
|
||||
spaceFilterSubject.send(filters)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,15 +7,44 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
enum SpaceServiceProxyError: Error {
|
||||
case sdkError(Error)
|
||||
case missingSpace
|
||||
}
|
||||
|
||||
struct SpaceServiceFilter: Identifiable, Equatable {
|
||||
let room: SpaceServiceRoomProtocol
|
||||
let level: UInt
|
||||
let descendants: Set<String>
|
||||
|
||||
init(room: SpaceServiceRoomProtocol, level: UInt, descendants: Set<String>) {
|
||||
self.room = room
|
||||
self.level = level
|
||||
self.descendants = descendants
|
||||
}
|
||||
|
||||
init(filter: SpaceFilter) {
|
||||
room = SpaceServiceRoom(spaceRoom: filter.spaceRoom)
|
||||
level = UInt(max(filter.level, 0))
|
||||
descendants = Set(filter.descendants)
|
||||
}
|
||||
|
||||
// Same rooms might appear on multiple levels
|
||||
var id: String {
|
||||
room.id + "\(level)"
|
||||
}
|
||||
|
||||
static func == (lhs: SpaceServiceFilter, rhs: SpaceServiceFilter) -> Bool {
|
||||
lhs.room.id == rhs.room.id
|
||||
}
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol SpaceServiceProxyProtocol {
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> { get }
|
||||
var spaceFilterPublisher: CurrentValuePublisher<[SpaceServiceFilter], Never> { get }
|
||||
|
||||
func spaceRoomList(spaceID: String) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
/// Returns a joined space given its identifier
|
||||
|
||||
Reference in New Issue
Block a user