mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
3ef66cdd05
Also remove the redundant `userID` property given `id` already exists (for Identifiable conformance).
280 lines
11 KiB
Swift
280 lines
11 KiB
Swift
//
|
|
// 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.
|
|
}
|
|
|
|
struct SpaceServiceRoom {
|
|
var id: String
|
|
var name: String
|
|
var rawName: String?
|
|
var avatarURL: URL?
|
|
|
|
var isSpace: Bool
|
|
var isDirect: Bool?
|
|
var isDM: Bool?
|
|
var childrenCount: Int
|
|
|
|
var joinedMembersCount: Int
|
|
var heroes: [UserProfile]
|
|
var topic: String?
|
|
var canonicalAlias: String?
|
|
|
|
var joinRule: JoinRule?
|
|
var worldReadable: Bool?
|
|
var guestCanJoin: Bool
|
|
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, .custom:
|
|
.private
|
|
case .none:
|
|
.none
|
|
}
|
|
}
|
|
}
|
|
|
|
extension SpaceServiceRoom {
|
|
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
|
|
isDM = spaceRoom.isDm
|
|
childrenCount = Int(spaceRoom.childrenCount)
|
|
|
|
joinedMembersCount = Int(spaceRoom.numJoinedMembers)
|
|
heroes = (spaceRoom.heroes ?? []).map(UserProfile.init)
|
|
topic = spaceRoom.topic
|
|
canonicalAlias = spaceRoom.canonicalAlias
|
|
|
|
joinRule = spaceRoom.joinRule.map(JoinRule.init)
|
|
worldReadable = spaceRoom.worldReadable
|
|
guestCanJoin = spaceRoom.guestCanJoin
|
|
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,
|
|
isDM: Bool? = nil,
|
|
childrenCount: Int = 0,
|
|
joinedMembersCount: Int = 0,
|
|
heroes: [UserProfile] = [],
|
|
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,
|
|
isDM: isDM,
|
|
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 = .invite
|
|
case .invited:
|
|
state = .invited
|
|
joinRule = .invite
|
|
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: .invite,
|
|
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)
|
|
]
|
|
}
|
|
}
|