always present the space selection even for pre selected spaces

This commit is contained in:
Mauro Romito
2026-02-10 13:22:10 +01:00
committed by Mauro
parent 591ce3975b
commit 9ced1cff2e
15 changed files with 50 additions and 47 deletions
@@ -137,20 +137,20 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol {
self?.presentStartChatScreen() self?.presentStartChatScreen()
} }
stateMachine.addRoutes(event: .createRoom(isSpace: true), transitions: [.initial => .createRoom]) { [weak self] _ in stateMachine.addRoutes(event: .createRoom(isSpace: true), transitions: [.initial => .createRoom]) { [weak self] _ in
self?.presentCreateRoomScreen(isSpace: true, spaceSelectionMode: nil, isRoot: true) self?.presentCreateRoomScreen(isSpace: true, spaceSelectionMode: .none, isRoot: true)
} }
stateMachine.addRoutes(event: .createRoom(isSpace: false), transitions: [.initial => .createRoom]) { [weak self] context in stateMachine.addRoutes(event: .createRoom(isSpace: false), transitions: [.initial => .createRoom]) { [weak self] context in
guard context.fromState == .initial else { return } // Required check because the event is used in another route. guard context.fromState == .initial else { return } // Required check because the event is used in another route.
guard let space = context.userInfo as? SpaceServiceRoom else { guard let space = context.userInfo as? SpaceServiceRoom else {
fatalError("This transition only supports creating a room in a pre-selected space.") fatalError("This transition only supports creating a room in a pre-selected space.")
} }
self?.presentCreateRoomScreen(isSpace: false, spaceSelectionMode: .preSelected(space), isRoot: true) self?.presentCreateRoomScreen(isSpace: false, spaceSelectionMode: .editableSpacesList(preSelectedSpace: space), isRoot: true)
} }
stateMachine.addRoutes(event: .createRoom(isSpace: false), transitions: [.startChat => .createRoom]) { [weak self] context in stateMachine.addRoutes(event: .createRoom(isSpace: false), transitions: [.startChat => .createRoom]) { [weak self] context in
guard let self, context.fromState == .startChat else { return } // Required check because the event is used in another route. guard let self, context.fromState == .startChat else { return } // Required check because the event is used in another route.
presentCreateRoomScreen(isSpace: false, presentCreateRoomScreen(isSpace: false,
spaceSelectionMode: flowParameters.appSettings.createSpaceEnabled ? .editableSpacesList : nil, spaceSelectionMode: flowParameters.appSettings.createSpaceEnabled ? .editableSpacesList(preSelectedSpace: nil) : .none,
isRoot: false) isRoot: false)
} }
stateMachine.addRoutes(event: .dismissedCreateRoom, transitions: [.createRoom => .startChat]) { [weak self] _ in stateMachine.addRoutes(event: .dismissedCreateRoom, transitions: [.createRoom => .startChat]) { [weak self] _ in
@@ -208,7 +208,7 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol {
} }
private func presentCreateRoomScreen(isSpace: Bool, private func presentCreateRoomScreen(isSpace: Bool,
spaceSelectionMode: CreateRoomScreenSpaceSelectionMode?, spaceSelectionMode: CreateRoomScreenSpaceSelectionMode,
isRoot: Bool) { isRoot: Bool) {
let createParameters = CreateRoomScreenCoordinatorParameters(isSpace: isSpace, let createParameters = CreateRoomScreenCoordinatorParameters(isSpace: isSpace,
spaceSelectionMode: spaceSelectionMode, spaceSelectionMode: spaceSelectionMode,
@@ -11,7 +11,7 @@ import SwiftUI
struct CreateRoomScreenCoordinatorParameters { struct CreateRoomScreenCoordinatorParameters {
let isSpace: Bool let isSpace: Bool
let spaceSelectionMode: CreateRoomScreenSpaceSelectionMode? let spaceSelectionMode: CreateRoomScreenSpaceSelectionMode
let shouldShowCancelButton: Bool let shouldShowCancelButton: Bool
let userSession: UserSessionProtocol let userSession: UserSessionProtocol
let userIndicatorController: UserIndicatorControllerProtocol let userIndicatorController: UserIndicatorControllerProtocol
@@ -143,6 +143,6 @@ enum CreateRoomScreenAccessType {
} }
enum CreateRoomScreenSpaceSelectionMode { enum CreateRoomScreenSpaceSelectionMode {
case editableSpacesList case editableSpacesList(preSelectedSpace: SpaceServiceRoom?)
case preSelected(SpaceServiceRoom) case none
} }
@@ -28,7 +28,7 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
} }
init(isSpace: Bool, init(isSpace: Bool,
spaceSelectionMode: CreateRoomScreenSpaceSelectionMode?, spaceSelectionMode: CreateRoomScreenSpaceSelectionMode,
shouldShowCancelButton: Bool, shouldShowCancelButton: Bool,
userSession: UserSessionProtocol, userSession: UserSessionProtocol,
analytics: AnalyticsService, analytics: AnalyticsService,
@@ -40,18 +40,19 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen
self.userIndicatorController = userIndicatorController self.userIndicatorController = userIndicatorController
var selectedSpace: SpaceServiceRoom? var selectedSpace: SpaceServiceRoom?
var canSelectSpace = false let canSelectSpace: Bool
var selectedAccessType = CreateRoomScreenAccessType.private var selectedAccessType = CreateRoomScreenAccessType.private
switch spaceSelectionMode { switch spaceSelectionMode {
case .editableSpacesList: case .editableSpacesList(let preSelectedSpace):
canSelectSpace = true canSelectSpace = true
case .preSelected(let value): if let preSelectedSpace {
selectedSpace = value selectedSpace = preSelectedSpace
if value.joinRule != .public { if preSelectedSpace.joinRule != .public {
selectedAccessType = .spaceMembers selectedAccessType = .spaceMembers
} }
}
case .none: case .none:
break canSelectSpace = false
} }
let bindings = CreateRoomScreenViewStateBindings(roomTopic: "", let bindings = CreateRoomScreenViewStateBindings(roomTopic: "",
@@ -337,10 +337,10 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
return viewModel return viewModel
}() }()
static let spaceViewModel = makeViewModel(isSpace: true, selectionMode: nil) static let spaceViewModel = makeViewModel(isSpace: true, selectionMode: .none)
static let spaceWithAvatarViewModel = { static let spaceWithAvatarViewModel = {
let viewModel = makeViewModel(isSpace: true, selectionMode: nil) let viewModel = makeViewModel(isSpace: true, selectionMode: .none)
viewModel.updateAvatar(fileURL: Bundle.main.url(forResource: "preview_avatar_room", withExtension: "jpg") ?? .picturesDirectory) viewModel.updateAvatar(fileURL: Bundle.main.url(forResource: "preview_avatar_room", withExtension: "jpg") ?? .picturesDirectory)
return viewModel return viewModel
}() }()
@@ -371,7 +371,8 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
return viewModel return viewModel
}() }()
static let selectedSpaceViewModel = makeViewModel(selectionMode: .preSelected(SpaceServiceRoom.mock(name: "Awesome Space", static let selectedSpaceViewModel = makeViewModel(selectionMode: .editableSpacesList(preSelectedSpace: SpaceServiceRoom.mock(id: "awesome-space-id",
name: "Awesome Space",
isSpace: true, isSpace: true,
joinRule: .invite))) joinRule: .invite)))
@@ -383,7 +384,8 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
static let selectedSpaceWithAskToJoinViewModel = { static let selectedSpaceWithAskToJoinViewModel = {
let viewModel = makeViewModel(isKnockingEnabled: true, let viewModel = makeViewModel(isKnockingEnabled: true,
selectionMode: .preSelected(SpaceServiceRoom.mock(name: "Awesome Space", selectionMode: .editableSpacesList(preSelectedSpace: SpaceServiceRoom.mock(id: "awesome-space-id",
name: "Awesome Space",
isSpace: true, isSpace: true,
joinRule: .invite))) joinRule: .invite)))
viewModel.context.selectedAccessType = .askToJoinWithSpaceMembers viewModel.context.selectedAccessType = .askToJoinWithSpaceMembers
@@ -453,7 +455,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview {
private static func makeViewModel(isKnockingEnabled: Bool = false, private static func makeViewModel(isKnockingEnabled: Bool = false,
isSpace: Bool = false, isSpace: Bool = false,
selectionMode: CreateRoomScreenSpaceSelectionMode? = .editableSpacesList, selectionMode: CreateRoomScreenSpaceSelectionMode = .editableSpacesList(preSelectedSpace: nil),
isAliasAvailable: Bool = true) -> CreateRoomScreenViewModel { isAliasAvailable: Bool = true) -> CreateRoomScreenViewModel {
AppSettings.resetAllSettings() AppSettings.resetAllSettings()
let appSettings = AppSettings() let appSettings = AppSettings()
@@ -68,7 +68,7 @@ struct CreateRoomSpaceSelectionSheet_Previews: PreviewProvider, TestablePreview
let userSession = UserSessionMock(.init(clientProxy: clientProxy)) let userSession = UserSessionMock(.init(clientProxy: clientProxy))
return CreateRoomScreenViewModel(isSpace: false, return CreateRoomScreenViewModel(isSpace: false,
spaceSelectionMode: .editableSpacesList, spaceSelectionMode: .editableSpacesList(preSelectedSpace: nil),
shouldShowCancelButton: false, shouldShowCancelButton: false,
userSession: userSession, userSession: userSession,
analytics: ServiceLocator.shared.analytics, analytics: ServiceLocator.shared.analytics,
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:83a67df5a49ac8156919889499ec22a33f563b7938e7dfb48c0dc49bb02645fe oid sha256:9e581f275989e39a2aadc059af9c69c2685abb938eecc9855fa1f2182d83bed5
size 136305 size 146942
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:86a40d4382a544aa180015701cfcfb21a1041f75721560c984e12d33b9c7e02e oid sha256:0daa761c0dfd08eec088ee9e03790e9697f17a4c3ce83bdb7a68917c79e1b34e
size 162193 size 174278
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:e30083baf88ea9ef1e0add6e08fdf32fcfbe20e1aec5bd810fea63aa3317159f oid sha256:15414d3cc95a1dbcae9fd481df8690c98b074141bc3c2c00b8ecd118ce2927d6
size 87147 size 96260
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:93389d81a8bf41c04f994fdd8c68be0851d1121830d8d818fbf9ab1660c7301b oid sha256:d98136e94aa426de48e76784bb204bd4bfad6852db9874fe61413dfac88f622e
size 116725 size 126375
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:81a9fc6f2b4f30f472b070566de301e972261c2fc793c1eb3d7fd7ff18447cd3 oid sha256:7df313c7cc43fb33c5a43d01a6f160556dc9d5870608563dfaf3e717ffbb79ab
size 124679 size 135404
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:b6b446617b753a1a15f1e0314d75e0564d513c6dae0406b643a28d23307acee4 oid sha256:30dec3b7383f8a5f83ec0284a5f026c0eaf4ea413a939d3614f1d9f69f990efd
size 143705 size 155660
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:e822a146afe0c7e297a81bae8f8001f412385f6d6e2a38b900892327fb854147 oid sha256:7c60a5df34365749605fb6a18f08c46d8d1363b6b0f58794a011dbdd8becc275
size 74358 size 83208
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:0ba8cbcfc9e73d632b836f99fe78db039e462c19448781a474a745fa939f3f88 oid sha256:4dd5907f0b71f3ff6fec6dd399f12a987c6d7461120718664f71c50458851b83
size 93507 size 103355
@@ -80,7 +80,7 @@ class CreateRoomScreenViewModelTests: XCTestCase {
userSession = UserSessionMock(.init(clientProxy: clientProxy)) userSession = UserSessionMock(.init(clientProxy: clientProxy))
ServiceLocator.shared.settings.knockingEnabled = true ServiceLocator.shared.settings.knockingEnabled = true
let viewModel = CreateRoomScreenViewModel(isSpace: true, let viewModel = CreateRoomScreenViewModel(isSpace: true,
spaceSelectionMode: nil, spaceSelectionMode: .none,
shouldShowCancelButton: false, shouldShowCancelButton: false,
userSession: userSession, userSession: userSession,
analytics: ServiceLocator.shared.analytics, analytics: ServiceLocator.shared.analytics,
@@ -272,14 +272,14 @@ class CreateRoomScreenViewModelTests: XCTestCase {
func testCreateRoomInAnAlreadySelectedSpace() async throws { func testCreateRoomInAnAlreadySelectedSpace() async throws {
let space = SpaceServiceRoom.mock(isSpace: true, joinRule: .invite) let space = SpaceServiceRoom.mock(isSpace: true, joinRule: .invite)
setup(spacesSelectionMode: .preSelected(space)) setup(spacesSelectionMode: .editableSpacesList(preSelectedSpace: space))
context.send(viewAction: .updateRoomName("A")) context.send(viewAction: .updateRoomName("A"))
context.selectedAccessType = .spaceMembers context.selectedAccessType = .spaceMembers
XCTAssertTrue(context.viewState.canCreateRoom) XCTAssertTrue(context.viewState.canCreateRoom)
XCTAssertEqual(context.selectedSpace?.id, space.id) XCTAssertEqual(context.selectedSpace?.id, space.id)
XCTAssertEqual(context.viewState.availableAccessTypes, [.spaceMembers, .askToJoinWithSpaceMembers, .private]) XCTAssertEqual(context.viewState.availableAccessTypes, [.spaceMembers, .askToJoinWithSpaceMembers, .private])
XCTAssertFalse(context.viewState.canSelectSpace) XCTAssertTrue(context.viewState.canSelectSpace)
// When creating the room. // When creating the room.
clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .success("1") clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .success("1")
@@ -307,7 +307,7 @@ class CreateRoomScreenViewModelTests: XCTestCase {
func testCreateRoomInAnPublicSpaceAvailableTypes() { func testCreateRoomInAnPublicSpaceAvailableTypes() {
let space = SpaceServiceRoom.mock(isSpace: true, joinRule: .public) let space = SpaceServiceRoom.mock(isSpace: true, joinRule: .public)
setup(spacesSelectionMode: .preSelected(space)) setup(spacesSelectionMode: .editableSpacesList(preSelectedSpace: space))
// Given a form with a blank topic. // Given a form with a blank topic.
context.send(viewAction: .updateRoomName("A")) context.send(viewAction: .updateRoomName("A"))
@@ -316,10 +316,10 @@ class CreateRoomScreenViewModelTests: XCTestCase {
XCTAssertTrue(context.viewState.canCreateRoom) XCTAssertTrue(context.viewState.canCreateRoom)
XCTAssertEqual(context.selectedSpace?.id, space.id) XCTAssertEqual(context.selectedSpace?.id, space.id)
XCTAssertEqual(context.viewState.availableAccessTypes, [.public, .askToJoin, .private]) XCTAssertEqual(context.viewState.availableAccessTypes, [.public, .askToJoin, .private])
XCTAssertFalse(context.viewState.canSelectSpace) XCTAssertTrue(context.viewState.canSelectSpace)
} }
private func setup(isSpace: Bool = false, spacesSelectionMode: CreateRoomScreenSpaceSelectionMode = .editableSpacesList) { private func setup(isSpace: Bool = false, spacesSelectionMode: CreateRoomScreenSpaceSelectionMode = .editableSpacesList(preSelectedSpace: nil)) {
spaceService = SpaceServiceProxyMock(.init(editableSpaces: .mockJoinedSpaces2, spaceService = SpaceServiceProxyMock(.init(editableSpaces: .mockJoinedSpaces2,
spaceRoomLists: ["1": .init()])) spaceRoomLists: ["1": .init()]))
clientProxy = ClientProxyMock(.init(userIDServerName: "matrix.org", clientProxy = ClientProxyMock(.init(userIDServerName: "matrix.org",