[iOS] Create public space #143

- Update after design review
This commit is contained in:
Gil Eluard 2021-12-09 09:04:21 +01:00
parent fcba28e9c1
commit 9c29b62075
16 changed files with 29 additions and 21 deletions

View file

@ -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 youll have?";
"spaces_creation_new_rooms_message" = "Well create a room for each one.";

View file

@ -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 youre 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 theyre 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")

View file

@ -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))

View file

@ -57,7 +57,6 @@ struct ThemableNavigationBar: View {
.foregroundColor(theme.colors.secondaryContent)
}
}
.padding(.top, 25)
.padding(.horizontal)
.frame(height: 44)
.background(theme.colors.background)

View file

@ -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)

View file

@ -39,6 +39,8 @@ class SpaceCreationEmailInvitesUITests: MockScreenTest {
verifyEmailValues()
case .emailValidationFailed:
verifyEmailValues()
case .loading:
verifyEmailValues()
}
}

View file

@ -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
}

View file

@ -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

View file

@ -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)

View file

@ -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)
}

View file

@ -17,6 +17,7 @@
//
import Foundation
import UIKit
struct SpaceCreationPostProcessViewState: BindableState {
var avatar: AvatarInput

View file

@ -18,6 +18,7 @@
import Foundation
import Combine
import UIKit
@available(iOS 14.0, *)
class MockSpaceCreationPostProcessService: SpaceCreationPostProcessServiceProtocol {

View file

@ -18,6 +18,7 @@
import Foundation
import Combine
import UIKit
@available(iOS 14.0, *)
protocol SpaceCreationPostProcessServiceProtocol: AnyObject {

View file

@ -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)
}

View file

@ -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)

View file

@ -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))
}
}