Add a SpaceScreen for listing rooms and subspaces within a space. (#4412)

This commit is contained in:
Doug
2025-08-14 17:24:20 +01:00
committed by GitHub
parent de626186bd
commit 8000dbe29f
34 changed files with 756 additions and 93 deletions
@@ -5,19 +5,43 @@
// Please see LICENSE files in the repository root for full details.
//
import Combine
import Foundation
import MatrixRustSDK
extension SpaceRoomListProxyMock {
struct Configuration {
class Configuration {
var spaceRoomProxy: SpaceRoomProxyProtocol
var spaceRooms: [SpaceRoomProxyProtocol] = []
var initialSpaceRooms: [SpaceRoomProxyProtocol]
var paginationStateSubject: CurrentValueSubject<SpaceRoomListProxyPaginationState, Never>
var paginationResponses: [[SpaceRoomProxyProtocol]]
init(spaceRoomProxy: SpaceRoomProxyProtocol,
initialSpaceRooms: [SpaceRoomProxyProtocol] = [],
paginationStateSubject: CurrentValueSubject<SpaceRoomListProxyPaginationState, Never> = .init(.idle(endReached: true)),
paginationResponses: [[SpaceRoomProxyProtocol]] = []) {
self.spaceRoomProxy = spaceRoomProxy
self.initialSpaceRooms = initialSpaceRooms
self.paginationStateSubject = paginationStateSubject
self.paginationResponses = paginationResponses
}
}
convenience init(_ configuration: Configuration) {
self.init()
let spaceRoomsSubject: CurrentValueSubject<[SpaceRoomProxyProtocol], Never> = .init(configuration.initialSpaceRooms)
spaceRoom = configuration.spaceRoomProxy
spaceRoomsPublisher = .init(configuration.spaceRooms)
spaceRoomsPublisher = spaceRoomsSubject.asCurrentValuePublisher()
paginationStatePublisher = configuration.paginationStateSubject.asCurrentValuePublisher()
paginateClosure = {
configuration.paginationStateSubject.send(.loading)
try? await Task.sleep(for: .milliseconds(100))
let newRooms = configuration.paginationResponses.removeFirst()
spaceRoomsSubject.send(spaceRoomsSubject.value + newRooms)
configuration.paginationStateSubject.send(.idle(endReached: configuration.paginationResponses.isEmpty))
}
}
}
@@ -46,3 +46,79 @@ extension SpaceRoomProxyMock {
state = configuration.state
}
}
extension [SpaceRoomProxyProtocol] {
static var mockJoinedSpaces: [SpaceRoomProxyMock] {
[
SpaceRoomProxyMock(.init(id: "space1",
name: "The Foundation",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 500,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space2",
name: "The Second Foundation",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 100,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space3",
name: "The Galactic Empire",
isSpace: true,
childrenCount: 25000,
joinedMembersCount: 1_000_000_000,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space4",
name: "The Korellians",
isSpace: true,
childrenCount: 27,
joinedMembersCount: 2_000_000,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space5",
name: "The Luminists",
isSpace: true,
childrenCount: 1,
joinedMembersCount: 100_000,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space6",
name: "The Anacreons",
isSpace: true,
childrenCount: 25,
joinedMembersCount: 400_000,
state: .joined)),
SpaceRoomProxyMock(.init(id: "space7",
name: "The Thespians",
isSpace: true,
childrenCount: 15,
joinedMembersCount: 300_000,
state: .joined))
]
}
static var mockSpaceList: [SpaceRoomProxyProtocol] {
makeSpaceRooms(isSpace: true) + makeSpaceRooms(isSpace: false)
}
private static func makeSpaceRooms(isSpace: Bool) -> [SpaceRoomProxyMock] {
let typeName = isSpace ? "Space" : "Room"
return [
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())1:matrix.org",
name: "Company \(typeName)",
isSpace: isSpace)),
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())2:matrix.org",
name: "Public \(typeName)",
avatarURL: .mockMXCAvatar,
isSpace: isSpace,
joinedMembersCount: 78,
topic: "Discussion on specific topic goes here.",
joinRule: .public)),
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())3:matrix.org",
name: "Joined \(typeName)",
isSpace: isSpace,
joinedMembersCount: 123,
topic: "Discussion on specific topic goes here.",
state: .joined))
]
}
}
@@ -25,6 +25,10 @@ extension UserProfileProxy {
.init(userID: "@charlie:matrix.org", displayName: "Charlie", avatarURL: nil)
}
static var mockDan: UserProfileProxy {
.init(userID: "@dan:matrix.org", displayName: "Dan", avatarURL: .mockMXCUserAvatar)
}
static var mockVerbose: UserProfileProxy {
.init(userID: "@charlie:matrix.org", displayName: "Charlie is the best display name", avatarURL: nil)
}