Skip to content

Commit 8000dbe

Browse files
authored
Add a SpaceScreen for listing rooms and subspaces within a space. (#4412)
1 parent de62618 commit 8000dbe

34 files changed

+756
-93
lines changed

AccessibilityTests/Sources/GeneratedAccessibilityTests.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,10 @@ extension AccessibilityTests {
583583
try await performAccessibilityAudit(named: "SoftLogoutScreen_Previews")
584584
}
585585

586+
func testSpaceHeaderView() async throws {
587+
try await performAccessibilityAudit(named: "SpaceHeaderView_Previews")
588+
}
589+
586590
func testSpaceListScreen() async throws {
587591
try await performAccessibilityAudit(named: "SpaceListScreen_Previews")
588592
}
@@ -591,6 +595,10 @@ extension AccessibilityTests {
591595
try await performAccessibilityAudit(named: "SpaceRoomCell_Previews")
592596
}
593597

598+
func testSpaceScreen() async throws {
599+
try await performAccessibilityAudit(named: "SpaceScreen_Previews")
600+
}
601+
594602
func testSplashScreen() async throws {
595603
try await performAccessibilityAudit(named: "SplashScreen_Previews")
596604
}

ElementX.xcodeproj/project.pbxproj

Lines changed: 36 additions & 0 deletions
Large diffs are not rendered by default.

ElementX/Resources/Localizations/en.lproj/Localizable.strings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@
278278
"common_signing_out" = "Signing out";
279279
"common_something_went_wrong" = "Something went wrong";
280280
"common_something_went_wrong_message" = "We encountered an issue. Please try again.";
281+
"common_space" = "Space";
281282
"common_starting_chat" = "Starting chat…";
282283
"common_sticker" = "Sticker";
283284
"common_success" = "Success";
@@ -1075,6 +1076,7 @@
10751076
"screen_roomlist_filter_favourites_empty_state_title" = "You don’t have favourite chats yet";
10761077
"screen_roomlist_filter_invites_empty_state_title" = "You don't have any pending invites.";
10771078
"screen_roomlist_filter_low_priority" = "Low Priority";
1079+
"screen_roomlist_filter_low_priority_empty_state_title" = "You don’t have any low priority chats yet";
10781080
"screen_roomlist_filter_mixed_empty_state_subtitle" = "You can deselect filters in order to see your other chats";
10791081
"screen_roomlist_filter_mixed_empty_state_title" = "You don’t have chats for this selection";
10801082
"screen_roomlist_filter_people_empty_state_title" = "You don’t have any DMs yet";

ElementX/Sources/Generated/Strings.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,8 @@ internal enum L10n {
624624
internal static var commonSomethingWentWrong: String { return L10n.tr("Localizable", "common_something_went_wrong") }
625625
/// We encountered an issue. Please try again.
626626
internal static var commonSomethingWentWrongMessage: String { return L10n.tr("Localizable", "common_something_went_wrong_message") }
627+
/// Space
628+
internal static var commonSpace: String { return L10n.tr("Localizable", "common_space") }
627629
/// Plural format key: "%#@COUNT@"
628630
internal static func commonSpaces(_ p1: Int) -> String {
629631
return L10n.tr("Localizable", "common_spaces", p1)
@@ -2581,6 +2583,8 @@ internal enum L10n {
25812583
internal static var screenRoomlistFilterInvitesEmptyStateTitle: String { return L10n.tr("Localizable", "screen_roomlist_filter_invites_empty_state_title") }
25822584
/// Low Priority
25832585
internal static var screenRoomlistFilterLowPriority: String { return L10n.tr("Localizable", "screen_roomlist_filter_low_priority") }
2586+
/// You don’t have any low priority chats yet
2587+
internal static var screenRoomlistFilterLowPriorityEmptyStateTitle: String { return L10n.tr("Localizable", "screen_roomlist_filter_low_priority_empty_state_title") }
25842588
/// You can deselect filters in order to see your other chats
25852589
internal static var screenRoomlistFilterMixedEmptyStateSubtitle: String { return L10n.tr("Localizable", "screen_roomlist_filter_mixed_empty_state_subtitle") }
25862590
/// You don’t have chats for this selection

ElementX/Sources/Mocks/SpaceRoomListProxyMock.swift

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,43 @@
55
// Please see LICENSE files in the repository root for full details.
66
//
77

8+
import Combine
89
import Foundation
910
import MatrixRustSDK
1011

1112
extension SpaceRoomListProxyMock {
12-
struct Configuration {
13+
class Configuration {
1314
var spaceRoomProxy: SpaceRoomProxyProtocol
14-
var spaceRooms: [SpaceRoomProxyProtocol] = []
15+
var initialSpaceRooms: [SpaceRoomProxyProtocol]
16+
var paginationStateSubject: CurrentValueSubject<SpaceRoomListProxyPaginationState, Never>
17+
var paginationResponses: [[SpaceRoomProxyProtocol]]
18+
19+
init(spaceRoomProxy: SpaceRoomProxyProtocol,
20+
initialSpaceRooms: [SpaceRoomProxyProtocol] = [],
21+
paginationStateSubject: CurrentValueSubject<SpaceRoomListProxyPaginationState, Never> = .init(.idle(endReached: true)),
22+
paginationResponses: [[SpaceRoomProxyProtocol]] = []) {
23+
self.spaceRoomProxy = spaceRoomProxy
24+
self.initialSpaceRooms = initialSpaceRooms
25+
self.paginationStateSubject = paginationStateSubject
26+
self.paginationResponses = paginationResponses
27+
}
1528
}
1629

1730
convenience init(_ configuration: Configuration) {
1831
self.init()
1932

33+
let spaceRoomsSubject: CurrentValueSubject<[SpaceRoomProxyProtocol], Never> = .init(configuration.initialSpaceRooms)
34+
2035
spaceRoom = configuration.spaceRoomProxy
21-
spaceRoomsPublisher = .init(configuration.spaceRooms)
36+
spaceRoomsPublisher = spaceRoomsSubject.asCurrentValuePublisher()
37+
paginationStatePublisher = configuration.paginationStateSubject.asCurrentValuePublisher()
38+
39+
paginateClosure = {
40+
configuration.paginationStateSubject.send(.loading)
41+
try? await Task.sleep(for: .milliseconds(100))
42+
let newRooms = configuration.paginationResponses.removeFirst()
43+
spaceRoomsSubject.send(spaceRoomsSubject.value + newRooms)
44+
configuration.paginationStateSubject.send(.idle(endReached: configuration.paginationResponses.isEmpty))
45+
}
2246
}
2347
}

ElementX/Sources/Mocks/SpaceRoomProxyMock.swift

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,79 @@ extension SpaceRoomProxyMock {
4646
state = configuration.state
4747
}
4848
}
49+
50+
extension [SpaceRoomProxyProtocol] {
51+
static var mockJoinedSpaces: [SpaceRoomProxyMock] {
52+
[
53+
SpaceRoomProxyMock(.init(id: "space1",
54+
name: "The Foundation",
55+
isSpace: true,
56+
childrenCount: 1,
57+
joinedMembersCount: 500,
58+
state: .joined)),
59+
SpaceRoomProxyMock(.init(id: "space2",
60+
name: "The Second Foundation",
61+
isSpace: true,
62+
childrenCount: 1,
63+
joinedMembersCount: 100,
64+
state: .joined)),
65+
SpaceRoomProxyMock(.init(id: "space3",
66+
name: "The Galactic Empire",
67+
isSpace: true,
68+
childrenCount: 25000,
69+
joinedMembersCount: 1_000_000_000,
70+
state: .joined)),
71+
SpaceRoomProxyMock(.init(id: "space4",
72+
name: "The Korellians",
73+
isSpace: true,
74+
childrenCount: 27,
75+
joinedMembersCount: 2_000_000,
76+
state: .joined)),
77+
SpaceRoomProxyMock(.init(id: "space5",
78+
name: "The Luminists",
79+
isSpace: true,
80+
childrenCount: 1,
81+
joinedMembersCount: 100_000,
82+
state: .joined)),
83+
SpaceRoomProxyMock(.init(id: "space6",
84+
name: "The Anacreons",
85+
isSpace: true,
86+
childrenCount: 25,
87+
joinedMembersCount: 400_000,
88+
state: .joined)),
89+
SpaceRoomProxyMock(.init(id: "space7",
90+
name: "The Thespians",
91+
isSpace: true,
92+
childrenCount: 15,
93+
joinedMembersCount: 300_000,
94+
state: .joined))
95+
]
96+
}
97+
98+
static var mockSpaceList: [SpaceRoomProxyProtocol] {
99+
makeSpaceRooms(isSpace: true) + makeSpaceRooms(isSpace: false)
100+
}
101+
102+
private static func makeSpaceRooms(isSpace: Bool) -> [SpaceRoomProxyMock] {
103+
let typeName = isSpace ? "Space" : "Room"
104+
105+
return [
106+
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())1:matrix.org",
107+
name: "Company \(typeName)",
108+
isSpace: isSpace)),
109+
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())2:matrix.org",
110+
name: "Public \(typeName)",
111+
avatarURL: .mockMXCAvatar,
112+
isSpace: isSpace,
113+
joinedMembersCount: 78,
114+
topic: "Discussion on specific topic goes here.",
115+
joinRule: .public)),
116+
SpaceRoomProxyMock(.init(id: "!\(typeName.lowercased())3:matrix.org",
117+
name: "Joined \(typeName)",
118+
isSpace: isSpace,
119+
joinedMembersCount: 123,
120+
topic: "Discussion on specific topic goes here.",
121+
state: .joined))
122+
]
123+
}
124+
}

ElementX/Sources/Mocks/UserProfile+Mock.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ extension UserProfileProxy {
2525
.init(userID: "@charlie:matrix.org", displayName: "Charlie", avatarURL: nil)
2626
}
2727

28+
static var mockDan: UserProfileProxy {
29+
.init(userID: "@dan:matrix.org", displayName: "Dan", avatarURL: .mockMXCUserAvatar)
30+
}
31+
2832
static var mockVerbose: UserProfileProxy {
2933
.init(userID: "@charlie:matrix.org", displayName: "Charlie is the best display name", avatarURL: nil)
3034
}

ElementX/Sources/Other/Avatars.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ enum UserAvatarSizeOnScreen {
7171
case readReceipt
7272
case readReceiptSheet
7373
case editUserDetails
74+
case spaceHeader
7475
case completionSuggestions
7576
case blockedUsers
7677
case knockingUsersBannerStack
@@ -91,6 +92,8 @@ enum UserAvatarSizeOnScreen {
9192
return 16
9293
case .readReceiptSheet:
9394
return 32
95+
case .spaceHeader:
96+
return 20
9497
case .completionSuggestions:
9598
return 32
9699
case .blockedUsers:

ElementX/Sources/Other/TestablePreview/TestablePreviewsDictionary.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,10 @@ enum TestablePreviewsDictionary {
153153
"SettingsScreen_Previews" : SettingsScreen_Previews.self,
154154
"ShimmerOverlay_Previews" : ShimmerOverlay_Previews.self,
155155
"SoftLogoutScreen_Previews" : SoftLogoutScreen_Previews.self,
156+
"SpaceHeaderView_Previews" : SpaceHeaderView_Previews.self,
156157
"SpaceListScreen_Previews" : SpaceListScreen_Previews.self,
157158
"SpaceRoomCell_Previews" : SpaceRoomCell_Previews.self,
159+
"SpaceScreen_Previews" : SpaceScreen_Previews.self,
158160
"SplashScreen_Previews" : SplashScreen_Previews.self,
159161
"StackedAvatarsView_Previews" : StackedAvatarsView_Previews.self,
160162
"StartChatScreen_Previews" : StartChatScreen_Previews.self,

0 commit comments

Comments
 (0)