mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:02:10 +00:00
Remove the protocol for SpaceServiceRoom given its a struct type. (#5000)
* Remove the protocol for SpaceServiceRoom given its a struct type. * Fix a few missed mocks in the unit tests.
This commit is contained in:
@@ -87,12 +87,12 @@ final class LeaveSpaceHandleProxy {
|
||||
}
|
||||
|
||||
@Observable class LeaveSpaceRoomDetails {
|
||||
let spaceServiceRoom: SpaceServiceRoomProtocol
|
||||
let spaceServiceRoom: SpaceServiceRoom
|
||||
let canLeave: Bool
|
||||
let areCreatorsPrivileged: Bool
|
||||
var isSelected: Bool
|
||||
|
||||
init(spaceServiceRoom: SpaceServiceRoomProtocol, isLastOwner: Bool, areCreatorsPrivileged: Bool, isSelected: Bool) {
|
||||
init(spaceServiceRoom: SpaceServiceRoom, isLastOwner: Bool, areCreatorsPrivileged: Bool, isSelected: Bool) {
|
||||
self.spaceServiceRoom = spaceServiceRoom
|
||||
canLeave = !isLastOwner || spaceServiceRoom.joinedMembersCount == 1
|
||||
self.isSelected = isSelected
|
||||
|
||||
@@ -15,14 +15,14 @@ class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
|
||||
private let spaceRoomList: SpaceRoomListProtocol
|
||||
|
||||
private var spaceServiceRoomHandle: TaskHandle?
|
||||
private let spaceServiceRoomSubject: CurrentValueSubject<SpaceServiceRoomProtocol, Never>
|
||||
var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never> {
|
||||
private let spaceServiceRoomSubject: CurrentValueSubject<SpaceServiceRoom, Never>
|
||||
var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoom, Never> {
|
||||
spaceServiceRoomSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
private var spaceRoomsHandle: TaskHandle?
|
||||
private let spaceRoomsSubject = CurrentValueSubject<[SpaceServiceRoomProtocol], Never>([])
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
|
||||
private let spaceRoomsSubject = CurrentValueSubject<[SpaceServiceRoom], Never>([])
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoom], Never> {
|
||||
spaceRoomsSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ enum SpaceRoomListProxyError: Error {
|
||||
protocol SpaceRoomListProxyProtocol {
|
||||
var id: String { get }
|
||||
|
||||
var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoomProtocol, Never> { get }
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> { get }
|
||||
var spaceServiceRoomPublisher: CurrentValuePublisher<SpaceServiceRoom, Never> { get }
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceServiceRoom], Never> { get }
|
||||
var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never> { get }
|
||||
|
||||
func paginate() async
|
||||
|
||||
@@ -14,8 +14,8 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
private let spaceService: SpaceServiceProtocol
|
||||
|
||||
private var topLevelSpacesHandle: TaskHandle?
|
||||
private let spacesSubject = CurrentValueSubject<[SpaceServiceRoomProtocol], Never>([])
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> {
|
||||
private let spacesSubject = CurrentValueSubject<[SpaceServiceRoom], Never>([])
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoom], Never> {
|
||||
spacesSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError> {
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoom?, SpaceServiceProxyError> {
|
||||
do {
|
||||
return try await .success(spaceService.getSpaceRoom(roomId: spaceID).map(SpaceServiceRoom.init))
|
||||
} catch {
|
||||
@@ -68,7 +68,7 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func joinedParents(childID: String) async -> Result<[SpaceServiceRoomProtocol], SpaceServiceProxyError> {
|
||||
func joinedParents(childID: String) async -> Result<[SpaceServiceRoom], SpaceServiceProxyError> {
|
||||
do {
|
||||
return try await .success(spaceService.joinedParentsOfChild(childId: childID).map(SpaceServiceRoom.init))
|
||||
} catch {
|
||||
@@ -77,7 +77,7 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func editableSpaces() async -> [SpaceServiceRoomProtocol] {
|
||||
func editableSpaces() async -> [SpaceServiceRoom] {
|
||||
await spaceService.editableSpaces().map(SpaceServiceRoom.init)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@ enum SpaceServiceProxyError: Error {
|
||||
}
|
||||
|
||||
struct SpaceServiceFilter: Identifiable, Equatable {
|
||||
let room: SpaceServiceRoomProtocol
|
||||
let room: SpaceServiceRoom
|
||||
let level: UInt
|
||||
let descendants: Set<String>
|
||||
|
||||
init(room: SpaceServiceRoomProtocol, level: UInt, descendants: Set<String>) {
|
||||
init(room: SpaceServiceRoom, level: UInt, descendants: Set<String>) {
|
||||
self.room = room
|
||||
self.level = level
|
||||
self.descendants = descendants
|
||||
@@ -43,17 +43,17 @@ struct SpaceServiceFilter: Identifiable, Equatable {
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol SpaceServiceProxyProtocol {
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoomProtocol], Never> { get }
|
||||
var topLevelSpacesPublisher: CurrentValuePublisher<[SpaceServiceRoom], Never> { get }
|
||||
var spaceFilterPublisher: CurrentValuePublisher<[SpaceServiceFilter], Never> { get }
|
||||
|
||||
func spaceRoomList(spaceID: String) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
/// Returns a joined space given its identifier
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoomProtocol?, SpaceServiceProxyError>
|
||||
func spaceForIdentifier(spaceID: String) async -> Result<SpaceServiceRoom?, 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<[SpaceServiceRoomProtocol], SpaceServiceProxyError>
|
||||
func joinedParents(childID: String) async -> Result<[SpaceServiceRoom], SpaceServiceProxyError>
|
||||
/// Returns all the joined spaces that can be edited by the user
|
||||
func editableSpaces() async -> [SpaceServiceRoomProtocol]
|
||||
func editableSpaces() async -> [SpaceServiceRoom]
|
||||
|
||||
/// Adds a room (or space) as a child of another space.
|
||||
func addChild(_ childID: String, to spaceID: String) async -> Result<Void, SpaceServiceProxyError>
|
||||
|
||||
@@ -9,7 +9,14 @@
|
||||
import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
struct SpaceServiceRoom: SpaceServiceRoomProtocol {
|
||||
enum SpaceServiceRoomVisibility: Equatable {
|
||||
case `public`
|
||||
case `private`
|
||||
case restricted
|
||||
// We can add the external case in here eventually.
|
||||
}
|
||||
|
||||
struct SpaceServiceRoom {
|
||||
var id: String
|
||||
var name: String
|
||||
var rawName: String?
|
||||
@@ -30,6 +37,31 @@ struct SpaceServiceRoom: SpaceServiceRoomProtocol {
|
||||
var state: Membership?
|
||||
var via: [String]
|
||||
|
||||
var avatar: RoomAvatar {
|
||||
if isSpace {
|
||||
.space(id: id, name: name, avatarURL: avatarURL)
|
||||
} else if isDirect == true, avatarURL == nil, heroes.count == 1 {
|
||||
.heroes(heroes)
|
||||
} else {
|
||||
.room(id: id, name: name, avatarURL: avatarURL)
|
||||
}
|
||||
}
|
||||
|
||||
var visibility: SpaceServiceRoomVisibility? {
|
||||
switch joinRule {
|
||||
case .public:
|
||||
.public
|
||||
case .restricted, .knockRestricted:
|
||||
.restricted
|
||||
case .invite, .knock, .private, .custom:
|
||||
.private
|
||||
case .none:
|
||||
.none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SpaceServiceRoom {
|
||||
init(spaceRoom: SpaceRoom) {
|
||||
id = spaceRoom.roomId
|
||||
name = spaceRoom.displayName
|
||||
@@ -51,4 +83,193 @@ struct SpaceServiceRoom: SpaceServiceRoomProtocol {
|
||||
state = spaceRoom.state
|
||||
via = spaceRoom.via
|
||||
}
|
||||
|
||||
// MARK: - Mocks
|
||||
|
||||
static func mock(id: String = UUID().uuidString,
|
||||
name: String? = nil,
|
||||
rawName: String? = nil,
|
||||
avatarURL: URL? = nil,
|
||||
isSpace: Bool,
|
||||
isDirect: Bool? = nil,
|
||||
childrenCount: Int = 0,
|
||||
joinedMembersCount: Int = 0,
|
||||
heroes: [UserProfileProxy] = [],
|
||||
topic: String? = nil,
|
||||
canonicalAlias: String? = nil,
|
||||
joinRule: JoinRule? = nil,
|
||||
worldReadable: Bool? = nil,
|
||||
guestCanJoin: Bool = true,
|
||||
state: Membership? = nil,
|
||||
via: [String] = []) -> Self {
|
||||
SpaceServiceRoom(id: id,
|
||||
name: name ?? id,
|
||||
rawName: rawName,
|
||||
avatarURL: avatarURL,
|
||||
isSpace: isSpace,
|
||||
isDirect: isDirect,
|
||||
childrenCount: childrenCount,
|
||||
joinedMembersCount: joinedMembersCount,
|
||||
heroes: heroes,
|
||||
topic: topic,
|
||||
canonicalAlias: canonicalAlias,
|
||||
joinRule: joinRule,
|
||||
worldReadable: worldReadable,
|
||||
guestCanJoin: guestCanJoin,
|
||||
state: state,
|
||||
via: via)
|
||||
}
|
||||
|
||||
static func mock(joinRoomScreenMode: JoinRoomScreenMode) -> Self {
|
||||
var state: Membership?
|
||||
var joinRule: JoinRule?
|
||||
|
||||
switch joinRoomScreenMode {
|
||||
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
|
||||
}
|
||||
|
||||
return SpaceServiceRoom.mock(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)
|
||||
}
|
||||
}
|
||||
|
||||
extension [SpaceServiceRoom] {
|
||||
static var mockJoinedSpaces: [SpaceServiceRoom] {
|
||||
[
|
||||
SpaceServiceRoom.mock(id: "space1",
|
||||
name: "The Foundation",
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 500,
|
||||
canonicalAlias: "#the-foundation:matrix.org",
|
||||
state: .joined),
|
||||
SpaceServiceRoom.mock(id: "space2",
|
||||
name: "The Second Foundation",
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 100,
|
||||
state: .joined),
|
||||
SpaceServiceRoom.mock(id: "space3",
|
||||
name: "The Galactic Empire",
|
||||
isSpace: true,
|
||||
childrenCount: 25000,
|
||||
joinedMembersCount: 1_000_000_000,
|
||||
canonicalAlias: "#the-galactic-empire:matrix.org",
|
||||
state: .joined),
|
||||
SpaceServiceRoom.mock(id: "space4",
|
||||
name: "The Korellians",
|
||||
isSpace: true,
|
||||
childrenCount: 27,
|
||||
joinedMembersCount: 2_000_000,
|
||||
state: .joined),
|
||||
SpaceServiceRoom.mock(id: "space5",
|
||||
name: "The Luminists",
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 100_000,
|
||||
state: .joined),
|
||||
SpaceServiceRoom.mock(id: "space6",
|
||||
name: "The Anacreons",
|
||||
isSpace: true,
|
||||
childrenCount: 25,
|
||||
joinedMembersCount: 400_000,
|
||||
state: .joined),
|
||||
SpaceServiceRoom.mock(id: "space7",
|
||||
name: "The Thespians",
|
||||
isSpace: true,
|
||||
childrenCount: 15,
|
||||
joinedMembersCount: 300_000,
|
||||
state: .joined)
|
||||
]
|
||||
}
|
||||
|
||||
static var mockJoinedSpaces2: [SpaceServiceRoom] {
|
||||
[
|
||||
SpaceServiceRoom.mock(id: "space1",
|
||||
name: "The Foundation",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 500,
|
||||
canonicalAlias: "#the-foundation:matrix.org",
|
||||
joinRule: .private,
|
||||
state: .joined),
|
||||
SpaceServiceRoom.mock(id: "space2",
|
||||
name: "The Second Foundation",
|
||||
isSpace: true,
|
||||
childrenCount: 1,
|
||||
joinedMembersCount: 100,
|
||||
state: .joined),
|
||||
SpaceServiceRoom.mock(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: [SpaceServiceRoom] {
|
||||
makeSpaceRooms(isSpace: true) + makeSpaceRooms(isSpace: false)
|
||||
}
|
||||
|
||||
static var mockSingleRoom: [SpaceServiceRoom] {
|
||||
[SpaceServiceRoom.mock(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) -> [SpaceServiceRoom] {
|
||||
let typeName = isSpace ? "Space" : "Room"
|
||||
|
||||
return [
|
||||
SpaceServiceRoom.mock(id: "!\(typeName.lowercased())1:matrix.org",
|
||||
name: "Company \(typeName)",
|
||||
isSpace: isSpace),
|
||||
SpaceServiceRoom.mock(id: "!\(typeName.lowercased())2:matrix.org",
|
||||
name: "Public \(typeName)",
|
||||
avatarURL: .mockMXCAvatar,
|
||||
isSpace: isSpace,
|
||||
joinedMembersCount: 78,
|
||||
topic: "Discussion on specific topic goes here.",
|
||||
joinRule: .public),
|
||||
SpaceServiceRoom.mock(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)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +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
|
||||
|
||||
enum SpaceServiceRoomVisibility: Equatable {
|
||||
case `public`
|
||||
case `private`
|
||||
case restricted
|
||||
// We can add the external case in here eventually.
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol SpaceServiceRoomProtocol {
|
||||
var id: String { get }
|
||||
var name: String { get }
|
||||
var rawName: String? { get }
|
||||
var avatarURL: URL? { get }
|
||||
|
||||
var isSpace: Bool { get }
|
||||
var isDirect: Bool? { get }
|
||||
var childrenCount: Int { get }
|
||||
|
||||
var joinedMembersCount: Int { get }
|
||||
var heroes: [UserProfileProxy] { get }
|
||||
var topic: String? { get }
|
||||
var canonicalAlias: String? { get }
|
||||
|
||||
var joinRule: JoinRule? { get }
|
||||
var worldReadable: Bool? { get }
|
||||
var guestCanJoin: Bool { get }
|
||||
var state: Membership? { get }
|
||||
var via: [String] { get }
|
||||
}
|
||||
|
||||
extension SpaceServiceRoomProtocol {
|
||||
var avatar: RoomAvatar {
|
||||
if isSpace {
|
||||
.space(id: id, name: name, avatarURL: avatarURL)
|
||||
} else if isDirect == true, avatarURL == nil, heroes.count == 1 {
|
||||
.heroes(heroes)
|
||||
} else {
|
||||
.room(id: id, name: name, avatarURL: avatarURL)
|
||||
}
|
||||
}
|
||||
|
||||
var visibility: SpaceServiceRoomVisibility? {
|
||||
switch joinRule {
|
||||
case .public:
|
||||
.public
|
||||
case .restricted, .knockRestricted:
|
||||
.restricted
|
||||
case .invite, .knock, .private, .custom:
|
||||
.private
|
||||
case .none:
|
||||
.none
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user