From 9c29b62075bbb562d5db34d5f879b0bc290525ad Mon Sep 17 00:00:00 2001 From: Gil Eluard Date: Thu, 9 Dec 2021 09:04:21 +0100 Subject: [PATCH] [iOS] Create public space #143 - Update after design review --- Riot/Assets/en.lproj/Vector.strings | 5 +++-- Riot/Generated/Strings.swift | 8 ++++++-- .../Modules/Common/Util/RoundedBorderTextField.swift | 2 +- .../Modules/Common/Util/ThemableNavigationBar.swift | 1 - .../Coordinator/SpaceCreationCoordinator.swift | 4 ++-- .../Test/UI/SpaceCreationEmailInvitesUITests.swift | 2 ++ .../SpaceCreationEmailInvitesViewModelTests.swift | 2 +- .../View/SpaceCreationEmailInvites.swift | 3 +-- .../View/SpaceCreationMatrixItemChooserListRow.swift | 2 +- .../SpaceCreationMenu/View/SpaceCreationMenu.swift | 2 +- .../Model/SpaceCreationPostProcessViewState.swift | 1 + .../Mock/MockSpaceCreationPostProcessService.swift | 1 + .../SpaceCreationPostProcessServiceProtocol.swift | 1 + .../SpaceCreationPostProcessViewModelTests.swift | 12 ++++++------ .../View/SpaceCreationPostProcess.swift | 2 +- .../SpaceCreationRooms/View/SpaceCreationRooms.swift | 2 +- 16 files changed, 29 insertions(+), 21 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 15ec80e3c..3c0e832cf 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -67,6 +67,7 @@ "done" = "Done"; "private" = "Private"; "public" = "Public"; +"stop" = "Stop"; // Call Bar "callbar_only_single_active" = "Tap to return to the call (%@)"; @@ -1761,8 +1762,8 @@ Tap the + to start adding people."; "spaces_creation_address_already_exists" = "%@\nalready exists"; "spaces_creation_public_space_title" = "Your public space"; "spaces_creation_private_space_title" = "Your private space"; -"spaces_creation_cancel_title" = "Please confirm"; -"spaces_creation_cancel_message" = "You will need to start from scratch next time."; +"spaces_creation_cancel_title" = "Stop creating a space?"; +"spaces_creation_cancel_message" = "Your progress will be lost."; "spaces_creation_new_rooms_title" = "What are some discussions you’ll have?"; "spaces_creation_new_rooms_message" = "We’ll create a room for each one."; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index d85a27c3e..ef2d2a861 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -5039,11 +5039,11 @@ public class VectorL10n: NSObject { public static func spacesCreationAddressInvalidCharacters(_ p1: String) -> String { return VectorL10n.tr("Vector", "spaces_creation_address_invalid_characters", p1) } - /// You will need to start from scratch next time. + /// Your progress will be lost. public static var spacesCreationCancelMessage: String { return VectorL10n.tr("Vector", "spaces_creation_cancel_message") } - /// Please confirm + /// Stop creating a space? public static var spacesCreationCancelTitle: String { return VectorL10n.tr("Vector", "spaces_creation_cancel_title") } @@ -5239,6 +5239,10 @@ public class VectorL10n: NSObject { public static var start: String { return VectorL10n.tr("Vector", "start") } + /// Stop + public static var stop: String { + return VectorL10n.tr("Vector", "stop") + } /// Element is a new type of messenger and collaboration app that:\n\n1. Puts you in control to preserve your privacy\n2. Lets you communicate with anyone in the Matrix network, and even beyond by integrating with apps such as Slack\n3. Protects you from advertising, datamining, backdoors and walled gardens\n4. Secures you through end-to-end encryption, with cross-signing to verify others\n\nElement is completely different from other messaging and collaboration apps because it is decentralised and open source.\n\nElement lets you self-host - or choose a host - so that you have privacy, ownership and control of your data and conversations. It gives you access to an open network; so you’re not just stuck speaking to other Element users only. And it is very secure.\n\nElement is able to do all this because it operates on Matrix - the standard for open, decentralised communication. \n\nElement puts you in control by letting you choose who hosts your conversations. From the Element app, you can choose to host in different ways:\n\n1. Get a free account on the matrix.org public server\n2. Self-host your account by running a server on your own hardware\n3. Sign up for an account on a custom server by simply subscribing to the Element Matrix Services hosting platform\n\nWhy choose Element?\n\nOWN YOUR DATA: You decide where to keep your data and messages. You own it and control it, not some MEGACORP that mines your data or gives access to third parties.\n\nOPEN MESSAGING AND COLLABORATION: You can chat with anyone else in the Matrix network, whether they’re using Element or another Matrix app, and even if they are using a different messaging system of the likes of Slack, IRC or XMPP.\n\nSUPER-SECURE: Real end-to-end encryption (only those in the conversation can decrypt messages), and cross-signing to verify the devices of conversation participants.\n\nCOMPLETE COMMUNICATION: Messaging, voice and video calls, file sharing, screen sharing and a whole bunch of integrations, bots and widgets. Build rooms, communities, stay in touch and get things done.\n\nEVERYWHERE YOU ARE: Stay in touch wherever you are with fully synchronised message history across all your devices and on the web at https://element.io/app. public static var storeFullDescription: String { return VectorL10n.tr("Vector", "store_full_description") diff --git a/RiotSwiftUI/Modules/Common/Util/RoundedBorderTextField.swift b/RiotSwiftUI/Modules/Common/Util/RoundedBorderTextField.swift index 64e38d8c1..6a571ff86 100644 --- a/RiotSwiftUI/Modules/Common/Util/RoundedBorderTextField.swift +++ b/RiotSwiftUI/Modules/Common/Util/RoundedBorderTextField.swift @@ -69,7 +69,7 @@ struct RoundedBorderTextField: View { .frame(height: 30) .modifier(ClearViewModifier(alignment: .center, text: $text)) } - .padding(EdgeInsets(top: 8, leading: 8, bottom: 8, trailing: 0)) + .padding(EdgeInsets(top: 8, leading: 8, bottom: 8, trailing: text.isEmpty ? 8 : 0)) .overlay(RoundedRectangle(cornerRadius: 8) .stroke(editing ? theme.colors.accent : (footerText != nil && isError ? theme.colors.alert : theme.colors.quinaryContent), lineWidth: editing || (footerText != nil && isError) ? 2 : 1)) diff --git a/RiotSwiftUI/Modules/Common/Util/ThemableNavigationBar.swift b/RiotSwiftUI/Modules/Common/Util/ThemableNavigationBar.swift index 0a8b2bd97..010034d18 100644 --- a/RiotSwiftUI/Modules/Common/Util/ThemableNavigationBar.swift +++ b/RiotSwiftUI/Modules/Common/Util/ThemableNavigationBar.swift @@ -57,7 +57,6 @@ struct ThemableNavigationBar: View { .foregroundColor(theme.colors.secondaryContent) } } - .padding(.top, 25) .padding(.horizontal) .frame(height: 44) .background(theme.colors.background) diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/Coordinator/SpaceCreationCoordinator.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/Coordinator/SpaceCreationCoordinator.swift index 4913fab70..f8484c059 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/Coordinator/SpaceCreationCoordinator.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/Coordinator/SpaceCreationCoordinator.swift @@ -257,10 +257,10 @@ final class SpaceCreationCoordinator: Coordinator { private func cancel() { if parameters.creationParameters.isModified { let alert = UIAlertController(title: VectorL10n.spacesCreationCancelTitle, message: VectorL10n.spacesCreationCancelMessage, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: VectorL10n.continue, style: .destructive, handler: { action in + alert.addAction(UIAlertAction(title: VectorL10n.stop, style: .destructive, handler: { action in self.callback?(.cancel) })) - alert.addAction(UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: nil)) + alert.addAction(UIAlertAction(title: VectorL10n.continue, style: .cancel, handler: nil)) navigationRouter.present(alert, animated: true) } else { self.callback?(.cancel) diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/UI/SpaceCreationEmailInvitesUITests.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/UI/SpaceCreationEmailInvitesUITests.swift index fb8b66415..c6f1f8426 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/UI/SpaceCreationEmailInvitesUITests.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/UI/SpaceCreationEmailInvitesUITests.swift @@ -39,6 +39,8 @@ class SpaceCreationEmailInvitesUITests: MockScreenTest { verifyEmailValues() case .emailValidationFailed: verifyEmailValues() + case .loading: + verifyEmailValues() } } diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/Unit/SpaceCreationEmailInvitesViewModelTests.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/Unit/SpaceCreationEmailInvitesViewModelTests.swift index 9676dcae2..8a53ff89a 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/Unit/SpaceCreationEmailInvitesViewModelTests.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/Test/Unit/SpaceCreationEmailInvitesViewModelTests.swift @@ -29,7 +29,7 @@ class SpaceCreationEmailInvitesViewModelTests: XCTestCase { var context: SpaceCreationEmailInvitesViewModelType.Context! override func setUpWithError() throws { - service = MockSpaceCreationEmailInvitesService(defaultValidation: true) + service = MockSpaceCreationEmailInvitesService(defaultValidation: true, isLoading: false) viewModel = SpaceCreationEmailInvitesViewModel(creationParameters: creationParameters, service: service) context = viewModel.context } diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/View/SpaceCreationEmailInvites.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/View/SpaceCreationEmailInvites.swift index 0f104a480..b8e36720c 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/View/SpaceCreationEmailInvites.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationEmailInvites/View/SpaceCreationEmailInvites.swift @@ -40,7 +40,6 @@ struct SpaceCreationEmailInvites: View { viewModel.send(viewAction: .cancel) } mainView - .frame(width: .infinity, height: .infinity) .animation(.easeInOut(duration: 0.2), value: viewModel.viewState.loading) .modifier(WaitOverlay(isLoading: .constant(viewModel.viewState.loading))) } @@ -65,7 +64,7 @@ struct SpaceCreationEmailInvites: View { } footerView } - .padding(EdgeInsets(top: 24, leading: 16, bottom: 24, trailing: 16)) + .padding(EdgeInsets(top: 0, leading: 16, bottom: 24, trailing: 16)) } @ViewBuilder diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMatrixItemChooser/View/SpaceCreationMatrixItemChooserListRow.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMatrixItemChooser/View/SpaceCreationMatrixItemChooserListRow.swift index 9d70139e6..0144fce20 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMatrixItemChooser/View/SpaceCreationMatrixItemChooserListRow.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMatrixItemChooser/View/SpaceCreationMatrixItemChooserListRow.swift @@ -55,7 +55,7 @@ struct SpaceCreationMatrixItemChooserListRow: View { Image(systemName: "circle").renderingMode(.template).foregroundColor(theme.colors.tertiaryContent) } } - //add to a style + .contentShape(Rectangle()) .padding(.horizontal) .padding(.vertical, 12) .frame(maxWidth: .infinity) diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/View/SpaceCreationMenu.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/View/SpaceCreationMenu.swift index 164cbbaa6..68bc776c7 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/View/SpaceCreationMenu.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationMenu/View/SpaceCreationMenu.swift @@ -57,7 +57,7 @@ struct SpaceCreationMenu: View { .frame(minHeight: reader.size.height - 2) } } - .padding(EdgeInsets(top: 24, leading: 16, bottom: 24, trailing: 16)) + .padding(EdgeInsets(top: 0, leading: 16, bottom: 24, trailing: 16)) } .background(theme.colors.background) } diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Model/SpaceCreationPostProcessViewState.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Model/SpaceCreationPostProcessViewState.swift index 22ce4f952..311b2fcba 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Model/SpaceCreationPostProcessViewState.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Model/SpaceCreationPostProcessViewState.swift @@ -17,6 +17,7 @@ // import Foundation +import UIKit struct SpaceCreationPostProcessViewState: BindableState { var avatar: AvatarInput diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/Mock/MockSpaceCreationPostProcessService.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/Mock/MockSpaceCreationPostProcessService.swift index a2c034f2a..949ff78ea 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/Mock/MockSpaceCreationPostProcessService.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/Mock/MockSpaceCreationPostProcessService.swift @@ -18,6 +18,7 @@ import Foundation import Combine +import UIKit @available(iOS 14.0, *) class MockSpaceCreationPostProcessService: SpaceCreationPostProcessServiceProtocol { diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/SpaceCreationPostProcessServiceProtocol.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/SpaceCreationPostProcessServiceProtocol.swift index 6f3f38705..49c81d3d8 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/SpaceCreationPostProcessServiceProtocol.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Service/SpaceCreationPostProcessServiceProtocol.swift @@ -18,6 +18,7 @@ import Foundation import Combine +import UIKit @available(iOS 14.0, *) protocol SpaceCreationPostProcessServiceProtocol: AnyObject { diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Test/Unit/SpaceCreationPostProcessViewModelTests.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Test/Unit/SpaceCreationPostProcessViewModelTests.swift index e5eb02e26..16e9dc6f7 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Test/Unit/SpaceCreationPostProcessViewModelTests.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/Test/Unit/SpaceCreationPostProcessViewModelTests.swift @@ -29,13 +29,13 @@ class SpaceCreationPostProcessViewModelTests: XCTestCase { var context: SpaceCreationPostProcessViewModelType.Context! override func setUpWithError() throws { - service = MockSpaceCreationPostProcessService(tasks: Constant.defaultTasks) + service = MockSpaceCreationPostProcessService(tasks: MockSpaceCreationPostProcessService.defaultTasks) viewModel = SpaceCreationPostProcessViewModel.makeSpaceCreationPostProcessViewModel(spaceCreationPostProcessService: service) context = viewModel.context } func testInitialState() { - XCTAssertEqual(context.viewState.tasks, Constant.defaultTasks) + XCTAssertEqual(context.viewState.tasks, MockSpaceCreationPostProcessService.defaultTasks) XCTAssertEqual(context.viewState.errorCount, 1) XCTAssertEqual(context.viewState.isFinished, false) } @@ -43,8 +43,8 @@ class SpaceCreationPostProcessViewModelTests: XCTestCase { func testUpateToNextTask() { let tasksPublisher = context.$viewState.map(\.tasks).removeDuplicates() let awaitDeferred = xcAwaitDeferred(tasksPublisher) - service.simulateUpdate(tasks: Constant.nextStepTasks) - XCTAssertEqual(try awaitDeferred(), Constant.nextStepTasks) + service.simulateUpdate(tasks: MockSpaceCreationPostProcessService.nextStepTasks) + XCTAssertEqual(try awaitDeferred(), MockSpaceCreationPostProcessService.nextStepTasks) XCTAssertEqual(context.viewState.errorCount, 2) XCTAssertEqual(context.viewState.isFinished, false) } @@ -52,8 +52,8 @@ class SpaceCreationPostProcessViewModelTests: XCTestCase { func testLastTaskDone() { let tasksPublisher = context.$viewState.map(\.tasks).removeDuplicates() let awaitDeferred = xcAwaitDeferred(tasksPublisher) - service.simulateUpdate(tasks: Constant.lastTaskDone) - XCTAssertEqual(try awaitDeferred(), Constant.lastTaskDone) + service.simulateUpdate(tasks: MockSpaceCreationPostProcessService.lastTaskDoneWithError) + XCTAssertEqual(try awaitDeferred(), MockSpaceCreationPostProcessService.lastTaskDoneWithError) XCTAssertEqual(context.viewState.errorCount, 2) XCTAssertEqual(context.viewState.isFinished, true) } diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/View/SpaceCreationPostProcess.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/View/SpaceCreationPostProcess.swift index 797b31b0e..37b8d47d4 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/View/SpaceCreationPostProcess.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationPostProcess/View/SpaceCreationPostProcess.swift @@ -41,7 +41,7 @@ struct SpaceCreationPostProcess: View { buttonsPanel } .animation(.easeIn(duration: 0.2), value: viewModel.viewState.errorCount) - .padding(EdgeInsets(top: 24, leading: 16, bottom: 24, trailing: 16)) + .padding(EdgeInsets(top: 0, leading: 16, bottom: 24, trailing: 16)) .navigationBarHidden(true) .background(theme.colors.background) .frame(maxHeight: .infinity) diff --git a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/View/SpaceCreationRooms.swift b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/View/SpaceCreationRooms.swift index 2fb0eed8f..0a7a1f670 100644 --- a/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/View/SpaceCreationRooms.swift +++ b/RiotSwiftUI/Modules/Spaces/SpaceCreation/SpaceCreationRooms/View/SpaceCreationRooms.swift @@ -83,7 +83,7 @@ struct SpaceCreationRooms: View { viewModel.send(viewAction: .done) } } - .padding(EdgeInsets(top: 24, leading: 16, bottom: 24, trailing: 16)) + .padding(EdgeInsets(top: 0, leading: 16, bottom: 24, trailing: 16)) } }