mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
Rename SpaceRoomProxy to SpaceServiceRoom and stop proxying the struct. (#4952)
* Rename SpaceRoomProxy to SpaceServiceRoom. The underlying type is a struct, we don't need to proxy it. * Actually stop proxying the SpaceRoom.
This commit is contained in:
@@ -18,12 +18,12 @@ enum SpaceFlowCoordinatorAction {
|
||||
|
||||
enum SpaceFlowCoordinatorEntryPoint {
|
||||
case space(SpaceRoomListProxyProtocol)
|
||||
case joinSpace(SpaceRoomProxyProtocol)
|
||||
case joinSpace(SpaceServiceRoomProtocol)
|
||||
|
||||
var spaceID: String {
|
||||
switch self {
|
||||
case .space(let spaceRoomListProxy): spaceRoomListProxy.id
|
||||
case .joinSpace(let spaceRoomProxy): spaceRoomProxy.id
|
||||
case .joinSpace(let spaceServiceRoom): spaceServiceRoom.id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,8 +294,8 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
switch action {
|
||||
case .selectSpace(let spaceRoomListProxy):
|
||||
stateMachine.tryEvent(.startChildFlow, userInfo: SpaceFlowCoordinatorEntryPoint.space(spaceRoomListProxy))
|
||||
case .selectUnjoinedSpace(let spaceRoomProxy):
|
||||
stateMachine.tryEvent(.startChildFlow, userInfo: SpaceFlowCoordinatorEntryPoint.joinSpace(spaceRoomProxy))
|
||||
case .selectUnjoinedSpace(let spaceServiceRoom):
|
||||
stateMachine.tryEvent(.startChildFlow, userInfo: SpaceFlowCoordinatorEntryPoint.joinSpace(spaceServiceRoom))
|
||||
case .selectRoom(let roomID):
|
||||
stateMachine.tryEvent(.startRoomFlow(roomID: roomID))
|
||||
case .leftSpace:
|
||||
@@ -322,9 +322,9 @@ class SpaceFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
|
||||
private func presentJoinSpaceScreen() {
|
||||
guard case let .joinSpace(spaceRoomProxy) = entryPoint else { fatalError("Attempting to join a space with the wrong entry point.") }
|
||||
guard case let .joinSpace(spaceServiceRoom) = entryPoint else { fatalError("Attempting to join a space with the wrong entry point.") }
|
||||
|
||||
let parameters = JoinRoomScreenCoordinatorParameters(source: .space(spaceRoomProxy),
|
||||
let parameters = JoinRoomScreenCoordinatorParameters(source: .space(spaceServiceRoom),
|
||||
userSession: flowParameters.userSession,
|
||||
userIndicatorController: flowParameters.userIndicatorController,
|
||||
appSettings: flowParameters.appSettings)
|
||||
|
||||
@@ -123,8 +123,8 @@ extension ClientProxyMock {
|
||||
roomProxy.loadOrFetchEventDetailsForReturnValue = .success(TimelineEventSDKMock())
|
||||
return .joined(roomProxy)
|
||||
}
|
||||
} else if let spaceRoomProxy = configuration.spaceServiceConfiguration.topLevelSpaces.first(where: { $0.id == identifier }) {
|
||||
let roomProxy = await JoinedRoomProxyMock(.init(id: spaceRoomProxy.id, name: spaceRoomProxy.name, isSpace: spaceRoomProxy.isSpace))
|
||||
} else if let spaceServiceRoom = configuration.spaceServiceConfiguration.topLevelSpaces.first(where: { $0.id == identifier }) {
|
||||
let roomProxy = await JoinedRoomProxyMock(.init(id: spaceServiceRoom.id, name: spaceServiceRoom.name, isSpace: spaceServiceRoom.isSpace))
|
||||
roomProxy.loadOrFetchEventDetailsForReturnValue = .success(TimelineEventSDKMock())
|
||||
return .joined(roomProxy)
|
||||
} else {
|
||||
|
||||
@@ -16721,16 +16721,16 @@ class SpaceRoomListProxyMock: SpaceRoomListProxyProtocol, @unchecked Sendable {
|
||||
set(value) { underlyingId = value }
|
||||
}
|
||||
var underlyingId: String!
|
||||
var spaceRoomProxyPublisher: CurrentValuePublisher<SpaceRoomProxyProtocol, Never> {
|
||||
get { return underlyingSpaceRoomProxyPublisher }
|
||||
set(value) { underlyingSpaceRoomProxyPublisher = value }
|
||||
var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never> {
|
||||
get { return underlyingSpaceServiceRoomPublisher }
|
||||
set(value) { underlyingSpaceServiceRoomPublisher = value }
|
||||
}
|
||||
var underlyingSpaceRoomProxyPublisher: CurrentValuePublisher<SpaceRoomProxyProtocol, Never>!
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> {
|
||||
var underlyingSpaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never>!
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
|
||||
get { return underlyingSpaceRoomsPublisher }
|
||||
set(value) { underlyingSpaceRoomsPublisher = value }
|
||||
}
|
||||
var underlyingSpaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never>!
|
||||
var underlyingSpaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never>!
|
||||
var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never> {
|
||||
get { return underlyingPaginationStatePublisher }
|
||||
set(value) { underlyingPaginationStatePublisher = value }
|
||||
@@ -16773,55 +16773,12 @@ class SpaceRoomListProxyMock: SpaceRoomListProxyProtocol, @unchecked Sendable {
|
||||
await paginateClosure?()
|
||||
}
|
||||
}
|
||||
class SpaceRoomProxyMock: SpaceRoomProxyProtocol, @unchecked Sendable {
|
||||
var id: String {
|
||||
get { return underlyingId }
|
||||
set(value) { underlyingId = value }
|
||||
}
|
||||
var underlyingId: String!
|
||||
var name: String {
|
||||
get { return underlyingName }
|
||||
set(value) { underlyingName = value }
|
||||
}
|
||||
var underlyingName: String!
|
||||
var rawName: String?
|
||||
var avatarURL: URL?
|
||||
var isSpace: Bool {
|
||||
get { return underlyingIsSpace }
|
||||
set(value) { underlyingIsSpace = value }
|
||||
}
|
||||
var underlyingIsSpace: Bool!
|
||||
var isDirect: Bool?
|
||||
var childrenCount: Int {
|
||||
get { return underlyingChildrenCount }
|
||||
set(value) { underlyingChildrenCount = value }
|
||||
}
|
||||
var underlyingChildrenCount: Int!
|
||||
var joinedMembersCount: Int {
|
||||
get { return underlyingJoinedMembersCount }
|
||||
set(value) { underlyingJoinedMembersCount = value }
|
||||
}
|
||||
var underlyingJoinedMembersCount: Int!
|
||||
var heroes: [UserProfileProxy] = []
|
||||
var topic: String?
|
||||
var canonicalAlias: String?
|
||||
var joinRule: JoinRule?
|
||||
var worldReadable: Bool?
|
||||
var guestCanJoin: Bool {
|
||||
get { return underlyingGuestCanJoin }
|
||||
set(value) { underlyingGuestCanJoin = value }
|
||||
}
|
||||
var underlyingGuestCanJoin: Bool!
|
||||
var state: Membership?
|
||||
var via: [String] = []
|
||||
|
||||
}
|
||||
class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> {
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
|
||||
get { return underlyingTopLevelSpacesPublisher }
|
||||
set(value) { underlyingTopLevelSpacesPublisher = value }
|
||||
}
|
||||
var underlyingTopLevelSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never>!
|
||||
var underlyingTopLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never>!
|
||||
|
||||
//MARK: - spaceRoomList
|
||||
|
||||
@@ -16925,13 +16882,13 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
var spaceForIdentifierSpaceIDReceivedSpaceID: String?
|
||||
var spaceForIdentifierSpaceIDReceivedInvocations: [String] = []
|
||||
|
||||
var spaceForIdentifierSpaceIDUnderlyingReturnValue: Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>!
|
||||
var spaceForIdentifierSpaceIDReturnValue: Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>! {
|
||||
var spaceForIdentifierSpaceIDUnderlyingReturnValue: Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>!
|
||||
var spaceForIdentifierSpaceIDReturnValue: Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return spaceForIdentifierSpaceIDUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>? = nil
|
||||
var returnValue: Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = spaceForIdentifierSpaceIDUnderlyingReturnValue
|
||||
}
|
||||
@@ -16949,9 +16906,9 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
}
|
||||
var spaceForIdentifierSpaceIDClosure: ((String) async -> Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>)?
|
||||
var spaceForIdentifierSpaceIDClosure: ((String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>)?
|
||||
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError> {
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError> {
|
||||
spaceForIdentifierSpaceIDCallsCount += 1
|
||||
spaceForIdentifierSpaceIDReceivedSpaceID = spaceID
|
||||
DispatchQueue.main.async {
|
||||
@@ -17065,13 +17022,13 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
var joinedParentsChildIDReceivedChildID: String?
|
||||
var joinedParentsChildIDReceivedInvocations: [String] = []
|
||||
|
||||
var joinedParentsChildIDUnderlyingReturnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>!
|
||||
var joinedParentsChildIDReturnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>! {
|
||||
var joinedParentsChildIDUnderlyingReturnValue: Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>!
|
||||
var joinedParentsChildIDReturnValue: Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return joinedParentsChildIDUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>? = nil
|
||||
var returnValue: Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = joinedParentsChildIDUnderlyingReturnValue
|
||||
}
|
||||
@@ -17089,9 +17046,9 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
}
|
||||
var joinedParentsChildIDClosure: ((String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>)?
|
||||
var joinedParentsChildIDClosure: ((String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>)?
|
||||
|
||||
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> {
|
||||
func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError> {
|
||||
joinedParentsChildIDCallsCount += 1
|
||||
joinedParentsChildIDReceivedChildID = childID
|
||||
DispatchQueue.main.async {
|
||||
@@ -17104,6 +17061,49 @@ class SpaceServiceProxyMock: SpaceServiceProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
}
|
||||
}
|
||||
class SpaceServiceRoomMock: SpaceServiceRoomProtocol, @unchecked Sendable {
|
||||
var id: String {
|
||||
get { return underlyingId }
|
||||
set(value) { underlyingId = value }
|
||||
}
|
||||
var underlyingId: String!
|
||||
var name: String {
|
||||
get { return underlyingName }
|
||||
set(value) { underlyingName = value }
|
||||
}
|
||||
var underlyingName: String!
|
||||
var rawName: String?
|
||||
var avatarURL: URL?
|
||||
var isSpace: Bool {
|
||||
get { return underlyingIsSpace }
|
||||
set(value) { underlyingIsSpace = value }
|
||||
}
|
||||
var underlyingIsSpace: Bool!
|
||||
var isDirect: Bool?
|
||||
var childrenCount: Int {
|
||||
get { return underlyingChildrenCount }
|
||||
set(value) { underlyingChildrenCount = value }
|
||||
}
|
||||
var underlyingChildrenCount: Int!
|
||||
var joinedMembersCount: Int {
|
||||
get { return underlyingJoinedMembersCount }
|
||||
set(value) { underlyingJoinedMembersCount = value }
|
||||
}
|
||||
var underlyingJoinedMembersCount: Int!
|
||||
var heroes: [UserProfileProxy] = []
|
||||
var topic: String?
|
||||
var canonicalAlias: String?
|
||||
var joinRule: JoinRule?
|
||||
var worldReadable: Bool?
|
||||
var guestCanJoin: Bool {
|
||||
get { return underlyingGuestCanJoin }
|
||||
set(value) { underlyingGuestCanJoin = value }
|
||||
}
|
||||
var underlyingGuestCanJoin: Bool!
|
||||
var state: Membership?
|
||||
var via: [String] = []
|
||||
|
||||
}
|
||||
class StaticRoomSummaryProviderMock: StaticRoomSummaryProviderProtocol, @unchecked Sendable {
|
||||
var statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never> {
|
||||
get { return underlyingStatePublisher }
|
||||
|
||||
@@ -98,17 +98,17 @@ extension RoomPreviewProxyMock {
|
||||
underlyingOwnMembershipDetails = roomMembershipDetails
|
||||
}
|
||||
|
||||
convenience init(spaceRoomProxy: SpaceRoomProxyProtocol) {
|
||||
self.init(Configuration(roomID: spaceRoomProxy.id,
|
||||
canonicalAlias: spaceRoomProxy.canonicalAlias ?? "",
|
||||
name: spaceRoomProxy.name,
|
||||
topic: spaceRoomProxy.topic ?? "",
|
||||
avatarURL: spaceRoomProxy.avatarURL?.absoluteString ?? "",
|
||||
numJoinedMembers: UInt64(spaceRoomProxy.joinedMembersCount),
|
||||
numActiveMembers: UInt64(spaceRoomProxy.joinedMembersCount),
|
||||
roomType: spaceRoomProxy.isSpace ? .space : .room,
|
||||
convenience init(spaceServiceRoom: SpaceServiceRoomProtocol) {
|
||||
self.init(Configuration(roomID: spaceServiceRoom.id,
|
||||
canonicalAlias: spaceServiceRoom.canonicalAlias ?? "",
|
||||
name: spaceServiceRoom.name,
|
||||
topic: spaceServiceRoom.topic ?? "",
|
||||
avatarURL: spaceServiceRoom.avatarURL?.absoluteString ?? "",
|
||||
numJoinedMembers: UInt64(spaceServiceRoom.joinedMembersCount),
|
||||
numActiveMembers: UInt64(spaceServiceRoom.joinedMembersCount),
|
||||
roomType: spaceServiceRoom.isSpace ? .space : .room,
|
||||
membership: nil,
|
||||
joinRule: spaceRoomProxy.joinRule ?? .restricted(rules: []),
|
||||
joinRule: spaceServiceRoom.joinRule ?? .restricted(rules: []),
|
||||
isDirect: false))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,17 +23,17 @@ extension LeaveSpaceHandleSDKMock {
|
||||
}
|
||||
|
||||
extension [LeaveSpaceRoom] {
|
||||
static func mockRoomsWithSpace(spaceRoomProxy: SpaceRoomProxyProtocol, isLastAdmin: Bool) -> [LeaveSpaceRoom] {
|
||||
mockRooms + mockSingleSpace(spaceRoomProxy: spaceRoomProxy, isLastAdmin: isLastAdmin)
|
||||
static func mockRoomsWithSpace(spaceServiceRoom: SpaceServiceRoomProtocol, isLastAdmin: Bool) -> [LeaveSpaceRoom] {
|
||||
mockRooms + mockSingleSpace(spaceServiceRoom: spaceServiceRoom, isLastAdmin: isLastAdmin)
|
||||
}
|
||||
|
||||
static func mockSingleSpace(spaceRoomProxy: SpaceRoomProxyProtocol, isLastAdmin: Bool) -> [LeaveSpaceRoom] {
|
||||
[LeaveSpaceRoom(spaceRoom: SpaceRoom(id: spaceRoomProxy.id,
|
||||
name: spaceRoomProxy.name,
|
||||
avatarURL: spaceRoomProxy.avatarURL,
|
||||
static func mockSingleSpace(spaceServiceRoom: SpaceServiceRoomProtocol, isLastAdmin: Bool) -> [LeaveSpaceRoom] {
|
||||
[LeaveSpaceRoom(spaceRoom: SpaceRoom(id: spaceServiceRoom.id,
|
||||
name: spaceServiceRoom.name,
|
||||
avatarURL: spaceServiceRoom.avatarURL,
|
||||
isSpace: true,
|
||||
memberCount: UInt64(spaceRoomProxy.joinedMembersCount),
|
||||
joinRule: spaceRoomProxy.joinRule),
|
||||
memberCount: UInt64(spaceServiceRoom.joinedMembersCount),
|
||||
joinRule: spaceServiceRoom.joinRule),
|
||||
isLastAdmin: isLastAdmin)]
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
extension SpaceServiceRoomMock {
|
||||
struct Configuration {
|
||||
var id: String = UUID().uuidString
|
||||
var name: String?
|
||||
var rawName: String?
|
||||
var avatarURL: URL?
|
||||
|
||||
var isSpace: Bool
|
||||
var isDirect: Bool?
|
||||
var childrenCount = 0
|
||||
|
||||
var joinedMembersCount = 0
|
||||
var heroes: [UserProfileProxy] = []
|
||||
var topic: String?
|
||||
var canonicalAlias: String?
|
||||
|
||||
var joinRule: JoinRule?
|
||||
var worldReadable: Bool?
|
||||
var guestCanJoin = true
|
||||
var state: Membership?
|
||||
}
|
||||
|
||||
convenience init(_ configuration: Configuration) {
|
||||
self.init()
|
||||
|
||||
id = configuration.id
|
||||
name = configuration.name ?? configuration.id
|
||||
rawName = configuration.rawName
|
||||
avatarURL = configuration.avatarURL
|
||||
isSpace = configuration.isSpace
|
||||
isDirect = configuration.isDirect
|
||||
childrenCount = configuration.childrenCount
|
||||
joinedMembersCount = configuration.joinedMembersCount
|
||||
heroes = configuration.heroes
|
||||
topic = configuration.topic
|
||||
canonicalAlias = configuration.canonicalAlias
|
||||
joinRule = configuration.joinRule
|
||||
worldReadable = configuration.worldReadable
|
||||
guestCanJoin = configuration.guestCanJoin
|
||||
state = configuration.state
|
||||
}
|
||||
}
|
||||
|
||||
extension [SpaceServiceRoomProtocol] {
|
||||
static var mockJoinedSpaces: [SpaceServiceRoomMock] {
|
||||
[
|
||||
SpaceServiceRoomMock(.init(id: "space1",
|
||||
name: "The Foundation",
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 500,
|
||||
state: .joined)),
|
||||
SpaceServiceRoomMock(.init(id: "space2",
|
||||
name: "The Second Foundation",
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 100,
|
||||
state: .joined)),
|
||||
SpaceServiceRoomMock(.init(id: "space3",
|
||||
name: "The Galactic Empire",
|
||||
isSpace: true,
|
||||
childrenCount: 25000,
|
||||
joinedMembersCount: 1_000_000_000,
|
||||
state: .joined)),
|
||||
SpaceServiceRoomMock(.init(id: "space4",
|
||||
name: "The Korellians",
|
||||
isSpace: true,
|
||||
childrenCount: 27,
|
||||
joinedMembersCount: 2_000_000,
|
||||
state: .joined)),
|
||||
SpaceServiceRoomMock(.init(id: "space5",
|
||||
name: "The Luminists",
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 100_000,
|
||||
state: .joined)),
|
||||
SpaceServiceRoomMock(.init(id: "space6",
|
||||
name: "The Anacreons",
|
||||
isSpace: true,
|
||||
childrenCount: 25,
|
||||
joinedMembersCount: 400_000,
|
||||
state: .joined)),
|
||||
SpaceServiceRoomMock(.init(id: "space7",
|
||||
name: "The Thespians",
|
||||
isSpace: true,
|
||||
childrenCount: 15,
|
||||
joinedMembersCount: 300_000,
|
||||
state: .joined))
|
||||
]
|
||||
}
|
||||
|
||||
static var mockJoinedSpaces2: [SpaceServiceRoomMock] {
|
||||
[
|
||||
SpaceServiceRoomMock(.init(id: "space1",
|
||||
name: "The Foundation",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 500,
|
||||
canonicalAlias: "#the-foundation:matrix.org",
|
||||
state: .joined)),
|
||||
SpaceServiceRoomMock(.init(id: "space2",
|
||||
name: "The Second Foundation",
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 100,
|
||||
state: .joined)),
|
||||
SpaceServiceRoomMock(.init(id: "space3",
|
||||
name: "The Galactic Empire",
|
||||
isSpace: true,
|
||||
childrenCount: 25000,
|
||||
joinedMembersCount: 1_000_000_000,
|
||||
canonicalAlias: "#the-galactic-empire:matrix.org",
|
||||
state: .joined))
|
||||
]
|
||||
}
|
||||
|
||||
static var mockSpaceList: [SpaceServiceRoomProtocol] {
|
||||
makeSpaceRooms(isSpace: true) + makeSpaceRooms(isSpace: false)
|
||||
}
|
||||
|
||||
static var mockSingleRoom: [SpaceServiceRoomProtocol] {
|
||||
[SpaceServiceRoomMock(.init(id: "!spaceroom:matrix.org",
|
||||
name: "Management",
|
||||
isSpace: false,
|
||||
joinedMembersCount: 12,
|
||||
topic: "This is where everything gets organised 📋.",
|
||||
state: .joined))]
|
||||
}
|
||||
|
||||
private static func makeSpaceRooms(isSpace: Bool) -> [SpaceServiceRoomMock] {
|
||||
let typeName = isSpace ? "Space" : "Room"
|
||||
|
||||
return [
|
||||
SpaceServiceRoomMock(.init(id: "!\(typeName.lowercased())1:matrix.org",
|
||||
name: "Company \(typeName)",
|
||||
isSpace: isSpace)),
|
||||
SpaceServiceRoomMock(.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)),
|
||||
SpaceServiceRoomMock(.init(id: "!\(typeName.lowercased())3:matrix.org",
|
||||
name: "Joined \(typeName)",
|
||||
isSpace: isSpace,
|
||||
joinedMembersCount: 123,
|
||||
topic: "Discussion on specific topic goes here.",
|
||||
joinRule: .restricted(rules: []),
|
||||
state: .joined))
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
extension SpaceServiceRoomMock {
|
||||
convenience init(mode: JoinRoomScreenMode) {
|
||||
var state: Membership?
|
||||
var joinRule: JoinRule?
|
||||
|
||||
switch mode {
|
||||
case .joinable:
|
||||
joinRule = .public
|
||||
case .restricted:
|
||||
joinRule = .restricted(rules: [])
|
||||
case .inviteRequired:
|
||||
joinRule = .private
|
||||
case .invited:
|
||||
state = .invited
|
||||
joinRule = .private
|
||||
case .knockable:
|
||||
joinRule = .knock
|
||||
case .knocked:
|
||||
state = .knocked
|
||||
joinRule = .knock
|
||||
case .banned:
|
||||
state = .banned
|
||||
case .loading, .unknown, .forbidden:
|
||||
break
|
||||
}
|
||||
|
||||
self.init(.init(id: "1",
|
||||
name: "The Three-Body Problem",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
childrenCount: 100,
|
||||
joinedMembersCount: 123,
|
||||
heroes: [.mockAlice, .mockBob, .mockCharlie],
|
||||
topic: "“Science and technology were the only keys to opening the door to the future, and people approached science with the faith and sincerity of elementary school students.”",
|
||||
canonicalAlias: "#3-body-problem:matrix.org",
|
||||
joinRule: joinRule,
|
||||
state: state))
|
||||
}
|
||||
}
|
||||
@@ -12,16 +12,16 @@ import MatrixRustSDK
|
||||
|
||||
extension SpaceRoomListProxyMock {
|
||||
class Configuration {
|
||||
var spaceRoomProxy: SpaceRoomProxyProtocol
|
||||
var initialSpaceRooms: [SpaceRoomProxyProtocol]
|
||||
var spaceServiceRoom: SpaceServiceRoomProtocol
|
||||
var initialSpaceRooms: [SpaceServiceRoomProtocol]
|
||||
var paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never>
|
||||
var paginationResponses: [[SpaceRoomProxyProtocol]]
|
||||
var paginationResponses: [[SpaceServiceRoomProtocol]]
|
||||
|
||||
init(spaceRoomProxy: SpaceRoomProxyProtocol,
|
||||
initialSpaceRooms: [SpaceRoomProxyProtocol] = [],
|
||||
init(spaceServiceRoom: SpaceServiceRoomProtocol,
|
||||
initialSpaceRooms: [SpaceServiceRoomProtocol] = [],
|
||||
paginationStateSubject: CurrentValueSubject<SpaceRoomListPaginationState, Never> = .init(.idle(endReached: true)),
|
||||
paginationResponses: [[SpaceRoomProxyProtocol]] = []) {
|
||||
self.spaceRoomProxy = spaceRoomProxy
|
||||
paginationResponses: [[SpaceServiceRoomProtocol]] = []) {
|
||||
self.spaceServiceRoom = spaceServiceRoom
|
||||
self.initialSpaceRooms = initialSpaceRooms
|
||||
self.paginationStateSubject = paginationStateSubject
|
||||
self.paginationResponses = paginationResponses
|
||||
@@ -31,10 +31,10 @@ extension SpaceRoomListProxyMock {
|
||||
convenience init(_ configuration: Configuration) {
|
||||
self.init()
|
||||
|
||||
let spaceRoomsSubject: CurrentValueSubject<[SpaceRoomProxyProtocol], Never> = .init(configuration.initialSpaceRooms)
|
||||
let spaceRoomsSubject: CurrentValueSubject<[SpaceServiceRoomProtocol], Never> = .init(configuration.initialSpaceRooms)
|
||||
|
||||
id = configuration.spaceRoomProxy.id
|
||||
spaceRoomProxyPublisher = .init(configuration.spaceRoomProxy)
|
||||
id = configuration.spaceServiceRoom.id
|
||||
spaceServiceRoomPublisher = .init(configuration.spaceServiceRoom)
|
||||
spaceRoomsPublisher = spaceRoomsSubject.asCurrentValuePublisher()
|
||||
paginationStatePublisher = configuration.paginationStateSubject.asCurrentValuePublisher()
|
||||
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
extension SpaceRoomProxyMock {
|
||||
struct Configuration {
|
||||
var id: String = UUID().uuidString
|
||||
var name: String?
|
||||
var rawName: String?
|
||||
var avatarURL: URL?
|
||||
|
||||
var isSpace: Bool
|
||||
var isDirect: Bool?
|
||||
var childrenCount = 0
|
||||
|
||||
var joinedMembersCount = 0
|
||||
var heroes: [UserProfileProxy] = []
|
||||
var topic: String?
|
||||
var canonicalAlias: String?
|
||||
|
||||
var joinRule: JoinRule?
|
||||
var worldReadable: Bool?
|
||||
var guestCanJoin = true
|
||||
var state: Membership?
|
||||
}
|
||||
|
||||
convenience init(_ configuration: Configuration) {
|
||||
self.init()
|
||||
|
||||
id = configuration.id
|
||||
name = configuration.name ?? configuration.id
|
||||
rawName = configuration.rawName
|
||||
avatarURL = configuration.avatarURL
|
||||
isSpace = configuration.isSpace
|
||||
isDirect = configuration.isDirect
|
||||
childrenCount = configuration.childrenCount
|
||||
joinedMembersCount = configuration.joinedMembersCount
|
||||
heroes = configuration.heroes
|
||||
topic = configuration.topic
|
||||
canonicalAlias = configuration.canonicalAlias
|
||||
joinRule = configuration.joinRule
|
||||
worldReadable = configuration.worldReadable
|
||||
guestCanJoin = configuration.guestCanJoin
|
||||
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 mockJoinedSpaces2: [SpaceRoomProxyMock] {
|
||||
[
|
||||
SpaceRoomProxyMock(.init(id: "space1",
|
||||
name: "The Foundation",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 500,
|
||||
canonicalAlias: "#the-foundation:matrix.org",
|
||||
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,
|
||||
canonicalAlias: "#the-galactic-empire:matrix.org",
|
||||
state: .joined))
|
||||
]
|
||||
}
|
||||
|
||||
static var mockSpaceList: [SpaceRoomProxyProtocol] {
|
||||
makeSpaceRooms(isSpace: true) + makeSpaceRooms(isSpace: false)
|
||||
}
|
||||
|
||||
static var mockSingleRoom: [SpaceRoomProxyProtocol] {
|
||||
[SpaceRoomProxyMock(.init(id: "!spaceroom:matrix.org",
|
||||
name: "Management",
|
||||
isSpace: false,
|
||||
joinedMembersCount: 12,
|
||||
topic: "This is where everything gets organised 📋.",
|
||||
state: .joined))]
|
||||
}
|
||||
|
||||
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.",
|
||||
joinRule: .restricted(rules: []),
|
||||
state: .joined))
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
extension SpaceRoomProxyMock {
|
||||
convenience init(mode: JoinRoomScreenMode) {
|
||||
var state: Membership?
|
||||
var joinRule: JoinRule?
|
||||
|
||||
switch mode {
|
||||
case .joinable:
|
||||
joinRule = .public
|
||||
case .restricted:
|
||||
joinRule = .restricted(rules: [])
|
||||
case .inviteRequired:
|
||||
joinRule = .private
|
||||
case .invited:
|
||||
state = .invited
|
||||
joinRule = .private
|
||||
case .knockable:
|
||||
joinRule = .knock
|
||||
case .knocked:
|
||||
state = .knocked
|
||||
joinRule = .knock
|
||||
case .banned:
|
||||
state = .banned
|
||||
case .loading, .unknown, .forbidden:
|
||||
break
|
||||
}
|
||||
|
||||
self.init(.init(id: "1",
|
||||
name: "The Three-Body Problem",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
childrenCount: 100,
|
||||
joinedMembersCount: 123,
|
||||
heroes: [.mockAlice, .mockBob, .mockCharlie],
|
||||
topic: "“Science and technology were the only keys to opening the door to the future, and people approached science with the faith and sincerity of elementary school students.”",
|
||||
canonicalAlias: "#3-body-problem:matrix.org",
|
||||
joinRule: joinRule,
|
||||
state: state))
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,8 @@ import MatrixRustSDKMocks
|
||||
|
||||
extension SpaceServiceProxyMock {
|
||||
struct Configuration {
|
||||
var topLevelSpaces: [SpaceRoomProxyProtocol] = []
|
||||
var joinedParentSpaces: [SpaceRoomProxyProtocol] = []
|
||||
var topLevelSpaces: [SpaceServiceRoomProtocol] = []
|
||||
var joinedParentSpaces: [SpaceServiceRoomProtocol] = []
|
||||
var spaceRoomLists: [String: SpaceRoomListProxyMock] = [:]
|
||||
var leaveSpaceRooms: [LeaveSpaceRoom] = []
|
||||
}
|
||||
@@ -43,11 +43,11 @@ extension SpaceServiceProxyMock {
|
||||
|
||||
extension SpaceServiceProxyMock.Configuration {
|
||||
static var populated: SpaceServiceProxyMock.Configuration {
|
||||
let spaceRoomLists = [SpaceRoomProxyProtocol].mockJoinedSpaces.map {
|
||||
($0.id, SpaceRoomListProxyMock(.init(spaceRoomProxy: $0, initialSpaceRooms: .mockSpaceList)))
|
||||
let spaceRoomLists = [SpaceServiceRoomProtocol].mockJoinedSpaces.map {
|
||||
($0.id, SpaceRoomListProxyMock(.init(spaceServiceRoom: $0, initialSpaceRooms: .mockSpaceList)))
|
||||
}
|
||||
let subSpaceRoomLists = [SpaceRoomProxyProtocol].mockSpaceList.map {
|
||||
($0.id, SpaceRoomListProxyMock(.init(spaceRoomProxy: $0, initialSpaceRooms: .mockSingleRoom)))
|
||||
let subSpaceRoomLists = [SpaceServiceRoomProtocol].mockSpaceList.map {
|
||||
($0.id, SpaceRoomListProxyMock(.init(spaceServiceRoom: $0, initialSpaceRooms: .mockSingleRoom)))
|
||||
}
|
||||
|
||||
return .init(topLevelSpaces: .mockJoinedSpaces, spaceRoomLists: .init(uniqueKeysWithValues: spaceRoomLists + subSpaceRoomLists))
|
||||
|
||||
@@ -18,14 +18,14 @@ struct JoinRoomScreenCoordinatorParameters {
|
||||
|
||||
enum JoinRoomScreenSource {
|
||||
case generic(roomID: String, via: [String])
|
||||
case space(SpaceRoomProxyProtocol)
|
||||
case space(SpaceServiceRoomProtocol)
|
||||
|
||||
func roomIDAndVia() -> (roomID: String, via: [String]) {
|
||||
switch self {
|
||||
case let .generic(roomID: roomID, via: via):
|
||||
return (roomID: roomID, via: via)
|
||||
case let .space(spaceRoomProxy):
|
||||
return (roomID: spaceRoomProxy.id, via: spaceRoomProxy.via)
|
||||
case let .space(spaceServiceRoom):
|
||||
return (roomID: spaceServiceRoom.id, via: spaceServiceRoom.via)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ struct JoinRoomScreenRoomDetails {
|
||||
|
||||
let isSpace: Bool?
|
||||
let childrenCount: Int?
|
||||
let spaceVisibility: SpaceRoomProxyVisibility?
|
||||
let spaceVisibility: SpaceServiceRoomVisibility?
|
||||
}
|
||||
|
||||
struct JoinRoomScreenViewState: BindableState {
|
||||
|
||||
@@ -172,8 +172,8 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
switch source {
|
||||
case .generic(let roomID, _):
|
||||
await updateGenericRoomDetails(roomID: roomID, roomInfo: roomInfo, inviter: inviter)
|
||||
case .space(let spaceRoomProxy):
|
||||
await updateSpaceRoomDetails(spaceRoomProxy: spaceRoomProxy, inviter: inviter)
|
||||
case .space(let spaceServiceRoom):
|
||||
await updateSpaceRoomDetails(spaceServiceRoom: spaceServiceRoom, inviter: inviter)
|
||||
}
|
||||
await updateMode()
|
||||
}
|
||||
@@ -200,18 +200,18 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
spaceVisibility: nil)
|
||||
}
|
||||
|
||||
private func updateSpaceRoomDetails(spaceRoomProxy: SpaceRoomProxyProtocol, inviter: RoomInviterDetails?) async {
|
||||
state.roomDetails = JoinRoomScreenRoomDetails(name: spaceRoomProxy.name,
|
||||
topic: spaceRoomProxy.topic,
|
||||
canonicalAlias: spaceRoomProxy.canonicalAlias,
|
||||
avatar: spaceRoomProxy.avatar,
|
||||
memberCount: spaceRoomProxy.joinedMembersCount,
|
||||
heroes: spaceRoomProxy.heroes,
|
||||
private func updateSpaceRoomDetails(spaceServiceRoom: SpaceServiceRoomProtocol, inviter: RoomInviterDetails?) async {
|
||||
state.roomDetails = JoinRoomScreenRoomDetails(name: spaceServiceRoom.name,
|
||||
topic: spaceServiceRoom.topic,
|
||||
canonicalAlias: spaceServiceRoom.canonicalAlias,
|
||||
avatar: spaceServiceRoom.avatar,
|
||||
memberCount: spaceServiceRoom.joinedMembersCount,
|
||||
heroes: spaceServiceRoom.heroes,
|
||||
inviter: inviter,
|
||||
isDirect: spaceRoomProxy.isDirect,
|
||||
isSpace: spaceRoomProxy.isSpace,
|
||||
childrenCount: spaceRoomProxy.childrenCount,
|
||||
spaceVisibility: spaceRoomProxy.visibility)
|
||||
isDirect: spaceServiceRoom.isDirect,
|
||||
isSpace: spaceServiceRoom.isSpace,
|
||||
childrenCount: spaceServiceRoom.childrenCount,
|
||||
spaceVisibility: spaceServiceRoom.visibility)
|
||||
}
|
||||
|
||||
private func updateMode() async {
|
||||
@@ -225,16 +225,16 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
return
|
||||
}
|
||||
|
||||
if case .space(let spaceRoomProxy) = source {
|
||||
switch spaceRoomProxy.state {
|
||||
if case .space(let spaceServiceRoom) = source {
|
||||
switch spaceServiceRoom.state {
|
||||
case .invited:
|
||||
state.mode = .invited(isDM: spaceRoomProxy.isDirect == true && spaceRoomProxy.joinedMembersCount == 1)
|
||||
state.mode = .invited(isDM: spaceServiceRoom.isDirect == true && spaceServiceRoom.joinedMembersCount == 1)
|
||||
case .knocked:
|
||||
state.mode = .knocked
|
||||
case .banned:
|
||||
state.mode = .banned(sender: nil, reason: nil)
|
||||
default:
|
||||
switch spaceRoomProxy.joinRule {
|
||||
switch spaceServiceRoom.joinRule {
|
||||
case .private, .invite:
|
||||
state.mode = .inviteRequired
|
||||
case .knock, .knockRestricted:
|
||||
|
||||
@@ -445,7 +445,7 @@ struct JoinRoomScreenPreviewWrapper: Identifiable {
|
||||
}
|
||||
|
||||
let source: JoinRoomScreenSource = if isSpace {
|
||||
.space(SpaceRoomProxyMock(mode: mode))
|
||||
.space(SpaceServiceRoomMock(mode: mode))
|
||||
} else {
|
||||
.generic(roomID: "1", via: [])
|
||||
}
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ enum ManageAuthorizedSpacesScreenViewAction {
|
||||
}
|
||||
|
||||
struct AuthorizedSpacesSelection {
|
||||
let joinedSpaces: [SpaceRoomProxyProtocol]
|
||||
let joinedSpaces: [SpaceServiceRoomProtocol]
|
||||
let unknownSpacesIDs: [String]
|
||||
let initialSelectedIDs: Set<String>
|
||||
let selectedIDs: PassthroughSubject<Set<String>, Never> = .init()
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ struct ManageAuthorizedSpacesScreen: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func avatar(space: SpaceRoomProxyProtocol) -> some View {
|
||||
private func avatar(space: SpaceServiceRoomProtocol) -> some View {
|
||||
RoomAvatarImage(avatar: space.avatar,
|
||||
avatarSize: .room(on: .authorizedSpaces),
|
||||
mediaProvider: context.mediaProvider)
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
|
||||
var canEditHistoryVisibility = false
|
||||
|
||||
/// The union of joined parent spaces and the joined spaces in the current access type
|
||||
var selectableJoinedSpaces: [SpaceRoomProxyProtocol] = []
|
||||
var selectableJoinedSpaces: [SpaceServiceRoomProtocol] = []
|
||||
|
||||
/// The count of the intersection between the set of joined parent spaces and the set of spaces in the current access type
|
||||
var selectableSpacesCount: Int {
|
||||
@@ -118,7 +118,7 @@ struct SecurityAndPrivacyScreenViewState: BindableState {
|
||||
|
||||
enum SpaceSelection {
|
||||
/// There is only one available parent space for selection and is joined by the user
|
||||
case singleJoined(SpaceRoomProxyProtocol)
|
||||
case singleJoined(SpaceServiceRoomProtocol)
|
||||
/// There is only one available space for selection and is unknown to the user
|
||||
case singleUnknown(id: String)
|
||||
/// Multiple spaces are available for selection
|
||||
|
||||
+2
-2
@@ -305,7 +305,7 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
|
||||
}
|
||||
|
||||
private func setupSelectableJoinedSpaces() async {
|
||||
var joinedParentSpaces: [SpaceRoomProxyProtocol] = []
|
||||
var joinedParentSpaces: [SpaceServiceRoomProtocol] = []
|
||||
switch await clientProxy.spaceService.joinedParents(childID: roomProxy.id) {
|
||||
case .success(let value):
|
||||
joinedParentSpaces = value
|
||||
@@ -313,7 +313,7 @@ class SecurityAndPrivacyScreenViewModel: SecurityAndPrivacyScreenViewModelType,
|
||||
break
|
||||
}
|
||||
|
||||
var nonParentJoinedSpaces: [SpaceRoomProxyProtocol] = []
|
||||
var nonParentJoinedSpaces: [SpaceServiceRoomProtocol] = []
|
||||
for spaceID in state.currentSettings.accessType.spaceIDs where !joinedParentSpaces.contains(where: { $0.id == spaceID }) {
|
||||
if case let .success(.some(space)) = await clientProxy.spaceService.spaceForIdentifier(spaceID: spaceID) {
|
||||
nonParentJoinedSpaces.append(space)
|
||||
|
||||
+4
-4
@@ -269,7 +269,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
AppSettings.resetAllSettings()
|
||||
let appSettings = AppSettings()
|
||||
appSettings.spaceSettingsEnabled = true
|
||||
let space = [SpaceRoomProxyProtocol].mockSingleRoom[0]
|
||||
let space = [SpaceServiceRoomProtocol].mockSingleRoom[0]
|
||||
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
@@ -286,7 +286,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
AppSettings.resetAllSettings()
|
||||
let appSettings = AppSettings()
|
||||
appSettings.spaceSettingsEnabled = true
|
||||
let spaces = [SpaceRoomProxyProtocol].mockJoinedSpaces
|
||||
let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces
|
||||
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
@@ -319,7 +319,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
let appSettings = AppSettings()
|
||||
appSettings.spaceSettingsEnabled = true
|
||||
appSettings.knockingEnabled = true
|
||||
let space = [SpaceRoomProxyProtocol].mockSingleRoom[0]
|
||||
let space = [SpaceServiceRoomProtocol].mockSingleRoom[0]
|
||||
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
@@ -337,7 +337,7 @@ struct SecurityAndPrivacyScreen_Previews: PreviewProvider, TestablePreview {
|
||||
let appSettings = AppSettings()
|
||||
appSettings.spaceSettingsEnabled = true
|
||||
appSettings.knockingEnabled = true
|
||||
let spaces = [SpaceRoomProxyProtocol].mockJoinedSpaces
|
||||
let spaces = [SpaceServiceRoomProtocol].mockJoinedSpaces
|
||||
|
||||
return SecurityAndPrivacyScreenViewModel(roomProxy: JoinedRoomProxyMock(.init(isEncrypted: false,
|
||||
canonicalAlias: "#room:matrix.org",
|
||||
|
||||
@@ -10,36 +10,36 @@ import Compound
|
||||
import SwiftUI
|
||||
|
||||
struct SpaceHeaderView: View {
|
||||
let spaceRoomProxy: SpaceRoomProxyProtocol
|
||||
let spaceServiceRoom: SpaceServiceRoomProtocol
|
||||
let mediaProvider: MediaProviderProtocol?
|
||||
|
||||
@State private var isPresentingTopic = false
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 16) {
|
||||
RoomAvatarImage(avatar: spaceRoomProxy.avatar,
|
||||
RoomAvatarImage(avatar: spaceServiceRoom.avatar,
|
||||
avatarSize: .room(on: .spaceHeader),
|
||||
mediaProvider: mediaProvider)
|
||||
.accessibilityHidden(true)
|
||||
|
||||
VStack(spacing: 8) {
|
||||
Text(spaceRoomProxy.name)
|
||||
Text(spaceServiceRoom.name)
|
||||
.font(.compound.headingLGBold)
|
||||
.foregroundStyle(.compound.textPrimary)
|
||||
.multilineTextAlignment(.center)
|
||||
|
||||
if let alias = spaceRoomProxy.canonicalAlias {
|
||||
if let alias = spaceServiceRoom.canonicalAlias {
|
||||
CopyTextButton(content: alias)
|
||||
}
|
||||
|
||||
spaceDetails
|
||||
|
||||
JoinedMembersBadgeView(heroes: spaceRoomProxy.heroes,
|
||||
joinedCount: spaceRoomProxy.joinedMembersCount,
|
||||
JoinedMembersBadgeView(heroes: spaceServiceRoom.heroes,
|
||||
joinedCount: spaceServiceRoom.joinedMembersCount,
|
||||
mediaProvider: mediaProvider)
|
||||
}
|
||||
|
||||
if let topic = spaceRoomProxy.topic {
|
||||
if let topic = spaceServiceRoom.topic {
|
||||
Button { isPresentingTopic = true } label: {
|
||||
Text(topic)
|
||||
.font(.compound.bodyMD)
|
||||
@@ -60,7 +60,7 @@ struct SpaceHeaderView: View {
|
||||
.frame(height: 1 / UIScreen.main.scale)
|
||||
}
|
||||
.sheet(isPresented: $isPresentingTopic) {
|
||||
if let topic = spaceRoomProxy.topic {
|
||||
if let topic = spaceServiceRoom.topic {
|
||||
SpaceHeaderTopicSheetView(topic: topic)
|
||||
}
|
||||
}
|
||||
@@ -79,7 +79,7 @@ struct SpaceHeaderView: View {
|
||||
}
|
||||
|
||||
private var spaceDetailsVisibilityTitle: String {
|
||||
switch spaceRoomProxy.visibility {
|
||||
switch spaceServiceRoom.visibility {
|
||||
case .public: L10n.commonPublicSpace
|
||||
case .private: L10n.commonPrivateSpace
|
||||
case .restricted: L10n.commonSharedSpace
|
||||
@@ -88,7 +88,7 @@ struct SpaceHeaderView: View {
|
||||
}
|
||||
|
||||
private var spaceDetailsVisibilityIcon: KeyPath<CompoundIcons, Image> {
|
||||
switch spaceRoomProxy.visibility {
|
||||
switch spaceServiceRoom.visibility {
|
||||
case .public: \.public
|
||||
case .private: \.lock
|
||||
case .restricted: \.space
|
||||
@@ -107,41 +107,41 @@ struct SpaceHeaderView_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
VStack(spacing: 0) {
|
||||
ForEach(spaces, id: \.id) { space in
|
||||
SpaceHeaderView(spaceRoomProxy: space, mediaProvider: mediaProvider)
|
||||
SpaceHeaderView(spaceServiceRoom: space, mediaProvider: mediaProvider)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static func makeSpaceRooms() -> [SpaceRoomProxyMock] {
|
||||
static func makeSpaceRooms() -> [SpaceServiceRoomMock] {
|
||||
[
|
||||
SpaceRoomProxyMock(.init(id: "!space1:matrix.org",
|
||||
name: "Company Space",
|
||||
isSpace: true,
|
||||
childrenCount: 10,
|
||||
joinedMembersCount: 50)),
|
||||
SpaceRoomProxyMock(.init(id: "!space2:matrix.org",
|
||||
name: "Community Space",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
childrenCount: 20,
|
||||
joinedMembersCount: 78,
|
||||
topic: "Description of the space goes right here.",
|
||||
canonicalAlias: "#space:matrix.org",
|
||||
joinRule: .public)),
|
||||
SpaceRoomProxyMock(.init(id: "!space3:matrix.org",
|
||||
name: "Subspace",
|
||||
isSpace: true,
|
||||
childrenCount: 30,
|
||||
joinedMembersCount: 123,
|
||||
heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose],
|
||||
topic: ["Description of the space goes right here.",
|
||||
"Lorem ipsum dolor sit amet consectetur.",
|
||||
"Leo viverra morbi habitant in.",
|
||||
"Sem amet enim habitant nibh augue mauris.",
|
||||
"Interdum mauris ultrices tincidunt proin morbi erat aenean risus nibh.",
|
||||
"Diam amet sit fermentum vulputate faucibus."].joined(separator: " "),
|
||||
canonicalAlias: "#subspace:matrix.org",
|
||||
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
|
||||
SpaceServiceRoomMock(.init(id: "!space1:matrix.org",
|
||||
name: "Company Space",
|
||||
isSpace: true,
|
||||
childrenCount: 10,
|
||||
joinedMembersCount: 50)),
|
||||
SpaceServiceRoomMock(.init(id: "!space2:matrix.org",
|
||||
name: "Community Space",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
childrenCount: 20,
|
||||
joinedMembersCount: 78,
|
||||
topic: "Description of the space goes right here.",
|
||||
canonicalAlias: "#space:matrix.org",
|
||||
joinRule: .public)),
|
||||
SpaceServiceRoomMock(.init(id: "!space3:matrix.org",
|
||||
name: "Subspace",
|
||||
isSpace: true,
|
||||
childrenCount: 30,
|
||||
joinedMembersCount: 123,
|
||||
heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose],
|
||||
topic: ["Description of the space goes right here.",
|
||||
"Lorem ipsum dolor sit amet consectetur.",
|
||||
"Leo viverra morbi habitant in.",
|
||||
"Sem amet enim habitant nibh augue mauris.",
|
||||
"Interdum mauris ultrices tincidunt proin morbi erat aenean risus nibh.",
|
||||
"Diam amet sit fermentum vulputate faucibus."].joined(separator: " "),
|
||||
canonicalAlias: "#subspace:matrix.org",
|
||||
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,32 +13,32 @@ import SwiftUI
|
||||
struct SpaceRoomCell: View {
|
||||
@Environment(\.dynamicTypeSize) var dynamicTypeSize
|
||||
|
||||
let spaceRoomProxy: SpaceRoomProxyProtocol
|
||||
let spaceServiceRoom: SpaceServiceRoomProtocol
|
||||
let isSelected: Bool
|
||||
var isJoining = false
|
||||
let mediaProvider: MediaProviderProtocol!
|
||||
|
||||
enum Action { case select(SpaceRoomProxyProtocol), join(SpaceRoomProxyProtocol) }
|
||||
enum Action { case select(SpaceServiceRoomProtocol), join(SpaceServiceRoomProtocol) }
|
||||
let action: (Action) -> Void
|
||||
|
||||
private let verticalInsets = 12.0
|
||||
private let horizontalInsets = 16.0
|
||||
|
||||
private var subtitle: String {
|
||||
if spaceRoomProxy.isSpace {
|
||||
switch spaceRoomProxy.visibility {
|
||||
if spaceServiceRoom.isSpace {
|
||||
switch spaceServiceRoom.visibility {
|
||||
case .public: L10n.commonPublicSpace
|
||||
case .private: L10n.commonPrivateSpace
|
||||
case .restricted: L10n.commonSharedSpace
|
||||
case .none: L10n.commonPrivateSpace
|
||||
}
|
||||
} else {
|
||||
L10n.commonMemberCount(spaceRoomProxy.joinedMembersCount)
|
||||
L10n.commonMemberCount(spaceServiceRoom.joinedMembersCount)
|
||||
}
|
||||
}
|
||||
|
||||
var visibilityIcon: KeyPath<CompoundIcons, Image>? {
|
||||
switch spaceRoomProxy.visibility {
|
||||
switch spaceServiceRoom.visibility {
|
||||
case .public: \.public
|
||||
case .private: \.lockSolid
|
||||
case .restricted: nil
|
||||
@@ -47,16 +47,16 @@ struct SpaceRoomCell: View {
|
||||
}
|
||||
|
||||
private var details: String {
|
||||
if spaceRoomProxy.isSpace {
|
||||
L10n.commonMemberCount(spaceRoomProxy.joinedMembersCount)
|
||||
if spaceServiceRoom.isSpace {
|
||||
L10n.commonMemberCount(spaceServiceRoom.joinedMembersCount)
|
||||
} else {
|
||||
spaceRoomProxy.topic ?? " " // Use a single space to reserve a consistent amount of space.
|
||||
spaceServiceRoom.topic ?? " " // Use a single space to reserve a consistent amount of space.
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
action(.select(spaceRoomProxy))
|
||||
action(.select(spaceServiceRoom))
|
||||
} label: {
|
||||
HStack(spacing: 16.0) {
|
||||
avatar
|
||||
@@ -74,13 +74,13 @@ struct SpaceRoomCell: View {
|
||||
.accessibilityElement(children: .combine)
|
||||
}
|
||||
.buttonStyle(SpaceRoomCellButtonStyle(isSelected: isSelected))
|
||||
.accessibilityIdentifier(A11yIdentifiers.spaceListScreen.spaceRoomName(spaceRoomProxy.name))
|
||||
.accessibilityIdentifier(A11yIdentifiers.spaceListScreen.spaceRoomName(spaceServiceRoom.name))
|
||||
}
|
||||
|
||||
@ViewBuilder @MainActor
|
||||
private var avatar: some View {
|
||||
if dynamicTypeSize < .accessibility3 {
|
||||
RoomAvatarImage(avatar: spaceRoomProxy.avatar,
|
||||
RoomAvatarImage(avatar: spaceServiceRoom.avatar,
|
||||
avatarSize: .room(on: .spaces),
|
||||
mediaProvider: mediaProvider)
|
||||
.dynamicTypeSize(dynamicTypeSize < .accessibility1 ? dynamicTypeSize : .accessibility1)
|
||||
@@ -91,7 +91,7 @@ struct SpaceRoomCell: View {
|
||||
private var content: some View {
|
||||
HStack(spacing: 16) {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(spaceRoomProxy.name)
|
||||
Text(spaceServiceRoom.name)
|
||||
.font(.compound.bodyLGSemibold)
|
||||
.foregroundColor(.compound.textPrimary)
|
||||
.lineLimit(1)
|
||||
@@ -128,9 +128,9 @@ struct SpaceRoomCell: View {
|
||||
|
||||
@ViewBuilder
|
||||
private var accessory: some View {
|
||||
switch spaceRoomProxy.state {
|
||||
switch spaceServiceRoom.state {
|
||||
case .none, .left, .invited:
|
||||
Button(L10n.actionJoin) { action(.join(spaceRoomProxy)) }
|
||||
Button(L10n.actionJoin) { action(.join(spaceServiceRoom)) }
|
||||
.font(.compound.bodyLG)
|
||||
.foregroundStyle(.compound.textActionAccent)
|
||||
.opacity(isJoining ? 0 : 1)
|
||||
@@ -159,21 +159,21 @@ struct SpaceRoomCellButtonStyle: ButtonStyle {
|
||||
struct SpaceRoomCell_Previews: PreviewProvider, TestablePreview {
|
||||
static let mediaProvider = MediaProviderMock(configuration: .init())
|
||||
|
||||
static let spaces = [SpaceRoomProxyProtocol].mockSpaceList
|
||||
static let spaces = [SpaceServiceRoomProtocol].mockSpaceList
|
||||
|
||||
static var previews: some View {
|
||||
VStack(spacing: 0) {
|
||||
ForEach(spaces, id: \.id) { space in
|
||||
SpaceRoomCell(spaceRoomProxy: space,
|
||||
SpaceRoomCell(spaceServiceRoom: space,
|
||||
isSelected: false,
|
||||
mediaProvider: mediaProvider) { _ in }
|
||||
}
|
||||
|
||||
SpaceRoomCell(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "Space being joined", isSpace: true)),
|
||||
SpaceRoomCell(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "Space being joined", isSpace: true)),
|
||||
isSelected: false,
|
||||
isJoining: true,
|
||||
mediaProvider: mediaProvider) { _ in }
|
||||
SpaceRoomCell(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "Room being joined", isSpace: false)),
|
||||
SpaceRoomCell(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "Room being joined", isSpace: false)),
|
||||
isSelected: false,
|
||||
isJoining: true,
|
||||
mediaProvider: mediaProvider) { _ in }
|
||||
|
||||
@@ -19,13 +19,13 @@ struct LeaveSpaceRoomDetailsCell: View {
|
||||
let action: () -> Void
|
||||
|
||||
private var subtitle: String? {
|
||||
guard !room.spaceRoomProxy.isSpace else { return nil }
|
||||
let memberCount = L10n.commonMemberCount(room.spaceRoomProxy.joinedMembersCount)
|
||||
guard !room.spaceServiceRoom.isSpace else { return nil }
|
||||
let memberCount = L10n.commonMemberCount(room.spaceServiceRoom.joinedMembersCount)
|
||||
return room.isLastAdmin ? L10n.screenLeaveSpaceLastAdminInfo(memberCount) : memberCount
|
||||
}
|
||||
|
||||
var visibilityIcon: KeyPath<CompoundIcons, Image>? {
|
||||
switch room.spaceRoomProxy.visibility {
|
||||
switch room.spaceServiceRoom.visibility {
|
||||
case .public: \.public
|
||||
case .private: \.lockSolid
|
||||
case .restricted: nil
|
||||
@@ -37,13 +37,13 @@ struct LeaveSpaceRoomDetailsCell: View {
|
||||
Button(action: action) {
|
||||
HStack(spacing: 16) {
|
||||
if dynamicTypeSize < .accessibility3 {
|
||||
RoomAvatarImage(avatar: room.spaceRoomProxy.avatar,
|
||||
RoomAvatarImage(avatar: room.spaceServiceRoom.avatar,
|
||||
avatarSize: .room(on: .leaveSpace),
|
||||
mediaProvider: mediaProvider)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(room.spaceRoomProxy.name)
|
||||
Text(room.spaceServiceRoom.name)
|
||||
.font(.compound.bodyLGSemibold)
|
||||
.foregroundStyle(.compound.textPrimary)
|
||||
.lineLimit(1)
|
||||
@@ -91,40 +91,40 @@ struct LeaveSpaceRoomDetailsCell: View {
|
||||
struct LeaveSpaceRoomDetailsCell_Previews: PreviewProvider, TestablePreview {
|
||||
static var previews: some View {
|
||||
VStack(spacing: 0) {
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "1",
|
||||
name: "Space",
|
||||
isSpace: true)),
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "1",
|
||||
name: "Space",
|
||||
isSpace: true)),
|
||||
isLastAdmin: false,
|
||||
isSelected: true),
|
||||
mediaProvider: MediaProviderMock(configuration: .init())) { }
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "2",
|
||||
name: "My Space",
|
||||
isSpace: true)),
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "2",
|
||||
name: "My Space",
|
||||
isSpace: true)),
|
||||
isLastAdmin: true,
|
||||
isSelected: false),
|
||||
mediaProvider: MediaProviderMock(configuration: .init())) { }
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "2",
|
||||
name: "My Space",
|
||||
isSpace: true)),
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "2",
|
||||
name: "My Space",
|
||||
isSpace: true)),
|
||||
isLastAdmin: true,
|
||||
isSelected: false),
|
||||
hideSelection: true,
|
||||
mediaProvider: MediaProviderMock(configuration: .init())) { }
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "3",
|
||||
name: "Room",
|
||||
isSpace: false)),
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "3",
|
||||
name: "Room",
|
||||
isSpace: false)),
|
||||
isLastAdmin: false,
|
||||
isSelected: true),
|
||||
mediaProvider: MediaProviderMock(configuration: .init())) { }
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "4",
|
||||
name: "My Room",
|
||||
isSpace: false)),
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "4",
|
||||
name: "My Room",
|
||||
isSpace: false)),
|
||||
isLastAdmin: true,
|
||||
isSelected: false),
|
||||
mediaProvider: MediaProviderMock(configuration: .init())) { }
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceRoomProxy: SpaceRoomProxyMock(.init(id: "4",
|
||||
name: "My Room",
|
||||
isSpace: false)),
|
||||
LeaveSpaceRoomDetailsCell(room: .init(spaceServiceRoom: SpaceServiceRoomMock(.init(id: "4",
|
||||
name: "My Room",
|
||||
isSpace: false)),
|
||||
isLastAdmin: true,
|
||||
isSelected: false),
|
||||
hideSelection: true,
|
||||
|
||||
@@ -64,11 +64,11 @@ struct LeaveSpaceView: View {
|
||||
context.viewState.leaveHandle.canLeave {
|
||||
LazyVStack(spacing: 0, pinnedViews: .sectionHeaders) {
|
||||
Section {
|
||||
ForEach(context.viewState.leaveHandle.rooms, id: \.spaceRoomProxy.id) { room in
|
||||
ForEach(context.viewState.leaveHandle.rooms, id: \.spaceServiceRoom.id) { room in
|
||||
LeaveSpaceRoomDetailsCell(room: room,
|
||||
hideSelection: context.viewState.leaveHandle.mode == .onlyAdminRooms,
|
||||
mediaProvider: context.mediaProvider) {
|
||||
context.send(viewAction: .toggleRoom(roomID: room.spaceRoomProxy.id))
|
||||
context.send(viewAction: .toggleRoom(roomID: room.spaceServiceRoom.id))
|
||||
}
|
||||
.disabled(room.isLastAdmin)
|
||||
}
|
||||
@@ -136,27 +136,27 @@ struct LeaveSpaceView_Previews: PreviewProvider, TestablePreview {
|
||||
.previewDisplayName("Last Space Admin")
|
||||
}
|
||||
|
||||
static let spaceRoomProxy = SpaceRoomProxyMock(.init(id: "!eng-space:matrix.org",
|
||||
name: "Engineering Team",
|
||||
isSpace: true,
|
||||
childrenCount: 30,
|
||||
joinedMembersCount: 76,
|
||||
heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose],
|
||||
topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.",
|
||||
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
|
||||
static let spaceServiceRoom = SpaceServiceRoomMock(.init(id: "!eng-space:matrix.org",
|
||||
name: "Engineering Team",
|
||||
isSpace: true,
|
||||
childrenCount: 30,
|
||||
joinedMembersCount: 76,
|
||||
heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose],
|
||||
topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.",
|
||||
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
|
||||
|
||||
static func makeViewModel(mode: LeaveSpaceHandleProxy.Mode) -> LeaveSpaceViewModel {
|
||||
let rooms: [LeaveSpaceRoom] = switch mode {
|
||||
case .manyRooms: .mockRooms
|
||||
case .onlyAdminRooms: .mockAdminRooms
|
||||
case .noRooms: .mockSingleSpace(spaceRoomProxy: spaceRoomProxy, isLastAdmin: false)
|
||||
case .lastSpaceAdmin: .mockRoomsWithSpace(spaceRoomProxy: spaceRoomProxy, isLastAdmin: true)
|
||||
case .noRooms: .mockSingleSpace(spaceServiceRoom: spaceServiceRoom, isLastAdmin: false)
|
||||
case .lastSpaceAdmin: .mockRoomsWithSpace(spaceServiceRoom: spaceServiceRoom, isLastAdmin: true)
|
||||
}
|
||||
|
||||
let leaveHandle = LeaveSpaceHandleProxy(spaceID: spaceRoomProxy.id,
|
||||
let leaveHandle = LeaveSpaceHandleProxy(spaceID: spaceServiceRoom.id,
|
||||
leaveHandle: LeaveSpaceHandleSDKMock(.init(rooms: rooms)))
|
||||
|
||||
return LeaveSpaceViewModel(spaceName: spaceRoomProxy.name,
|
||||
return LeaveSpaceViewModel(spaceName: spaceServiceRoom.name,
|
||||
canEditRolesAndPermissions: true,
|
||||
leaveHandle: leaveHandle,
|
||||
userIndicatorController: UserIndicatorControllerMock(),
|
||||
|
||||
@@ -18,7 +18,7 @@ struct SpaceListScreenViewState: BindableState {
|
||||
var userDisplayName: String?
|
||||
var userAvatarURL: URL?
|
||||
|
||||
var topLevelSpaces: [SpaceRoomProxyProtocol]
|
||||
var topLevelSpaces: [SpaceServiceRoomProtocol]
|
||||
var selectedSpaceID: String?
|
||||
|
||||
var isCreateSpaceEnabled: Bool
|
||||
|
||||
@@ -65,8 +65,8 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
||||
MXLog.info("View model: received view action: \(viewAction)")
|
||||
|
||||
switch viewAction {
|
||||
case .spaceAction(.select(let spaceRoomProxy)):
|
||||
Task { await selectSpace(spaceRoomProxy) }
|
||||
case .spaceAction(.select(let spaceServiceRoom)):
|
||||
Task { await selectSpace(spaceServiceRoom) }
|
||||
case .spaceAction(.join):
|
||||
fatalError("There shouldn't be any unjoined spaces in the joined spaces list.")
|
||||
case .showSettings:
|
||||
@@ -86,8 +86,8 @@ class SpaceListScreenViewModel: SpaceListScreenViewModelType, SpaceListScreenVie
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func selectSpace(_ spaceRoomProxy: SpaceRoomProxyProtocol) async {
|
||||
switch await spaceServiceProxy.spaceRoomList(spaceID: spaceRoomProxy.id) {
|
||||
private func selectSpace(_ spaceServiceRoom: SpaceServiceRoomProtocol) async {
|
||||
switch await spaceServiceProxy.spaceRoomList(spaceID: spaceServiceRoom.id) {
|
||||
case .success(let spaceRoomListProxy):
|
||||
actionsSubject.send(.selectSpace(spaceRoomListProxy))
|
||||
case .failure(let error):
|
||||
|
||||
@@ -85,9 +85,9 @@ struct SpaceListScreen: View {
|
||||
}
|
||||
|
||||
private var spaces: some View {
|
||||
ForEach(context.viewState.topLevelSpaces, id: \.id) { spaceRoomProxy in
|
||||
SpaceRoomCell(spaceRoomProxy: spaceRoomProxy,
|
||||
isSelected: spaceRoomProxy.id == context.viewState.selectedSpaceID,
|
||||
ForEach(context.viewState.topLevelSpaces, id: \.id) { spaceServiceRoom in
|
||||
SpaceRoomCell(spaceServiceRoom: spaceServiceRoom,
|
||||
isSelected: spaceServiceRoom.id == context.viewState.selectedSpaceID,
|
||||
mediaProvider: context.mediaProvider) { action in
|
||||
context.send(viewAction: .spaceAction(action))
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ struct SpaceScreenCoordinatorParameters {
|
||||
|
||||
enum SpaceScreenCoordinatorAction {
|
||||
case selectSpace(SpaceRoomListProxyProtocol)
|
||||
case selectUnjoinedSpace(SpaceRoomProxyProtocol)
|
||||
case selectUnjoinedSpace(SpaceServiceRoomProtocol)
|
||||
case selectRoom(roomID: String)
|
||||
case leftSpace
|
||||
case displayMembers(roomProxy: JoinedRoomProxyProtocol)
|
||||
@@ -60,8 +60,8 @@ final class SpaceScreenCoordinator: CoordinatorProtocol {
|
||||
switch action {
|
||||
case .selectSpace(let spaceRoomListProxy):
|
||||
actionsSubject.send(.selectSpace(spaceRoomListProxy))
|
||||
case .selectUnjoinedSpace(let spaceRoomProxy):
|
||||
actionsSubject.send(.selectUnjoinedSpace(spaceRoomProxy))
|
||||
case .selectUnjoinedSpace(let spaceServiceRoom):
|
||||
actionsSubject.send(.selectUnjoinedSpace(spaceServiceRoom))
|
||||
case .selectRoom(let roomID):
|
||||
actionsSubject.send(.selectRoom(roomID: roomID))
|
||||
case .leftSpace:
|
||||
|
||||
@@ -10,7 +10,7 @@ import Foundation
|
||||
|
||||
enum SpaceScreenViewModelAction {
|
||||
case selectSpace(SpaceRoomListProxyProtocol)
|
||||
case selectUnjoinedSpace(SpaceRoomProxyProtocol)
|
||||
case selectUnjoinedSpace(SpaceServiceRoomProtocol)
|
||||
case selectRoom(roomID: String)
|
||||
case leftSpace
|
||||
case presentRolesAndPermissions(roomProxy: JoinedRoomProxyProtocol)
|
||||
@@ -19,13 +19,13 @@ enum SpaceScreenViewModelAction {
|
||||
}
|
||||
|
||||
struct SpaceScreenViewState: BindableState {
|
||||
var space: SpaceRoomProxyProtocol
|
||||
var space: SpaceServiceRoomProtocol
|
||||
|
||||
var permalink: URL?
|
||||
var roomProxy: JoinedRoomProxyProtocol?
|
||||
|
||||
var isPaginating = false
|
||||
var rooms: [SpaceRoomProxyProtocol]
|
||||
var rooms: [SpaceServiceRoomProtocol]
|
||||
var selectedSpaceRoomID: String?
|
||||
var joiningRoomIDs: Set<String> = []
|
||||
|
||||
|
||||
@@ -37,12 +37,12 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.appSettings = appSettings
|
||||
|
||||
super.init(initialViewState: SpaceScreenViewState(space: spaceRoomListProxy.spaceRoomProxyPublisher.value,
|
||||
super.init(initialViewState: SpaceScreenViewState(space: spaceRoomListProxy.spaceServiceRoomPublisher.value,
|
||||
rooms: spaceRoomListProxy.spaceRoomsPublisher.value,
|
||||
selectedSpaceRoomID: selectedSpaceRoomPublisher.value),
|
||||
mediaProvider: userSession.mediaProvider)
|
||||
|
||||
spaceRoomListProxy.spaceRoomProxyPublisher
|
||||
spaceRoomListProxy.spaceServiceRoomPublisher
|
||||
.receive(on: DispatchQueue.main)
|
||||
.weakAssign(to: \.state.space, on: self)
|
||||
.store(in: &cancellables)
|
||||
@@ -107,19 +107,19 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
MXLog.info("View model: received view action: \(viewAction)")
|
||||
|
||||
switch viewAction {
|
||||
case .spaceAction(.select(let spaceRoomProxy)):
|
||||
if spaceRoomProxy.isSpace {
|
||||
if spaceRoomProxy.state != .joined {
|
||||
actionsSubject.send(.selectUnjoinedSpace(spaceRoomProxy))
|
||||
case .spaceAction(.select(let spaceServiceRoom)):
|
||||
if spaceServiceRoom.isSpace {
|
||||
if spaceServiceRoom.state != .joined {
|
||||
actionsSubject.send(.selectUnjoinedSpace(spaceServiceRoom))
|
||||
} else {
|
||||
Task { await selectSpace(spaceRoomProxy) }
|
||||
Task { await selectSpace(spaceServiceRoom) }
|
||||
}
|
||||
} else {
|
||||
// No need to check the join state, the room flow will show an appropriately configured join screen if needed.
|
||||
actionsSubject.send(.selectRoom(roomID: spaceRoomProxy.id))
|
||||
actionsSubject.send(.selectRoom(roomID: spaceServiceRoom.id))
|
||||
}
|
||||
case .spaceAction(.join(let spaceRoomProxy)):
|
||||
Task { await join(spaceRoomProxy) }
|
||||
case .spaceAction(.join(let spaceServiceRoom)):
|
||||
Task { await join(spaceServiceRoom) }
|
||||
case .leaveSpace:
|
||||
Task { await showLeaveSpaceConfirmation() }
|
||||
case .displayMembers(let roomProxy):
|
||||
@@ -136,11 +136,11 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func join(_ spaceRoomProxy: SpaceRoomProxyProtocol) async {
|
||||
state.joiningRoomIDs.insert(spaceRoomProxy.id)
|
||||
defer { state.joiningRoomIDs.remove(spaceRoomProxy.id) }
|
||||
private func join(_ spaceServiceRoom: SpaceServiceRoomProtocol) async {
|
||||
state.joiningRoomIDs.insert(spaceServiceRoom.id)
|
||||
defer { state.joiningRoomIDs.remove(spaceServiceRoom.id) }
|
||||
|
||||
guard case .success = await clientProxy.joinRoom(spaceRoomProxy.id, via: spaceRoomProxy.via) else {
|
||||
guard case .success = await clientProxy.joinRoom(spaceServiceRoom.id, via: spaceServiceRoom.via) else {
|
||||
showFailureIndicator()
|
||||
return
|
||||
}
|
||||
@@ -148,8 +148,8 @@ class SpaceScreenViewModel: SpaceScreenViewModelType, SpaceScreenViewModelProtoc
|
||||
// We don't want to show the space room after joining it this way 🤷♂️
|
||||
}
|
||||
|
||||
private func selectSpace(_ spaceRoomProxy: SpaceRoomProxyProtocol) async {
|
||||
switch await spaceServiceProxy.spaceRoomList(spaceID: spaceRoomProxy.id) {
|
||||
private func selectSpace(_ spaceServiceRoom: SpaceServiceRoomProtocol) async {
|
||||
switch await spaceServiceProxy.spaceRoomList(spaceID: spaceServiceRoom.id) {
|
||||
case .success(let spaceRoomListProxy):
|
||||
actionsSubject.send(.selectSpace(spaceRoomListProxy))
|
||||
case .failure(let error):
|
||||
|
||||
@@ -15,7 +15,7 @@ struct SpaceScreen: View {
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack(spacing: 0) {
|
||||
SpaceHeaderView(spaceRoomProxy: context.viewState.space,
|
||||
SpaceHeaderView(spaceServiceRoom: context.viewState.space,
|
||||
mediaProvider: context.mediaProvider)
|
||||
rooms
|
||||
}
|
||||
@@ -32,10 +32,10 @@ struct SpaceScreen: View {
|
||||
|
||||
@ViewBuilder
|
||||
var rooms: some View {
|
||||
ForEach(context.viewState.rooms, id: \.id) { spaceRoomProxy in
|
||||
SpaceRoomCell(spaceRoomProxy: spaceRoomProxy,
|
||||
isSelected: spaceRoomProxy.id == context.viewState.selectedSpaceRoomID,
|
||||
isJoining: context.viewState.joiningRoomIDs.contains(spaceRoomProxy.id),
|
||||
ForEach(context.viewState.rooms, id: \.id) { spaceServiceRoom in
|
||||
SpaceRoomCell(spaceServiceRoom: spaceServiceRoom,
|
||||
isSelected: spaceServiceRoom.id == context.viewState.selectedSpaceRoomID,
|
||||
isJoining: context.viewState.joiningRoomIDs.contains(spaceServiceRoom.id),
|
||||
mediaProvider: context.mediaProvider) { action in
|
||||
context.send(viewAction: .spaceAction(action))
|
||||
}
|
||||
@@ -114,16 +114,16 @@ struct SpaceScreen_Previews: PreviewProvider, TestablePreview {
|
||||
}
|
||||
|
||||
static func makeViewModel() -> SpaceScreenViewModel {
|
||||
let spaceRoomProxy = SpaceRoomProxyMock(.init(id: "!eng-space:matrix.org",
|
||||
name: "Engineering Team",
|
||||
isSpace: true,
|
||||
childrenCount: 30,
|
||||
joinedMembersCount: 76,
|
||||
heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose],
|
||||
topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.",
|
||||
canonicalAlias: "#engineering-team:element.io",
|
||||
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
|
||||
let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceRoomProxy: spaceRoomProxy,
|
||||
let spaceServiceRoom = SpaceServiceRoomMock(.init(id: "!eng-space:matrix.org",
|
||||
name: "Engineering Team",
|
||||
isSpace: true,
|
||||
childrenCount: 30,
|
||||
joinedMembersCount: 76,
|
||||
heroes: [.mockDan, .mockBob, .mockCharlie, .mockVerbose],
|
||||
topic: "Description of the space goes right here. Lorem ipsum dolor sit amet consectetur. Leo viverra morbi habitant in.",
|
||||
canonicalAlias: "#engineering-team:element.io",
|
||||
joinRule: .knockRestricted(rules: [.roomMembership(roomId: "")])))
|
||||
let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceServiceRoom: spaceServiceRoom,
|
||||
initialSpaceRooms: .mockSpaceList))
|
||||
|
||||
let clientProxy = ClientProxyMock(.init())
|
||||
|
||||
@@ -35,7 +35,7 @@ final class LeaveSpaceHandleProxy {
|
||||
room.spaceRoom.roomId != spaceID else {
|
||||
return nil
|
||||
}
|
||||
return .init(spaceRoomProxy: SpaceRoomProxy(spaceRoom: room.spaceRoom),
|
||||
return .init(spaceServiceRoom: SpaceServiceRoom(spaceRoom: room.spaceRoom),
|
||||
isLastAdmin: room.isLastAdmin,
|
||||
isSelected: !room.isLastAdmin)
|
||||
}
|
||||
@@ -64,21 +64,21 @@ final class LeaveSpaceHandleProxy {
|
||||
}
|
||||
|
||||
func toggleRoom(roomID: String) {
|
||||
guard let room = rooms.first(where: { $0.spaceRoomProxy.id == roomID }) else {
|
||||
guard let room = rooms.first(where: { $0.spaceServiceRoom.id == roomID }) else {
|
||||
return
|
||||
}
|
||||
room.isSelected.toggle()
|
||||
}
|
||||
|
||||
func leave() async -> Result<Void, SpaceServiceProxyError> {
|
||||
let selectedRoomIDs = rooms.filter(\.isSelected).map(\.spaceRoomProxy.id)
|
||||
let selectedRoomIDs = rooms.filter(\.isSelected).map(\.spaceServiceRoom.id)
|
||||
|
||||
do {
|
||||
return try await .success(leaveHandle.leave(roomIds: selectedRoomIDs + [id]))
|
||||
} catch {
|
||||
MXLog.error("Failed leaving space \(id): \(error)")
|
||||
rooms = rooms.filter { leaveRoom in
|
||||
leaveHandle.rooms().contains { $0.spaceRoom.roomId == leaveRoom.spaceRoomProxy.id }
|
||||
leaveHandle.rooms().contains { $0.spaceRoom.roomId == leaveRoom.spaceServiceRoom.id }
|
||||
}
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
@@ -86,12 +86,12 @@ final class LeaveSpaceHandleProxy {
|
||||
}
|
||||
|
||||
@Observable class LeaveSpaceRoomDetails {
|
||||
let spaceRoomProxy: SpaceRoomProxyProtocol
|
||||
let spaceServiceRoom: SpaceServiceRoomProtocol
|
||||
let isLastAdmin: Bool
|
||||
var isSelected: Bool
|
||||
|
||||
init(spaceRoomProxy: SpaceRoomProxyProtocol, isLastAdmin: Bool, isSelected: Bool) {
|
||||
self.spaceRoomProxy = spaceRoomProxy
|
||||
init(spaceServiceRoom: SpaceServiceRoomProtocol, isLastAdmin: Bool, isSelected: Bool) {
|
||||
self.spaceServiceRoom = spaceServiceRoom
|
||||
self.isLastAdmin = isLastAdmin
|
||||
self.isSelected = isSelected
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ import Combine
|
||||
import MatrixRustSDK
|
||||
|
||||
class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
|
||||
var id: String { spaceRoomProxyPublisher.value.id }
|
||||
var id: String { spaceServiceRoomPublisher.value.id }
|
||||
|
||||
private let spaceRoomList: SpaceRoomListProtocol
|
||||
|
||||
private var spaceRoomProxyHandle: TaskHandle?
|
||||
private let spaceRoomProxySubject: CurrentValueSubject<SpaceRoomProxyProtocol, Never>
|
||||
var spaceRoomProxyPublisher: CurrentValuePublisher<SpaceRoomProxyProtocol, Never> {
|
||||
spaceRoomProxySubject.asCurrentValuePublisher()
|
||||
private var spaceServiceRoomHandle: TaskHandle?
|
||||
private let spaceServiceRoomSubject: CurrentValueSubject<SpaceServiceRoomProtocol, Never>
|
||||
var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never> {
|
||||
spaceServiceRoomSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
private var spaceRoomsHandle: TaskHandle?
|
||||
private let spaceRoomsSubject = CurrentValueSubject<[SpaceRoomProxyProtocol], Never>([])
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> {
|
||||
private let spaceRoomsSubject = CurrentValueSubject<[SpaceServiceRoomProtocol], Never>([])
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
|
||||
spaceRoomsSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
|
||||
guard let spaceRoom = spaceRoomList.space() else { throw SpaceRoomListProxyError.missingSpace }
|
||||
|
||||
self.spaceRoomList = spaceRoomList
|
||||
spaceRoomProxySubject = .init(SpaceRoomProxy(spaceRoom: spaceRoom))
|
||||
spaceServiceRoomSubject = .init(SpaceServiceRoom(spaceRoom: spaceRoom))
|
||||
|
||||
let paginationStateSubject = CurrentValueSubject<SpaceRoomListPaginationState, Never>(spaceRoomList.paginationState())
|
||||
paginationStatePublisher = paginationStateSubject.asCurrentValuePublisher()
|
||||
@@ -46,9 +46,9 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
|
||||
self?.handleUpdates(updates)
|
||||
})
|
||||
|
||||
spaceRoomProxyHandle = spaceRoomList.subscribeToSpaceUpdates(listener: SDKListener { [weak self] spaceRoom in
|
||||
spaceServiceRoomHandle = spaceRoomList.subscribeToSpaceUpdates(listener: SDKListener { [weak self] spaceRoom in
|
||||
guard let spaceRoom else { return }
|
||||
self?.spaceRoomProxySubject.send(SpaceRoomProxy(spaceRoom: spaceRoom))
|
||||
self?.spaceServiceRoomSubject.send(SpaceServiceRoom(spaceRoom: spaceRoom))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -68,27 +68,27 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
|
||||
for update in updates {
|
||||
switch update {
|
||||
case .append(let spaceRooms):
|
||||
rooms.append(contentsOf: spaceRooms.map(SpaceRoomProxy.init))
|
||||
rooms.append(contentsOf: spaceRooms.map(SpaceServiceRoom.init))
|
||||
case .clear:
|
||||
rooms.removeAll()
|
||||
case .pushFront(let spaceRoom):
|
||||
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: 0)
|
||||
rooms.insert(SpaceServiceRoom(spaceRoom: spaceRoom), at: 0)
|
||||
case .pushBack(let spaceRoom):
|
||||
rooms.append(SpaceRoomProxy(spaceRoom: spaceRoom))
|
||||
rooms.append(SpaceServiceRoom(spaceRoom: spaceRoom))
|
||||
case .popFront:
|
||||
rooms.removeFirst()
|
||||
case .popBack:
|
||||
rooms.removeLast()
|
||||
case .insert(let index, let spaceRoom):
|
||||
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: Int(index))
|
||||
rooms.insert(SpaceServiceRoom(spaceRoom: spaceRoom), at: Int(index))
|
||||
case .set(let index, let spaceRoom):
|
||||
rooms[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom)
|
||||
rooms[Int(index)] = SpaceServiceRoom(spaceRoom: spaceRoom)
|
||||
case .remove(let index):
|
||||
rooms.remove(at: Int(index))
|
||||
case .truncate(let length):
|
||||
rooms.removeSubrange(Int(length)..<rooms.count)
|
||||
case .reset(let spaceRooms):
|
||||
rooms = spaceRooms.map(SpaceRoomProxy.init)
|
||||
rooms = spaceRooms.map(SpaceServiceRoom.init)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ enum SpaceRoomListProxyError: Error {
|
||||
protocol SpaceRoomListProxyProtocol {
|
||||
var id: String { get }
|
||||
|
||||
var spaceRoomProxyPublisher: CurrentValuePublisher<SpaceRoomProxyProtocol, Never> { get }
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { get }
|
||||
var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never> { get }
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> { get }
|
||||
var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never> { get }
|
||||
|
||||
func paginate() async
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
class SpaceRoomProxy: SpaceRoomProxyProtocol {
|
||||
private let spaceRoom: SpaceRoom
|
||||
|
||||
init(spaceRoom: SpaceRoom) {
|
||||
self.spaceRoom = spaceRoom
|
||||
}
|
||||
|
||||
lazy var id = spaceRoom.roomId
|
||||
var name: String { spaceRoom.displayName }
|
||||
var rawName: String? { spaceRoom.rawName }
|
||||
var avatarURL: URL? { spaceRoom.avatarUrl.flatMap(URL.init) }
|
||||
|
||||
var isSpace: Bool { spaceRoom.roomType == .space }
|
||||
var isDirect: Bool? { spaceRoom.isDirect }
|
||||
var childrenCount: Int { Int(spaceRoom.childrenCount) }
|
||||
|
||||
var joinedMembersCount: Int { Int(spaceRoom.numJoinedMembers) }
|
||||
var heroes: [UserProfileProxy] { (spaceRoom.heroes ?? []).map(UserProfileProxy.init) }
|
||||
var topic: String? { spaceRoom.topic }
|
||||
var canonicalAlias: String? { spaceRoom.canonicalAlias }
|
||||
|
||||
var joinRule: JoinRule? { spaceRoom.joinRule }
|
||||
var worldReadable: Bool? { spaceRoom.worldReadable }
|
||||
var guestCanJoin: Bool { spaceRoom.guestCanJoin }
|
||||
var state: Membership? { spaceRoom.state }
|
||||
var via: [String] { spaceRoom.via }
|
||||
}
|
||||
@@ -14,8 +14,8 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
private let spaceService: SpaceServiceProtocol
|
||||
|
||||
private var topLevelSpacesHandle: TaskHandle?
|
||||
private let spacesSubject = CurrentValueSubject<[SpaceRoomProxyProtocol], Never>([])
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> {
|
||||
private let spacesSubject = CurrentValueSubject<[SpaceServiceRoomProtocol], Never>([])
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
|
||||
spacesSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
@@ -40,9 +40,9 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError> {
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError> {
|
||||
do {
|
||||
return try await .success(spaceService.getSpaceRoom(roomId: spaceID).map(SpaceRoomProxy.init))
|
||||
return try await .success(spaceService.getSpaceRoom(roomId: spaceID).map(SpaceServiceRoom.init))
|
||||
} catch {
|
||||
MXLog.error("Failed getting space room for \(spaceID): \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
@@ -58,9 +58,9 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError> {
|
||||
func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError> {
|
||||
do {
|
||||
return try await .success(spaceService.joinedParentsOfChild(childId: childID).map(SpaceRoomProxy.init))
|
||||
return try await .success(spaceService.joinedParentsOfChild(childId: childID).map(SpaceServiceRoom.init))
|
||||
} catch {
|
||||
MXLog.error("Failed to get joined parents for \(childID): \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
@@ -75,27 +75,27 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
for update in updates {
|
||||
switch update {
|
||||
case .append(let spaceRooms):
|
||||
spaces.append(contentsOf: spaceRooms.map(SpaceRoomProxy.init))
|
||||
spaces.append(contentsOf: spaceRooms.map(SpaceServiceRoom.init))
|
||||
case .clear:
|
||||
spaces.removeAll()
|
||||
case .pushFront(let spaceRoom):
|
||||
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: 0)
|
||||
spaces.insert(SpaceServiceRoom(spaceRoom: spaceRoom), at: 0)
|
||||
case .pushBack(let spaceRoom):
|
||||
spaces.append(SpaceRoomProxy(spaceRoom: spaceRoom))
|
||||
spaces.append(SpaceServiceRoom(spaceRoom: spaceRoom))
|
||||
case .popFront:
|
||||
spaces.removeFirst()
|
||||
case .popBack:
|
||||
spaces.removeLast()
|
||||
case .insert(let index, let spaceRoom):
|
||||
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: Int(index))
|
||||
spaces.insert(SpaceServiceRoom(spaceRoom: spaceRoom), at: Int(index))
|
||||
case .set(let index, let spaceRoom):
|
||||
spaces[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom)
|
||||
spaces[Int(index)] = SpaceServiceRoom(spaceRoom: spaceRoom)
|
||||
case .remove(let index):
|
||||
spaces.remove(at: Int(index))
|
||||
case .truncate(let length):
|
||||
spaces.removeSubrange(Int(length)..<spaces.count)
|
||||
case .reset(let spaceRooms):
|
||||
spaces = spaceRooms.map(SpaceRoomProxy.init)
|
||||
spaces = spaceRooms.map(SpaceServiceRoom.init)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ enum SpaceServiceProxyError: Error {
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol SpaceServiceProxyProtocol {
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { get }
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> { get }
|
||||
|
||||
func spaceRoomList(spaceID: String) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
/// Returns a joined space given its identifier
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceRoomProxyProtocol?, SpaceServiceProxyError>
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>
|
||||
func leaveSpace(spaceID: String) async -> Result<LeaveSpaceHandleProxy, SpaceServiceProxyError>
|
||||
/// Returns all the parent spaces of a child that user has joined.
|
||||
func joinedParents(childID: String) async -> Result<[SpaceRoomProxyProtocol], SpaceServiceProxyError>
|
||||
func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError>
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// Copyright 2025 Element Creations Ltd.
|
||||
// Copyright 2025 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
// Please see LICENSE files in the repository root for full details.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
struct SpaceServiceRoom: SpaceServiceRoomProtocol {
|
||||
var id: String
|
||||
var name: String
|
||||
var rawName: String?
|
||||
var avatarURL: URL?
|
||||
|
||||
var isSpace: Bool
|
||||
var isDirect: Bool?
|
||||
var childrenCount: Int
|
||||
|
||||
var joinedMembersCount: Int
|
||||
var heroes: [UserProfileProxy]
|
||||
var topic: String?
|
||||
var canonicalAlias: String?
|
||||
|
||||
var joinRule: JoinRule?
|
||||
var worldReadable: Bool?
|
||||
var guestCanJoin: Bool
|
||||
var state: Membership?
|
||||
var via: [String]
|
||||
|
||||
init(spaceRoom: SpaceRoom) {
|
||||
id = spaceRoom.roomId
|
||||
name = spaceRoom.displayName
|
||||
rawName = spaceRoom.rawName
|
||||
avatarURL = spaceRoom.avatarUrl.flatMap(URL.init)
|
||||
|
||||
isSpace = spaceRoom.roomType == .space
|
||||
isDirect = spaceRoom.isDirect
|
||||
childrenCount = Int(spaceRoom.childrenCount)
|
||||
|
||||
joinedMembersCount = Int(spaceRoom.numJoinedMembers)
|
||||
heroes = (spaceRoom.heroes ?? []).map(UserProfileProxy.init)
|
||||
topic = spaceRoom.topic
|
||||
canonicalAlias = spaceRoom.canonicalAlias
|
||||
|
||||
joinRule = spaceRoom.joinRule
|
||||
worldReadable = spaceRoom.worldReadable
|
||||
guestCanJoin = spaceRoom.guestCanJoin
|
||||
state = spaceRoom.state
|
||||
via = spaceRoom.via
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
enum SpaceRoomProxyVisibility: Equatable {
|
||||
enum SpaceServiceRoomVisibility: Equatable {
|
||||
case `public`
|
||||
case `private`
|
||||
case restricted
|
||||
@@ -17,7 +17,7 @@ enum SpaceRoomProxyVisibility: Equatable {
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol SpaceRoomProxyProtocol {
|
||||
protocol SpaceServiceRoomProtocol {
|
||||
var id: String { get }
|
||||
var name: String { get }
|
||||
var rawName: String? { get }
|
||||
@@ -39,7 +39,7 @@ protocol SpaceRoomProxyProtocol {
|
||||
var via: [String] { get }
|
||||
}
|
||||
|
||||
extension SpaceRoomProxyProtocol {
|
||||
extension SpaceServiceRoomProtocol {
|
||||
var avatar: RoomAvatar {
|
||||
if isSpace {
|
||||
.space(id: id, name: name, avatarURL: avatarURL)
|
||||
@@ -50,7 +50,7 @@ extension SpaceRoomProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
var visibility: SpaceRoomProxyVisibility? {
|
||||
var visibility: SpaceServiceRoomVisibility? {
|
||||
switch joinRule {
|
||||
case .public:
|
||||
.public
|
||||
@@ -597,7 +597,7 @@ class MockScreen: Identifiable {
|
||||
deviceID: "MOCKCLIENT",
|
||||
roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(roomSummaries))),
|
||||
spaceServiceConfiguration: .init(topLevelSpaces: .mockSingleRoom),
|
||||
roomPreviews: [SpaceRoomProxyProtocol].mockSpaceList.map(RoomPreviewProxyMock.init)))
|
||||
roomPreviews: [SpaceServiceRoomProtocol].mockSpaceList.map(RoomPreviewProxyMock.init)))
|
||||
|
||||
// The tab bar remains hidden for the non-spaces tests as we don't supply any mock spaces.
|
||||
let spaceServiceProxy = SpaceServiceProxyMock(id == .userSessionSpacesFlow ? .populated : .init())
|
||||
|
||||
Reference in New Issue
Block a user