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:
Stefan Ceriu
2026-01-21 22:19:39 +02:00
committed by GitHub
parent 0d34a28ec2
commit b4b9f6affa
41 changed files with 808 additions and 13 deletions
@@ -16814,6 +16814,11 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
set(value) { underlyingTopLevelSpacesPublisher = value }
}
var underlyingTopLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never>!
var spaceFilterPublisher: CurrentValuePublisher<[SpaceServiceFilter], Never> {
get { return underlyingSpaceFilterPublisher }
set(value) { underlyingSpaceFilterPublisher = value }
}
var underlyingSpaceFilterPublisher: CurrentValuePublisher<[SpaceServiceFilter], Never>!
//MARK: - spaceRoomList
@@ -51,7 +51,7 @@ extension RoomSummaryProviderMock {
}
roomListSubject.send(rooms)
case let .all(filters):
case let .rooms(_, filters), let .all(filters):
var rooms = initialRooms
if filters.count > 1 {
@@ -60,6 +60,7 @@ extension [SpaceServiceRoomProtocol] {
isSpace: true,
childrenCount: 1,
joinedMembersCount: 500,
canonicalAlias: "#the-foundation:matrix.org",
state: .joined)),
SpaceServiceRoomMock(.init(id: "space2",
name: "The Second Foundation",
@@ -72,6 +73,7 @@ extension [SpaceServiceRoomProtocol] {
isSpace: true,
childrenCount: 25000,
joinedMembersCount: 1_000_000_000,
canonicalAlias: "#the-galactic-empire:matrix.org",
state: .joined)),
SpaceServiceRoomMock(.init(id: "space4",
name: "The Korellians",
@@ -14,6 +14,7 @@ import MatrixRustSDKMocks
extension SpaceServiceProxyMock {
struct Configuration {
var topLevelSpaces: [SpaceServiceRoomProtocol] = []
var spaceFilters: [SpaceServiceFilter] = []
var joinedParentSpaces: [SpaceServiceRoomProtocol] = []
var spaceRoomLists: [String: SpaceRoomListProxyMock] = [:]
var leaveSpaceRooms: [LeaveSpaceRoom] = []
@@ -23,6 +24,8 @@ extension SpaceServiceProxyMock {
self.init()
topLevelSpacesPublisher = .init(configuration.topLevelSpaces)
spaceFilterPublisher = .init(configuration.spaceFilters)
joinedParentsChildIDReturnValue = .success(configuration.joinedParentSpaces)
spaceRoomListSpaceIDClosure = { spaceID in
if let spaceRoomList = configuration.spaceRoomLists[spaceID] {
@@ -31,6 +34,7 @@ extension SpaceServiceProxyMock {
.failure(.sdkError(ClientProxyMockError.generic))
}
}
leaveSpaceSpaceIDClosure = { spaceID in
.success(LeaveSpaceHandleProxy(spaceID: spaceID,
leaveHandle: LeaveSpaceHandleSDKMock(.init(rooms: configuration.leaveSpaceRooms))))
@@ -45,13 +49,21 @@ extension SpaceServiceProxyMock {
extension SpaceServiceProxyMock.Configuration {
static var populated: SpaceServiceProxyMock.Configuration {
let spaceFilters = [SpaceServiceRoomProtocol].mockJoinedSpaces.reduce(into: [SpaceServiceFilter]()) { partialResult, spaceRoom in
partialResult.append(SpaceServiceFilter(room: spaceRoom, level: 0, descendants: .init()))
partialResult.append(SpaceServiceFilter(room: spaceRoom, level: 1, descendants: .init()))
}
let spaceRoomLists = [SpaceServiceRoomProtocol].mockJoinedSpaces.map {
($0.id, SpaceRoomListProxyMock(.init(spaceServiceRoom: $0, initialSpaceRooms: .mockSpaceList)))
}
let subSpaceRoomLists = [SpaceServiceRoomProtocol].mockSpaceList.map {
($0.id, SpaceRoomListProxyMock(.init(spaceServiceRoom: $0, initialSpaceRooms: .mockSingleRoom)))
}
return .init(topLevelSpaces: .mockJoinedSpaces, spaceRoomLists: .init(uniqueKeysWithValues: spaceRoomLists + subSpaceRoomLists))
return .init(topLevelSpaces: .mockJoinedSpaces,
spaceFilters: spaceFilters,
spaceRoomLists: .init(uniqueKeysWithValues: spaceRoomLists + subSpaceRoomLists))
}
}