From 56f6fd294a36985fdb5cbbc8a3f1495f218bd0fb Mon Sep 17 00:00:00 2001 From: Mauro <34335419+Velin92@users.noreply.github.com> Date: Thu, 15 Jan 2026 14:52:18 +0100 Subject: [PATCH] Create space flow (#4957) * create space flow implementation # Conflicts: # ElementX/Sources/FlowCoordinators/SpacesTabFlowCoordinator.swift * create space flow fully implemented and working * updated tests and updated the create room camera button UI * updated the avatar button in the create room screen, and added power level overrides for spaces * update power level content overrides to behave just as EW, and removed ask to join when creating a space regardless of the FF * updated UI tests snapshots * invite for a public space should always be forced to 50 * pr suggestions + PL override fix * fix a missed code change --- .../ChatsTabFlowCoordinator.swift | 14 ++- .../SpacesTabFlowCoordinator.swift | 67 ++++++++++- .../StartChatFlowCoordinator.swift | 72 +++++++++--- .../Other/SwiftUI/Views/ToolbarButton.swift | 21 ++-- .../CreateRoomScreenCoordinator.swift | 11 +- .../CreateRoomScreenModels.swift | 7 +- .../CreateRoomScreenViewModel.swift | 18 ++- .../View/CreateRoomScreen.swift | 110 ++++++++++++++++-- .../SpacesScreenCoordinator.swift | 3 + .../SpacesScreen/SpacesScreenModels.swift | 1 + .../SpacesScreen/SpacesScreenViewModel.swift | 3 +- .../Sources/Services/Client/ClientProxy.swift | 44 ++++++- .../UITests/UITestsAppCoordinator.swift | 2 +- ...eRoom.Create-Knockable-Room-iPad-en-GB.png | 4 +- ...Room.Create-Knockable-Room-iPad-pseudo.png | 4 +- ...oom.Create-Knockable-Room-iPhone-en-GB.png | 4 +- ...om.Create-Knockable-Room-iPhone-pseudo.png | 4 +- ...-Public-Room-existing-alias-iPad-en-GB.png | 4 +- ...Public-Room-existing-alias-iPad-pseudo.png | 4 +- ...ublic-Room-existing-alias-iPhone-en-GB.png | 4 +- ...blic-Room-existing-alias-iPhone-pseudo.png | 4 +- ...eateRoom.Create-Public-Room-iPad-en-GB.png | 4 +- ...ateRoom.Create-Public-Room-iPad-pseudo.png | 4 +- ...teRoom.Create-Public-Room-iPhone-en-GB.png | 4 +- ...eRoom.Create-Public-Room-iPhone-pseudo.png | 4 +- ...e-Public-Room-invalid-alias-iPad-en-GB.png | 4 +- ...-Public-Room-invalid-alias-iPad-pseudo.png | 4 +- ...Public-Room-invalid-alias-iPhone-en-GB.png | 4 +- ...ublic-Room-invalid-alias-iPhone-pseudo.png | 4 +- .../createRoom.Create-Room-iPad-en-GB.png | 4 +- .../createRoom.Create-Room-iPad-pseudo.png | 4 +- .../createRoom.Create-Room-iPhone-en-GB.png | 4 +- .../createRoom.Create-Room-iPhone-pseudo.png | 4 +- ...oom.Create-Room-with-avatar-iPad-en-GB.png | 3 + ...om.Create-Room-with-avatar-iPad-pseudo.png | 3 + ...m.Create-Room-with-avatar-iPhone-en-GB.png | 3 + ....Create-Room-with-avatar-iPhone-pseudo.png | 3 + .../createRoom.Create-Space-iPad-en-GB.png | 4 +- .../createRoom.Create-Space-iPad-pseudo.png | 4 +- .../createRoom.Create-Space-iPhone-en-GB.png | 4 +- .../createRoom.Create-Space-iPhone-pseudo.png | 4 +- ...om.Create-Space-with-avatar-iPad-en-GB.png | 3 + ...m.Create-Space-with-avatar-iPad-pseudo.png | 3 + ....Create-Space-with-avatar-iPhone-en-GB.png | 3 + ...Create-Space-with-avatar-iPhone-pseudo.png | 3 + .../startChat.testFlow-iPad-en-GB-3.png | 4 +- .../startChat.testFlow-iPad-en-GB-5.png | 4 +- .../startChat.testFlow-iPad-en-GB-8.png | 4 +- .../startChat.testFlow-iPhone-en-GB-3.png | 4 +- .../startChat.testFlow-iPhone-en-GB-5.png | 4 +- .../startChat.testFlow-iPhone-en-GB-8.png | 4 +- .../Sources/CreateRoomViewModelTests.swift | 45 ++++++- 52 files changed, 446 insertions(+), 116 deletions(-) create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPad-en-GB.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPad-pseudo.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPhone-en-GB.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPhone-pseudo.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPad-en-GB.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPad-pseudo.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPhone-en-GB.png create mode 100644 PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPhone-pseudo.png diff --git a/ElementX/Sources/FlowCoordinators/ChatsTabFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/ChatsTabFlowCoordinator.swift index 552aaea6e..9e2422ae9 100644 --- a/ElementX/Sources/FlowCoordinators/ChatsTabFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/ChatsTabFlowCoordinator.swift @@ -567,7 +567,7 @@ class ChatsTabFlowCoordinator: FlowCoordinatorProtocol { private func startStartChatFlow(animated: Bool) { let navigationStackCoordinator = NavigationStackCoordinator() - let coordinator = StartChatFlowCoordinator(isSpace: false, + let coordinator = StartChatFlowCoordinator(entryPoint: .startChat, userDiscoveryService: UserDiscoveryService(clientProxy: userSession.clientProxy), navigationStackCoordinator: navigationStackCoordinator, flowParameters: flowParameters) @@ -576,11 +576,17 @@ class ChatsTabFlowCoordinator: FlowCoordinatorProtocol { .sink { [weak self] action in guard let self else { return } switch action { - case .finished(let roomID): + case .finished(let result): navigationSplitCoordinator.setSheetCoordinator(nil) - - if let roomID { + + switch result { + case .room(let roomID): stateMachine.processEvent(.selectRoom(roomID: roomID, via: [], entryPoint: .room)) + case .space(let spaceRoomListProxy): + // This also automatically handles selecting the space. + stateMachine.processEvent(.selectRoom(roomID: spaceRoomListProxy.id, via: [], entryPoint: .room)) + case .cancelled: + break } case .showRoomDirectory: navigationSplitCoordinator.setSheetCoordinator(nil) diff --git a/ElementX/Sources/FlowCoordinators/SpacesTabFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/SpacesTabFlowCoordinator.swift index ea5ede1d3..bec3a2fad 100644 --- a/ElementX/Sources/FlowCoordinators/SpacesTabFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/SpacesTabFlowCoordinator.swift @@ -25,12 +25,15 @@ class SpacesTabFlowCoordinator: FlowCoordinatorProtocol { private let detailNavigationStackCoordinator: NavigationStackCoordinator private var spaceFlowCoordinator: SpaceFlowCoordinator? + private var startChatFlowCoordinator: StartChatFlowCoordinator? enum State: StateType { /// The state machine hasn't started. case initial /// The root screen for this flow. case spacesScreen(selectedSpaceID: String?) + /// The create space flow is currently being presented + case createSpaceFlow } enum Event: EventType { @@ -42,6 +45,10 @@ class SpacesTabFlowCoordinator: FlowCoordinatorProtocol { case selectSpace /// The space screen has been dismissed. case deselectSpace + /// Start the create a new space flow + case startCreateSpaceFlow + /// Create space has finished + case dismissedCreateSpaceFlow } private let stateMachine: StateMachine @@ -81,16 +88,20 @@ class SpacesTabFlowCoordinator: FlowCoordinatorProtocol { switch stateMachine.state { case .initial, .spacesScreen: break + case .createSpaceFlow: + startChatFlowCoordinator?.clearRoute(animated: animated) + clearRoute(animated: animated) } } // MARK: - Private + // swiftlint:disable:next cyclomatic_complexity private func configureStateMachine() { stateMachine.addRoutes(event: .start, transitions: [.initial => .spacesScreen(selectedSpaceID: nil)]) { [weak self] _ in self?.presentSpacesScreen() } - + stateMachine.addRouteMapping { event, fromState, userInfo in guard event == .selectSpace, case .spacesScreen = fromState else { return nil } guard let spaceRoomListProxy = userInfo as? SpaceRoomListProxyProtocol else { fatalError("A space proxy must be provided.") } @@ -110,6 +121,24 @@ class SpacesTabFlowCoordinator: FlowCoordinatorProtocol { spaceFlowCoordinator = nil } + stateMachine.addRouteMapping { event, fromState, _ in + guard event == .startCreateSpaceFlow, case .spacesScreen = fromState else { return nil } + return .createSpaceFlow + } handler: { [weak self] _ in + self?.startCreateSpaceFlow() + } + + stateMachine.addRouteMapping { event, fromState, userInfo in + guard event == .dismissedCreateSpaceFlow, case .createSpaceFlow = fromState else { return nil } + return .spacesScreen(selectedSpaceID: (userInfo as? SpaceRoomListProxyProtocol)?.id) + } handler: { [weak self] context in + guard let self else { return } + startChatFlowCoordinator = nil + if let spaceRoomListProxy = context.userInfo as? SpaceRoomListProxyProtocol { + startSpaceFlow(spaceRoomListProxy: spaceRoomListProxy) + } + } + stateMachine.addErrorHandler { context in fatalError("Unexpected transition: \(context)") } @@ -129,6 +158,8 @@ class SpacesTabFlowCoordinator: FlowCoordinatorProtocol { stateMachine.tryEvent(.selectSpace, userInfo: spaceRoomListProxy) case .showSettings: actionsSubject.send(.showSettings) + case .showCreateSpace: + stateMachine.tryEvent(.startCreateSpaceFlow) } } .store(in: &cancellables) @@ -167,4 +198,38 @@ class SpacesTabFlowCoordinator: FlowCoordinatorProtocol { coordinator.start() selectedSpaceSubject.send(spaceRoomListProxy.id) } + + private func startCreateSpaceFlow() { + let coordinator = NavigationStackCoordinator() + let flowCoordinator = StartChatFlowCoordinator(entryPoint: .createSpace, + userDiscoveryService: UserDiscoveryService(clientProxy: flowParameters.userSession.clientProxy), + navigationStackCoordinator: coordinator, + flowParameters: flowParameters) + + var spaceRoomListProxy: SpaceRoomListProxyProtocol? + flowCoordinator.actionsPublisher + .sink { [weak self] action in + guard let self else { return } + switch action { + case .finished(let result): + switch result { + case .space(let value): + spaceRoomListProxy = value + case .room, .cancelled: + break + } + navigationSplitCoordinator.setSheetCoordinator(nil) + case .showRoomDirectory: + fatalError("Not handled here") + } + } + .store(in: &cancellables) + + navigationSplitCoordinator.setSheetCoordinator(coordinator) { [weak self] in + self?.stateMachine.tryEvent(.dismissedCreateSpaceFlow, userInfo: spaceRoomListProxy) + } + + flowCoordinator.start(animated: true) + startChatFlowCoordinator = flowCoordinator + } } diff --git a/ElementX/Sources/FlowCoordinators/StartChatFlowCoordinator.swift b/ElementX/Sources/FlowCoordinators/StartChatFlowCoordinator.swift index 72e82c155..386d2e7ee 100644 --- a/ElementX/Sources/FlowCoordinators/StartChatFlowCoordinator.swift +++ b/ElementX/Sources/FlowCoordinators/StartChatFlowCoordinator.swift @@ -11,12 +11,29 @@ import Foundation import SwiftState enum StartChatFlowCoordinatorAction { - case finished(roomID: String?) + case finished(Result) case showRoomDirectory + + enum Result { + case room(id: String) + case space(spaceRoomListProxy: SpaceRoomListProxyProtocol) + case cancelled + } +} + +/// A value that represents where the flow will be started. +enum StartChatFlowCoordinatorEntryPoint { + case startChat + case createSpace } class StartChatFlowCoordinator: FlowCoordinatorProtocol { - private let isSpace: Bool + struct CreatedRoomResult { + let roomProxy: JoinedRoomProxyProtocol + let spaceRoomListProxy: SpaceRoomListProxyProtocol? + } + + private let entryPoint: StartChatFlowCoordinatorEntryPoint private let userDiscoveryService: UserDiscoveryServiceProtocol private let navigationStackCoordinator: NavigationStackCoordinator @@ -40,7 +57,7 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { enum Event: EventType { /// The flow is being started. - case start + case start(entryPoint: StartChatFlowCoordinatorEntryPoint) /// The user would like to create a room. case createRoom @@ -64,11 +81,11 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { actionsSubject.eraseToAnyPublisher() } - init(isSpace: Bool, + init(entryPoint: StartChatFlowCoordinatorEntryPoint, userDiscoveryService: UserDiscoveryServiceProtocol, navigationStackCoordinator: NavigationStackCoordinator, flowParameters: CommonFlowParameters) { - self.isSpace = isSpace + self.entryPoint = entryPoint self.userDiscoveryService = userDiscoveryService self.navigationStackCoordinator = navigationStackCoordinator @@ -79,7 +96,7 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { } func start(animated: Bool) { - stateMachine.tryEvent(.start) + stateMachine.tryEvent(.start(entryPoint: entryPoint)) } func handleAppRoute(_ appRoute: AppRoute, animated: Bool) { @@ -109,12 +126,16 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { // MARK: - Private private func configureStateMachine() { - stateMachine.addRoutes(event: .start, transitions: [.initial => .startChat]) { [weak self] _ in + stateMachine.addRoutes(event: .start(entryPoint: .startChat), transitions: [.initial => .startChat]) { [weak self] _ in self?.presentStartChatScreen() } + stateMachine.addRoutes(event: .start(entryPoint: .createSpace), transitions: [.initial => .createRoom]) { [weak self] _ in + self?.presentCreateRoomScreen(isSpace: true, isRoot: true) + } + stateMachine.addRoutes(event: .createRoom, transitions: [.startChat => .createRoom]) { [weak self] _ in - self?.presentCreateRoomScreen() + self?.presentCreateRoomScreen(isSpace: false, isRoot: false) } stateMachine.addRoutes(event: .dismissedCreateRoom, transitions: [.createRoom => .startChat]) { [weak self] _ in self?.createRoomScreenCoordinator = nil @@ -129,10 +150,10 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { stateMachine.addRoutes(event: .dismissedRoomAvatarPicker, transitions: [.roomAvatarPicker => .createRoom]) stateMachine.addRoutes(event: .createdRoom, transitions: [.createRoom => .inviteUsers]) { [weak self] context in - guard let roomProxy = context.userInfo as? JoinedRoomProxyProtocol else { + guard let result = context.userInfo as? CreatedRoomResult else { fatalError("A room proxy is required to invite users.") } - self?.presentInviteUsersScreen(roomProxy: roomProxy) + self?.presentInviteUsersScreen(roomProxy: result.roomProxy, spaceRoomListProxy: result.spaceRoomListProxy) } stateMachine.addErrorHandler { context in @@ -156,11 +177,11 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { guard let self else { return } switch action { case .close: - actionsSubject.send(.finished(roomID: nil)) + actionsSubject.send(.finished(.cancelled)) case .createRoom: stateMachine.tryEvent(.createRoom) case .openRoom(let roomID): - actionsSubject.send(.finished(roomID: roomID)) + actionsSubject.send(.finished(.room(id: roomID))) case .openRoomDirectorySearch: actionsSubject.send(.showRoomDirectory) } @@ -170,8 +191,9 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { navigationStackCoordinator.setRootCoordinator(coordinator) } - private func presentCreateRoomScreen() { + private func presentCreateRoomScreen(isSpace: Bool, isRoot: Bool) { let createParameters = CreateRoomScreenCoordinatorParameters(isSpace: isSpace, + shouldShowCancelButton: isRoot, userSession: flowParameters.userSession, userIndicatorController: flowParameters.userIndicatorController, appSettings: flowParameters.appSettings, @@ -180,17 +202,25 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { coordinator.actions.sink { [weak self] action in guard let self else { return } switch action { - case .createdRoom(let roomProxy): - stateMachine.tryEvent(.createdRoom, userInfo: roomProxy) + case .createdRoom(let roomProxy, let spaceRoomListProxy): + stateMachine.tryEvent(.createdRoom, userInfo: CreatedRoomResult(roomProxy: roomProxy, spaceRoomListProxy: spaceRoomListProxy)) case .displayMediaPickerWithMode(let mode): stateMachine.tryEvent(.presentRoomAvatarPicker, userInfo: mode) + case .dismiss: + // Only used when isRoot + actionsSubject.send(.finished(.cancelled)) } } .store(in: &cancellables) createRoomScreenCoordinator = coordinator - navigationStackCoordinator.push(coordinator) { [weak self] in - self?.stateMachine.tryEvent(.dismissedCreateRoom) + + if isRoot { + navigationStackCoordinator.setRootCoordinator(coordinator) + } else { + navigationStackCoordinator.push(coordinator) { [weak self] in + self?.stateMachine.tryEvent(.dismissedCreateRoom) + } } } @@ -219,7 +249,7 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { } } - private func presentInviteUsersScreen(roomProxy: JoinedRoomProxyProtocol) { + private func presentInviteUsersScreen(roomProxy: JoinedRoomProxyProtocol, spaceRoomListProxy: SpaceRoomListProxyProtocol?) { let inviteParameters = InviteUsersScreenCoordinatorParameters(userSession: flowParameters.userSession, roomProxy: roomProxy, isSkippable: true, @@ -231,7 +261,11 @@ class StartChatFlowCoordinator: FlowCoordinatorProtocol { guard let self else { return } switch action { case .dismiss: - actionsSubject.send(.finished(roomID: roomProxy.id)) + if let spaceRoomListProxy { + actionsSubject.send(.finished(.space(spaceRoomListProxy: spaceRoomListProxy))) + } else { + actionsSubject.send(.finished(.room(id: roomProxy.id))) + } } } .store(in: &cancellables) diff --git a/ElementX/Sources/Other/SwiftUI/Views/ToolbarButton.swift b/ElementX/Sources/Other/SwiftUI/Views/ToolbarButton.swift index dd733da41..8827c211e 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/ToolbarButton.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/ToolbarButton.swift @@ -10,18 +10,17 @@ import SwiftUI struct ToolbarButton: View { enum Role { - case cancel - case done - case save + static let cancel = Role.cancel(title: L10n.actionCancel) + static let done = Role.confirm(title: L10n.actionDone) + static let save = Role.confirm(title: L10n.actionSave) + + case cancel(title: String) + case confirm(title: String) var title: String { switch self { - case .cancel: - L10n.actionCancel - case .done: - L10n.actionDone - case .save: - L10n.actionSave + case .cancel(let title), .confirm(let title): + title } } @@ -31,7 +30,7 @@ struct ToolbarButton: View { case .cancel: CompoundIcon(\.close) .foregroundStyle(.compound.iconPrimary) - case .done, .save: + case .confirm: CompoundIcon(\.check) .foregroundStyle(.compound.iconOnSolidPrimary) } @@ -41,7 +40,7 @@ struct ToolbarButton: View { switch self { case .cancel: .compound.bgCanvasDefault - case .done, .save: + case .confirm: .compound.bgAccentRest } } diff --git a/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenCoordinator.swift b/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenCoordinator.swift index 4a29d6c04..9f392ac72 100644 --- a/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenCoordinator.swift +++ b/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenCoordinator.swift @@ -11,6 +11,7 @@ import SwiftUI struct CreateRoomScreenCoordinatorParameters { let isSpace: Bool + let shouldShowCancelButton: Bool let userSession: UserSessionProtocol let userIndicatorController: UserIndicatorControllerProtocol let appSettings: AppSettings @@ -18,8 +19,9 @@ struct CreateRoomScreenCoordinatorParameters { } enum CreateRoomScreenCoordinatorAction { - case createdRoom(JoinedRoomProxyProtocol) + case createdRoom(JoinedRoomProxyProtocol, SpaceRoomListProxyProtocol?) case displayMediaPickerWithMode(MediaPickerScreenMode) + case dismiss } final class CreateRoomScreenCoordinator: CoordinatorProtocol { @@ -33,6 +35,7 @@ final class CreateRoomScreenCoordinator: CoordinatorProtocol { init(parameters: CreateRoomScreenCoordinatorParameters) { viewModel = CreateRoomScreenViewModel(isSpace: parameters.isSpace, + shouldShowCancelButton: parameters.shouldShowCancelButton, userSession: parameters.userSession, analytics: parameters.analytics, userIndicatorController: parameters.userIndicatorController, @@ -43,12 +46,14 @@ final class CreateRoomScreenCoordinator: CoordinatorProtocol { viewModel.actions.sink { [weak self] action in guard let self else { return } switch action { - case .createdRoom(let roomProxy): - actionsSubject.send(.createdRoom(roomProxy)) + case .createdRoom(let roomProxy, let spaceRoomListProxy): + actionsSubject.send(.createdRoom(roomProxy, spaceRoomListProxy)) case .displayCameraPicker: actionsSubject.send(.displayMediaPickerWithMode(.init(source: .camera, selectionType: .single))) case .displayMediaPicker: actionsSubject.send(.displayMediaPickerWithMode(.init(source: .photoLibrary, selectionType: .single))) + case .dismiss: + actionsSubject.send(.dismiss) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenModels.swift b/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenModels.swift index 1a904af2b..5d5bfcdc1 100644 --- a/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenModels.swift +++ b/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenModels.swift @@ -17,13 +17,15 @@ enum CreateRoomScreenErrorType: Error { } enum CreateRoomScreenViewModelAction { - case createdRoom(JoinedRoomProxyProtocol) + case createdRoom(JoinedRoomProxyProtocol, SpaceRoomListProxyProtocol?) case displayMediaPicker case displayCameraPicker + case dismiss } struct CreateRoomScreenViewState: BindableState { let isSpace: Bool + let shouldShowCancelButton: Bool var roomName: String let serverName: String let isKnockingFeatureEnabled: Bool @@ -47,7 +49,7 @@ struct CreateRoomScreenViewState: BindableState { var availableAccessTypes: [CreateRoomAccessType] { var availableTypes = CreateRoomAccessType.allCases - if !isKnockingFeatureEnabled { + if isSpace || !isKnockingFeatureEnabled { availableTypes.removeAll { $0 == .askToJoin } } return availableTypes @@ -64,6 +66,7 @@ struct CreateRoomScreenViewStateBindings { } enum CreateRoomScreenViewAction { + case dismiss case createRoom case displayCameraPicker case displayMediaPicker diff --git a/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenViewModel.swift b/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenViewModel.swift index cf979399a..5c60c970f 100644 --- a/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/CreateRoomScreen/CreateRoomScreenViewModel.swift @@ -27,6 +27,7 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen } init(isSpace: Bool, + shouldShowCancelButton: Bool, userSession: UserSessionProtocol, analytics: AnalyticsService, userIndicatorController: UserIndicatorControllerProtocol, @@ -40,6 +41,7 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen selectedAccessType: .private) super.init(initialViewState: CreateRoomScreenViewState(isSpace: isSpace, + shouldShowCancelButton: shouldShowCancelButton, roomName: "", serverName: userSession.clientProxy.userIDServerName ?? "", isKnockingFeatureEnabled: appSettings.knockingEnabled, @@ -54,6 +56,8 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen override func process(viewAction: CreateRoomScreenViewAction) { switch viewAction { + case .dismiss: + actionsSubject.send(.dismiss) case .createRoom: Task { await createRoom() } case .displayCameraPicker: @@ -233,7 +237,19 @@ class CreateRoomScreenViewModel: CreateRoomScreenViewModelType, CreateRoomScreen return } analytics.trackCreatedRoom(isDM: false) - actionsSubject.send(.createdRoom(roomProxy)) + + var spaceRoomListProxy: SpaceRoomListProxyProtocol? + if state.isSpace { + switch await userSession.clientProxy.spaceService.spaceRoomList(spaceID: roomProxy.id) { + case .success(let value): + spaceRoomListProxy = value + case .failure: + MXLog.error("Failed to get space room list for newly created space with id: \(roomProxy.id)") + userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown)) + } + } + + actionsSubject.send(.createdRoom(roomProxy, spaceRoomListProxy)) case .failure: state.bindings.alertInfo = AlertInfo(id: .failedCreatingRoom, title: L10n.commonError, diff --git a/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift b/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift index ea25be4f3..40aa82194 100644 --- a/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift +++ b/ElementX/Sources/Screens/CreateRoomScreen/View/CreateRoomScreen.swift @@ -54,8 +54,18 @@ struct CreateRoomScreen: View { .shouldScrollOnKeyboardDidShow(focus == .alias, to: Focus.alias) } + private var nameTextFieldShape: AnyShape { + if #available(iOS 26, *) { + AnyShape(ConcentricRectangle(corners: .concentric(minimum: 26))) + } else { + AnyShape(RoundedRectangle(cornerRadius: 12)) + } + } + private var roomSection: some View { Section { + EmptyView() + } header: { HStack(alignment: .center, spacing: 16) { roomAvatarButton let nameLabel = if #available(iOS 26, *) { @@ -80,11 +90,11 @@ struct CreateRoomScreen: View { .accessibilityIdentifier(A11yIdentifiers.createRoomScreen.roomName) .padding(.horizontal, ListRowPadding.horizontal) .padding(.vertical, ListRowPadding.vertical) - .background(.compound.bgCanvasDefaultLevel1, in: RoundedRectangle(cornerRadius: 12)) + .background(.compound.bgCanvasDefaultLevel1, in: nameTextFieldShape) } } .listRowInsets(.init()) - .listRowBackground(Color.clear) + .padding(.top, 16) } } @@ -101,15 +111,27 @@ struct CreateRoomScreen: View { } placeholder: { ProgressView() } - .scaledFrame(size: 70) - .clipShape(Circle()) + .scaledFrame(size: 70, relativeTo: .title) + .clipShape(context.viewState.isSpace ? AnyShape(RoundedRectangle(cornerRadius: 16)) : AnyShape(Circle())) + .overlay(alignment: .bottomTrailing) { + editAvatarBadge + .scaledOffset(x: 12, y: 4, relativeTo: .title) + .accessibilityHidden(true) + } } else { - CompoundIcon(\.takePhoto, size: .custom(36), relativeTo: .title) - .foregroundColor(.compound.iconSecondary) - .scaledFrame(size: 70, relativeTo: .title) - .background(.compound.bgSubtlePrimary, in: Circle()) + CompoundIcon(\.takePhoto, size: .medium, relativeTo: .title) + .foregroundColor(.compound.iconPrimary) + .scaledFrame(size: 50, relativeTo: .title) + .background(.compound.bgCanvasDefault, in: Circle()) + .overlay { + Circle() + .stroke(.compound.borderInteractiveSecondary, lineWidth: 1) + } + .padding(10) + .accessibilityHidden(true) } } + .accessibilityLabel(L10n.a11yEditAvatar) .buttonStyle(.plain) .accessibilityIdentifier(A11yIdentifiers.createRoomScreen.roomAvatar) .confirmationDialog("", isPresented: $context.showAttachmentConfirmationDialog) { @@ -129,6 +151,23 @@ struct CreateRoomScreen: View { } } + private var editAvatarBadge: some View { + CompoundIcon(\.edit, size: .small, relativeTo: .body) + .foregroundStyle(.compound.iconPrimary) + .scaledPadding(5, relativeTo: .title) + .background { + Circle() + .fill(Color.compound.bgCanvasDefault) + .overlay { + Circle() + .inset(by: 0.5) + .stroke(.compound.borderInteractiveSecondary, lineWidth: 1) + } + } + .scaledPadding(3.5, relativeTo: .title) + .background(.compound.bgSubtleSecondaryLevel0, in: Circle()) + } + private var topicSection: some View { Section { ListRow(label: .plain(title: L10n.screenCreateRoomTopicPlaceholder), @@ -180,9 +219,18 @@ struct CreateRoomScreen: View { } } + @ToolbarContentBuilder private var toolbar: some ToolbarContent { + if context.viewState.shouldShowCancelButton { + ToolbarItem(placement: .topBarLeading) { + ToolbarButton(role: .cancel) { + context.send(viewAction: .dismiss) + } + } + } + ToolbarItem(placement: .confirmationAction) { - Button(L10n.actionCreate) { + ToolbarButton(role: .confirm(title: L10n.actionCreate)) { focus = nil context.send(viewAction: .createRoom) } @@ -247,26 +295,55 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview { AppSettings.resetAllSettings() let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com")))) return CreateRoomScreenViewModel(isSpace: false, + shouldShowCancelButton: false, userSession: userSession, analytics: ServiceLocator.shared.analytics, userIndicatorController: UserIndicatorControllerMock(), appSettings: ServiceLocator.shared.settings) }() + static let avatarViewModel = { + AppSettings.resetAllSettings() + let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com")))) + let viewModel = CreateRoomScreenViewModel(isSpace: false, + shouldShowCancelButton: false, + userSession: userSession, + analytics: ServiceLocator.shared.analytics, + userIndicatorController: UserIndicatorControllerMock(), + appSettings: ServiceLocator.shared.settings) + viewModel.updateAvatar(fileURL: Bundle.main.url(forResource: "preview_avatar_room", withExtension: "jpg")!) + return viewModel + }() + static let spaceViewModel = { AppSettings.resetAllSettings() let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com")))) return CreateRoomScreenViewModel(isSpace: true, + shouldShowCancelButton: true, userSession: userSession, analytics: ServiceLocator.shared.analytics, userIndicatorController: UserIndicatorControllerMock(), appSettings: ServiceLocator.shared.settings) }() + static let spaceWithAvatarViewModel = { + AppSettings.resetAllSettings() + let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userID: "@userid:example.com")))) + let viewModel = CreateRoomScreenViewModel(isSpace: true, + shouldShowCancelButton: true, + userSession: userSession, + analytics: ServiceLocator.shared.analytics, + userIndicatorController: UserIndicatorControllerMock(), + appSettings: ServiceLocator.shared.settings) + viewModel.updateAvatar(fileURL: Bundle.main.url(forResource: "preview_avatar_room", withExtension: "jpg")!) + return viewModel + }() + static let publicRoomViewModel = { AppSettings.resetAllSettings() let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com")))) let viewModel = CreateRoomScreenViewModel(isSpace: false, + shouldShowCancelButton: false, userSession: userSession, analytics: ServiceLocator.shared.analytics, userIndicatorController: UserIndicatorControllerMock(), @@ -281,6 +358,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview { appSettings.knockingEnabled = true let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com")))) let viewModel = CreateRoomScreenViewModel(isSpace: false, + shouldShowCancelButton: false, userSession: userSession, analytics: ServiceLocator.shared.analytics, userIndicatorController: UserIndicatorControllerMock(), @@ -293,6 +371,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview { AppSettings.resetAllSettings() let userSession = UserSessionMock(.init(clientProxy: ClientProxyMock(.init(userIDServerName: "example.org", userID: "@userid:example.com")))) let viewModel = CreateRoomScreenViewModel(isSpace: false, + shouldShowCancelButton: false, userSession: userSession, analytics: ServiceLocator.shared.analytics, userIndicatorController: UserIndicatorControllerMock(), @@ -308,6 +387,7 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview { clientProxy.isAliasAvailableReturnValue = .success(false) let userSession = UserSessionMock(.init(clientProxy: clientProxy)) let viewModel = CreateRoomScreenViewModel(isSpace: false, + shouldShowCancelButton: false, userSession: userSession, analytics: ServiceLocator.shared.analytics, userIndicatorController: UserIndicatorControllerMock(), @@ -323,11 +403,23 @@ struct CreateRoom_Previews: PreviewProvider, TestablePreview { } .previewDisplayName("Create Room") + NavigationStack { + CreateRoomScreen(context: avatarViewModel.context) + } + .previewDisplayName("Create Room with avatar") + .snapshotPreferences(expect: avatarViewModel.context.$viewState.map { $0.avatarMediaInfo != nil }) + NavigationStack { CreateRoomScreen(context: spaceViewModel.context) } .previewDisplayName("Create Space") + NavigationStack { + CreateRoomScreen(context: spaceWithAvatarViewModel.context) + } + .previewDisplayName("Create Space with avatar") + .snapshotPreferences(expect: spaceWithAvatarViewModel.context.$viewState.map { $0.avatarMediaInfo != nil }) + NavigationStack { CreateRoomScreen(context: publicRoomViewModel.context) } diff --git a/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenCoordinator.swift b/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenCoordinator.swift index 25b48c742..fc2de168c 100644 --- a/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenCoordinator.swift +++ b/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenCoordinator.swift @@ -19,6 +19,7 @@ struct SpacesScreenCoordinatorParameters { enum SpacesScreenCoordinatorAction { case selectSpace(SpaceRoomListProxyProtocol) case showSettings + case showCreateSpace } final class SpacesScreenCoordinator: CoordinatorProtocol { @@ -51,6 +52,8 @@ final class SpacesScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.selectSpace(spaceRoomListProxy)) case .showSettings: actionsSubject.send(.showSettings) + case .showCreateSpace: + actionsSubject.send(.showCreateSpace) } } .store(in: &cancellables) diff --git a/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenModels.swift b/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenModels.swift index 2b68805c4..fb154b4a8 100644 --- a/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenModels.swift +++ b/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenModels.swift @@ -11,6 +11,7 @@ import Foundation enum SpacesScreenViewModelAction { case selectSpace(SpaceRoomListProxyProtocol) case showSettings + case showCreateSpace } struct SpacesScreenViewState: BindableState { diff --git a/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenViewModel.swift b/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenViewModel.swift index 6a7ea9b54..9c3a7eb77 100644 --- a/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenViewModel.swift +++ b/ElementX/Sources/Screens/Spaces/SpacesScreen/SpacesScreenViewModel.swift @@ -79,8 +79,7 @@ class SpacesScreenViewModel: SpacesScreenViewModelType, SpacesScreenViewModelPro case .featureAnnouncementAppeared: appSettings.hasSeenSpacesAnnouncement = true case .createSpace: - // TODO: Implement - break + actionsSubject.send(.showCreateSpace) } } diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 10f3575e3..23aa0e9be 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -67,7 +67,7 @@ class ClientProxy: ClientProxyProtocol { ban: nil, kick: nil, redact: nil, - invite: nil, + invite: Int32(0), notifications: nil, users: [:], events: [ @@ -91,6 +91,32 @@ class ClientProxy: ClientProxyProtocol { "org.matrix.msc3401.call.member": Int32(0) ]) } + + private static var standardSpaceCreationPowerLevelOverrides: PowerLevels { + .init(usersDefault: nil, + eventsDefault: Int32(100), + stateDefault: nil, + ban: nil, + kick: nil, + redact: nil, + invite: Int32(50), + notifications: nil, + users: [:], + events: [:]) + } + + private static var publicSpaceCreationPowerLevelOverrides: PowerLevels { + .init(usersDefault: nil, + eventsDefault: Int32(100), + stateDefault: nil, + ban: nil, + kick: nil, + redact: nil, + invite: Int32(0), + notifications: nil, + users: [:], + events: [:]) + } private var loadCachedAvatarURLTask: Task? private let userAvatarURLSubject = CurrentValueSubject(nil) @@ -480,6 +506,20 @@ class ClientProxy: ClientProxyProtocol { avatarURL: URL?, aliasLocalPart: String?) async -> Result { do { + let powerLevelContentOverride = if isSpace { + if accessType == .public { + Self.publicSpaceCreationPowerLevelOverrides + } else { + Self.standardSpaceCreationPowerLevelOverrides + } + } else { + if accessType == .askToJoin { + Self.knockingRoomCreationPowerLevelOverrides + } else { + Self.roomCreationPowerLevelOverrides + } + } + let parameters = CreateRoomParameters(name: name, topic: topic, isEncrypted: accessType.isEncrypted, @@ -488,7 +528,7 @@ class ClientProxy: ClientProxyProtocol { preset: accessType.preset, invite: userIDs, avatar: avatarURL?.absoluteString, - powerLevelContentOverride: accessType == .askToJoin ? Self.knockingRoomCreationPowerLevelOverrides : Self.roomCreationPowerLevelOverrides, + powerLevelContentOverride: powerLevelContentOverride, joinRuleOverride: accessType.joinRuleOverride, historyVisibilityOverride: accessType.historyVisibilityOverride, // This is an FFI naming mistake, what is required is the `aliasLocalPart` not the whole alias diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index 51841abe7..fb37353aa 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -659,7 +659,7 @@ class MockScreen: Identifiable { userDiscoveryService.searchProfilesWithReturnValue = .success([.mockBob, .mockBobby]) let navigationStackCoordinator = NavigationStackCoordinator() - let flowCoordinator = StartChatFlowCoordinator(isSpace: false, + let flowCoordinator = StartChatFlowCoordinator(entryPoint: .startChat, userDiscoveryService: userDiscoveryService, navigationStackCoordinator: navigationStackCoordinator, flowParameters: CommonFlowParameters(userSession: UserSessionMock(.init(clientProxy: clientProxy)), diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPad-en-GB.png index beb92736b..a8cb232d6 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f513aac79644e109b9cd0be2cf88e47362a70bdd39e92688fecbeab9d49e6414 -size 157858 +oid sha256:aa327c6149879d4aa96fa4c5574bac7486fc6abfaa003ae74596c8b88adf6b0b +size 156228 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPad-pseudo.png index 3762ba6ab..624ac63ee 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4dcf0f103278fa02af6c0d97f54791e14f25d1f5ec0e31eba5b080e21ce6858 -size 187550 +oid sha256:704b115de7bad6d64ea253ea261a8812e536622dc32280a11e91a3bdc9473340 +size 186268 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPhone-en-GB.png index 581287721..36c02cecc 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6e0f7572a47ad8fbc35bbe862e8d0634dd1357f4559bd54d6cb57d481485763 -size 105733 +oid sha256:66f4d91f70ce033d8c6553479ecf7471d53ffdb181986cea4c9032701a595c25 +size 106657 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPhone-pseudo.png index 46e92876b..13abef3d1 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Knockable-Room-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:abcffb042721e323327f3c70f4cdca89ff56654887293b2f9b2215cc486d465c -size 142332 +oid sha256:0c355007d6ac8f669a701f0ef534e6e381895722d3c495be9e4ef49d20a7de79 +size 143489 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPad-en-GB.png index b4462539a..a1feeb99f 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c744f0ddc6f0e2cb2e2063cc0135d18a07f18d3a58314ee33651962295199225 -size 158006 +oid sha256:31efa5cc91a3b0a623056e85e8d5e0c6544a464d959b29ef771e2c9fa2843d7e +size 156446 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPad-pseudo.png index 1e97c3796..286663aff 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:301081a176b706092f008e01c9a195dd58c7dc28adc7a42d38ee5e4c168cd1a2 -size 189421 +oid sha256:e638ad86f90e438978096a9fc928f85b6ca0d883f02221978307fe3068e20e35 +size 188066 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPhone-en-GB.png index 6ee4cc474..ba696a46e 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7128f0417b2479525d2b35bfb4a501ac24690694f34841bc7ecf0d922741654d -size 109846 +oid sha256:9b51dfc640af59dd5b3564148d48a1267e9423b1c77fb02edc4607d91d10910b +size 108742 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPhone-pseudo.png index 37d6d50f3..26191b58d 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-existing-alias-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2a656ea4051f6a84282fca5f94978b199ec10df51dac04a7ad01c4ec55b6ae1f -size 146993 +oid sha256:8b8b277cc422ac3f6fba5b7b555e42c18d2b6ecde65a36eba6c4b63279fb80b5 +size 145650 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPad-en-GB.png index aaee17e36..1aec2e6cb 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c110232459827a0f641057ed1bfc6bfdb714134f3a658fa5acee9a9395bf62a -size 142457 +oid sha256:b71055f825775861294542ae166fbe7013800fc3672ce4d39ab4419716eedf45 +size 141129 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPad-pseudo.png index 6992e9bf5..1bf61662a 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:729a6515bc93eb02be4d04a60c07f3854875ab2404a282a5de8bd11ae9e86a89 -size 165595 +oid sha256:d2b85ce0989c5e068e489de22275aeaf723e51fe6b18cb304d16b831e8e8f368 +size 164236 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPhone-en-GB.png index 77997a5ee..1aa22bd6c 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9d4b216831eb0595f1b3adbf0fade0d3db2e621d7922dbc647b62fc31ddc854f -size 88801 +oid sha256:a5adc15a61b998447a66a4696b59f89413381583c4455be02b1f28594701b986 +size 89299 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPhone-pseudo.png index 26905829d..0f80e3a3a 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c3cfa55a1a89d1905c5c21d5aeadce37d8554487054c2abe6c7d39323e7359c4 -size 115037 +oid sha256:5823312ac25afe1b349f8eda8807299d6c30656e961d387c01e544eda40e6c4e +size 116112 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPad-en-GB.png index 695aeb728..06fec2121 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea061eb260fdeebd3d38a6f32c209345f45dfe3188bff5ebb4e5fefa26bd73e3 -size 161310 +oid sha256:400c0c0ed48ced1122851b21a6d3e9e48f0985635711fec7e4abe8660994a6b1 +size 159870 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPad-pseudo.png index 31205324a..6ba27ebad 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc8f86bff3d1377c3ca9cca775c998a736a90211d7bb4d03439aa788bdc60160 -size 197756 +oid sha256:575f32a8b119f2ffbaf6e234b9ea23366850ea245f3f63403a9ba0a2691a2a3b +size 195889 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPhone-en-GB.png index 84b2366c0..75b8ede59 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c58d9126bdf00d7b64ac59b740645d456ad06fe66ff67f0e805eb4b140f0adc1 -size 111712 +oid sha256:9002a2ad841596a8e206326fa282b131b750cc556e57a8b8fbf355318106e6ac +size 110759 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPhone-pseudo.png index 9931b4d1e..b3d4606ed 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Public-Room-invalid-alias-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3cc77ead9f512f919377e076cf95cba2678a0eb3d7c79395dfcdd33a82d32d3f -size 152160 +oid sha256:fab82b9e91cb4b3bad0a3bd13e1b2077a992473889ddb62297d0c902d724e104 +size 150819 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPad-en-GB.png index 3ffab95c3..4fd98f7f9 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26726c399334387ad4f4f9603af729dd998d8aa40e31175def2b1719e3fe27ec -size 124557 +oid sha256:9db61c6bde46ef08cfd7d1aceb50f379544053024ac4633d1234c863c98c066a +size 123222 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPad-pseudo.png index 089968bc0..34ad85b1e 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f0b7534290fc773b98633250f05b434ef83c5f8243dd891de5bc58902941e28 -size 142357 +oid sha256:e287da07572fd2bd3424894537844637e57629235b372108a8d99ae1b0994b1b +size 140788 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPhone-en-GB.png index 8fbd5ceba..e5f5a4784 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:37a460ee15e802c3a165053bba730a911518682570d0692c2f1228913936cb95 -size 72654 +oid sha256:8b820693bf00b97aaa0a797808106267ce741e495bba57936de8082dc4745bbf +size 73369 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPhone-pseudo.png index 29e88a9c0..29257ad13 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b1447dc8d94468cbb42821eea9bc4431ad6c26682a3ef3901d11d80bddaed9a -size 89114 +oid sha256:ff2841d40e79e09cc472837c7ff350082d6d60894539302056c0d20f645264b1 +size 90112 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPad-en-GB.png new file mode 100644 index 000000000..f983346d6 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPad-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9540a4055953e7e3462ccff5605af75f435f5ce7743f09f745d560c3daba7afd +size 122057 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPad-pseudo.png new file mode 100644 index 000000000..3cb6d8dbb --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPad-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d573231fbd9098847e02e294a362116e6b71a5959b37cfcd46043dfc18e5d2de +size 139671 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPhone-en-GB.png new file mode 100644 index 000000000..b08c89c7a --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPhone-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eebf3dac12738f6f864f382ac9b136e29c19ae9c9874d900891a1c55c6d006da +size 72559 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPhone-pseudo.png new file mode 100644 index 000000000..81181609c --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Room-with-avatar-iPhone-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68000903e55e1ba5a98b082b33b65d03c111c5751947bf6297f1a4fd46d0189f +size 89331 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPad-en-GB.png index 4b983b057..caaf4cfa9 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPad-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPad-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0152d34aba8e7c97fd38b48433a83dee21ceaea96aacbb070782d65a75bfc4ce -size 125037 +oid sha256:b112313be37d156c4ec72d85ec9a2859d36dda4d0674171d9dea25a637eabc47 +size 124039 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPad-pseudo.png index 1c9340657..2c49467bd 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPad-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPad-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5e9b590ea56f6498031583f2eceda6c1269a697b532006d8226a5c0fb152ca41 -size 142802 +oid sha256:029da760106a69b208e4cb55df1a78d6552bc8a6bed70a31e1c1efbf6bf60721 +size 141624 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPhone-en-GB.png index a2b259280..b373f7711 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPhone-en-GB.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPhone-en-GB.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c672bfb3589592b0cdcd373ce02e47ebcdaf695d8f1e009381f2c527f326aed2 -size 73155 +oid sha256:a069f80fe0ac2f396ac06f5b508fee9f5cec7880ecbc047dbb351ffab5132ef2 +size 73872 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPhone-pseudo.png index 42ee35ca9..06db0f24b 100644 --- a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPhone-pseudo.png +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-iPhone-pseudo.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b61ca92955968e5905967c5a62da3de062a561f608d6da3f7e200776a76ebfda -size 89771 +oid sha256:2e46256ac2ff573d13b1428bfdc5f06c536b9ab263812fa52c3e0a0ec89a6993 +size 90692 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPad-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPad-en-GB.png new file mode 100644 index 000000000..b77e663d8 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPad-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:619174a05f46847dfcab7d8edb7687ac87a6691ba2e7cbbb7965fd7d607269ff +size 122895 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPad-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPad-pseudo.png new file mode 100644 index 000000000..f6fa75c57 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPad-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:957faa7854136c335661ece9b9b57fa40ecee742cbaf2f01b8e96035f267a859 +size 140534 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPhone-en-GB.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPhone-en-GB.png new file mode 100644 index 000000000..0c7fad200 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPhone-en-GB.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7b4bd8e3da8f046b783b20fd2ac3f13fb6dd9fab1db692e5fa57f6a46f25f14 +size 73322 diff --git a/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPhone-pseudo.png b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPhone-pseudo.png new file mode 100644 index 000000000..d7523be23 --- /dev/null +++ b/PreviewTests/Sources/__Snapshots__/PreviewTests/createRoom.Create-Space-with-avatar-iPhone-pseudo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a87553939add3b0a99da570833fed8c0607afa8a10b0543c16d08154ddba34ff +size 90212 diff --git a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-3.png b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-3.png index 73c5ceaf5..866aed301 100644 --- a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-3.png +++ b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:43381daca1607ec68fc02e2d1287c9e3323fc8c44b168cb585a1378cc29724e3 -size 188246 +oid sha256:7058d76a8ad923e53494351880460242e1da254cabac48785b858eed3048a3f8 +size 174195 diff --git a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-5.png b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-5.png index fcf9eefa5..a584b60b5 100644 --- a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-5.png +++ b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6288614b6c59539ad70d8e8beb7c733fa5c4d5f4bf2b630eefb8394dd5cbc4f1 -size 185149 +oid sha256:fc69f92a9394c36a6e56d80af159821a1ef7a601c9361b24534db43d8cbae987 +size 172308 diff --git a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-8.png b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-8.png index 3df2add68..ff1bc1eae 100644 --- a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-8.png +++ b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPad-en-GB-8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dff103ed93f80acb3d13a3e3bcfff6c5f79a70042c8e46f0369e526dcfb882bd -size 174382 +oid sha256:3d22b6ed92303cd4ef902f7b2a513301293c9a82058ed49bc983bf8051a63207 +size 172371 diff --git a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-3.png b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-3.png index 8d5409c95..db16de2cd 100644 --- a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-3.png +++ b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-3.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a60bf270de7142d5712b239a6f1c1c80ccb9b67312b06e624509441816c5c3a2 -size 159489 +oid sha256:2c44caac7d1ea4a4539d36e5b28a6649d1ca4d9e6c34c0c83558a3518e9428a4 +size 134111 diff --git a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-5.png b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-5.png index 26bb22867..93648b2c4 100644 --- a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-5.png +++ b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-5.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9136ad78475665ced621f4fbc0d3c751d68995c4a860496cacf55a6eb6c5bb16 -size 154668 +oid sha256:d94d00822ddcddeda53539e81d9b2a2c01100fb573e28cfae36aa2ea87d6fe86 +size 132023 diff --git a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-8.png b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-8.png index 371c72bbc..3b5ad6035 100644 --- a/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-8.png +++ b/UITests/Sources/__Snapshots__/Application/startChat.testFlow-iPhone-en-GB-8.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:78827dda8f31802f0f25c1475af2c355ac0369797e4c8b510a05f7032c480c61 -size 131018 +oid sha256:2020495c6e1de6a801a16b78b560531f5fab86ce292998e3348c744043c88aa6 +size 129538 diff --git a/UnitTests/Sources/CreateRoomViewModelTests.swift b/UnitTests/Sources/CreateRoomViewModelTests.swift index 9bcd5c48c..c3b8a951a 100644 --- a/UnitTests/Sources/CreateRoomViewModelTests.swift +++ b/UnitTests/Sources/CreateRoomViewModelTests.swift @@ -29,6 +29,7 @@ class CreateRoomScreenViewModelTests: XCTestCase { userSession = UserSessionMock(.init(clientProxy: clientProxy)) ServiceLocator.shared.settings.knockingEnabled = true let viewModel = CreateRoomScreenViewModel(isSpace: false, + shouldShowCancelButton: false, userSession: userSession, analytics: ServiceLocator.shared.analytics, userIndicatorController: UserIndicatorControllerMock(), @@ -38,6 +39,9 @@ class CreateRoomScreenViewModelTests: XCTestCase { override func tearDown() { AppSettings.resetAllSettings() + viewModel = nil + clientProxy = nil + userSession = nil } func testDefaultSecurity() { @@ -60,7 +64,46 @@ class CreateRoomScreenViewModelTests: XCTestCase { // When creating the room. clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .success("1") let deferred = deferFulfillment(viewModel.actions) { action in - guard case .createdRoom(let roomProxy) = action, roomProxy.id == "1" else { return false } + guard case .createdRoom(let roomProxy, nil) = action, roomProxy.id == "1" else { return false } + return true + } + context.send(viewAction: .createRoom) + try await deferred.fulfill() + + // Then the room should be created and a topic should not be set. + XCTAssertTrue(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartCalled) + XCTAssertEqual(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.name, "A") + XCTAssertNil(clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReceivedArguments?.topic, + "The topic should be sent as nil when it is empty.") + } + + func testCreateSpace() async throws { + clientProxy = ClientProxyMock(.init(userIDServerName: "matrix.org", + userID: "@a:b.com", + spaceServiceConfiguration: .init(spaceRoomLists: ["1": .init()]))) + clientProxy.roomForIdentifierClosure = { roomID in .joined(JoinedRoomProxyMock(.init(id: roomID))) } + userSession = UserSessionMock(.init(clientProxy: clientProxy)) + ServiceLocator.shared.settings.knockingEnabled = true + let viewModel = CreateRoomScreenViewModel(isSpace: true, + shouldShowCancelButton: false, + userSession: userSession, + analytics: ServiceLocator.shared.analytics, + userIndicatorController: UserIndicatorControllerMock(), + appSettings: ServiceLocator.shared.settings) + self.viewModel = viewModel + + // Given a form with a blank topic. + context.send(viewAction: .updateRoomName("A")) + context.roomTopic = "" + context.selectedAccessType = .private + XCTAssertTrue(context.viewState.canCreateRoom) + + // When creating the room. + clientProxy.createRoomNameTopicAccessTypeIsSpaceUserIDsAvatarURLAliasLocalPartReturnValue = .success("1") + let deferred = deferFulfillment(viewModel.actions) { action in + guard case .createdRoom(let roomProxy, let spaceRoomListProxy) = action, + spaceRoomListProxy != nil, + roomProxy.id == "1" else { return false } return true } context.send(viewAction: .createRoom)