Merge branch 'gil/143_create_public_space' into gil/5224_space_creation

This commit is contained in:
Gil Eluard
2021-12-16 09:56:28 +01:00
9 changed files with 60 additions and 33 deletions
@@ -25,7 +25,13 @@ enum MockAppScreens {
MockTemplateRoomChatScreenState.self, MockTemplateRoomChatScreenState.self,
MockUserSuggestionScreenState.self, MockUserSuggestionScreenState.self,
MockPollEditFormScreenState.self, MockPollEditFormScreenState.self,
MockPollTimelineScreenState.self MockPollTimelineScreenState.self,
MockSpaceCreationEmailInvitesScreenState.self,
MockSpaceCreationMatrixItemChooserScreenState.self,
MockSpaceCreationMenuScreenState.self,
MockSpaceCreationRoomsScreenState.self,
MockSpaceCreationSettingsScreenState.self,
MockSpaceCreationPostProcessScreenState.self,
] ]
} }
@@ -89,6 +89,7 @@ class SpaceCreationEmailInvitesViewModel: SpaceCreationEmailInvitesViewModelType
private func done() { private func done() {
self.creationParameters.emailInvites = self.context.emailInvites self.creationParameters.emailInvites = self.context.emailInvites
self.creationParameters.inviteType = .email
let emailAddressesValidity = service.validate(self.context.emailInvites) let emailAddressesValidity = service.validate(self.context.emailInvites)
dispatch(action: .updateEmailValidity(emailAddressesValidity)) dispatch(action: .updateEmailValidity(emailAddressesValidity))
@@ -84,6 +84,7 @@ class SpaceCreationMatrixItemChooserViewModel: SpaceCreationMatrixItemChooserVie
let selectedItemIds = Array(spaceCreationMatrixItemChooserService.selectedItemIdsSubject.value) let selectedItemIds = Array(spaceCreationMatrixItemChooserService.selectedItemIdsSubject.value)
switch spaceCreationMatrixItemChooserService.type { switch spaceCreationMatrixItemChooserService.type {
case .people: case .people:
creationParams.inviteType = .userId
creationParams.userIdInvites = selectedItemIds creationParams.userIdInvites = selectedItemIds
default: default:
creationParams.addedRoomIds = selectedItemIds creationParams.addedRoomIds = selectedItemIds
@@ -17,6 +17,11 @@
import Foundation import Foundation
import UIKit import UIKit
enum SpaceCreationInviteType {
case email
case userId
}
class SpaceCreationParameters { class SpaceCreationParameters {
var name: String? { var name: String? {
didSet { didSet {
@@ -89,6 +94,11 @@ class SpaceCreationParameters {
isModified = true isModified = true
} }
} }
var inviteType: SpaceCreationInviteType = .email {
didSet {
isModified = true
}
}
private(set) var isModified: Bool = false private(set) var isModified: Bool = false
} }
@@ -114,7 +114,7 @@ class SpaceCreationPostProcessService: SpaceCreationPostProcessServiceProtocol {
})) }))
} }
if creationParams.userIdInvites.isEmpty { if creationParams.inviteType == .email {
let emailInviteCount = creationParams.userDefinedEmailInvites.count let emailInviteCount = creationParams.userDefinedEmailInvites.count
if emailInviteCount > 0 { if emailInviteCount > 0 {
let subTasks = creationParams.userDefinedEmailInvites.map { emailAddress in let subTasks = creationParams.userDefinedEmailInvites.map { emailAddress in
@@ -170,7 +170,8 @@ class SpaceCreationPostProcessService: SpaceCreationPostProcessServiceProtocol {
if let userDefinedAlias = creationParams.userDefinedAddress, !userDefinedAlias.isEmpty { if let userDefinedAlias = creationParams.userDefinedAddress, !userDefinedAlias.isEmpty {
alias = userDefinedAlias alias = userDefinedAlias
} }
session.spaceService.createSpace(withName: creationParams.name, topic: creationParams.topic, isPublic: creationParams.isPublic, aliasLocalPart: alias, inviteArray: creationParams.userIdInvites) { [weak self] response in let userIdInvites = creationParams.inviteType == .userId ? creationParams.userIdInvites : []
session.spaceService.createSpace(withName: creationParams.name, topic: creationParams.topic, isPublic: creationParams.isPublic, aliasLocalPart: alias, inviteArray: userIdInvites) { [weak self] response in
guard let self = self else { return } guard let self = self else { return }
if response.isFailure { if response.isFailure {
self.updateCurrentTask(with: .failure) self.updateCurrentTask(with: .failure)
@@ -32,10 +32,6 @@ class SpaceCreationPostProcessUITests: MockScreenTest {
func verifySpaceCreationPostProcessScreen() throws { func verifySpaceCreationPostProcessScreen() throws {
guard let screenState = screenState as? MockSpaceCreationPostProcessScreenState else { fatalError("no screen") } guard let screenState = screenState as? MockSpaceCreationPostProcessScreenState else { fatalError("no screen") }
switch screenState {
case .tasks:
verifyTasksList()
}
} }
func verifyTasksList() { func verifyTasksList() {
@@ -41,19 +41,15 @@ class SpaceCreationPostProcessViewModelTests: XCTestCase {
} }
func testUpateToNextTask() { func testUpateToNextTask() {
let tasksPublisher = context.$viewState.map(\.tasks).removeDuplicates()
let awaitDeferred = xcAwaitDeferred(tasksPublisher)
service.simulateUpdate(tasks: MockSpaceCreationPostProcessService.nextStepTasks) service.simulateUpdate(tasks: MockSpaceCreationPostProcessService.nextStepTasks)
XCTAssertEqual(try awaitDeferred(), MockSpaceCreationPostProcessService.nextStepTasks) XCTAssertEqual(context.viewState.tasks, MockSpaceCreationPostProcessService.nextStepTasks)
XCTAssertEqual(context.viewState.errorCount, 2) XCTAssertEqual(context.viewState.errorCount, 2)
XCTAssertEqual(context.viewState.isFinished, false) XCTAssertEqual(context.viewState.isFinished, false)
} }
func testLastTaskDone() { func testLastTaskDone() {
let tasksPublisher = context.$viewState.map(\.tasks).removeDuplicates()
let awaitDeferred = xcAwaitDeferred(tasksPublisher)
service.simulateUpdate(tasks: MockSpaceCreationPostProcessService.lastTaskDoneWithError) service.simulateUpdate(tasks: MockSpaceCreationPostProcessService.lastTaskDoneWithError)
XCTAssertEqual(try awaitDeferred(), MockSpaceCreationPostProcessService.lastTaskDoneWithError) XCTAssertEqual(context.viewState.tasks, MockSpaceCreationPostProcessService.lastTaskDoneWithError)
XCTAssertEqual(context.viewState.errorCount, 2) XCTAssertEqual(context.viewState.errorCount, 2)
XCTAssertEqual(context.viewState.isFinished, true) XCTAssertEqual(context.viewState.isFinished, true)
} }
@@ -45,8 +45,8 @@ class SpaceCreationSettingsViewModelTests: XCTestCase {
func testInitialState() { func testInitialState() {
XCTAssertEqual(context.viewState.title, creationParameters.isPublic ? VectorL10n.spacesCreationPublicSpaceTitle : VectorL10n.spacesCreationPrivateSpaceTitle) XCTAssertEqual(context.viewState.title, creationParameters.isPublic ? VectorL10n.spacesCreationPublicSpaceTitle : VectorL10n.spacesCreationPrivateSpaceTitle)
XCTAssertEqual(context.viewState.isAddressValid, true) XCTAssertEqual(context.viewState.isAddressValid, true)
XCTAssertEqual(context.viewState.defaultAddress, "#fake:matrix.org") XCTAssertEqual(context.viewState.defaultAddress, "fake-uri")
XCTAssertEqual(context.viewState.addressMessage, VectorL10n.spacesCreationAddressDefaultMessage("#fake:matrix.org")) XCTAssertEqual(context.viewState.addressMessage, VectorL10n.spacesCreationAddressDefaultMessage("#fake-uri:fake-domain.org"))
XCTAssertEqual(context.viewState.avatarImage, Asset.Images.appSymbol.image) XCTAssertEqual(context.viewState.avatarImage, Asset.Images.appSymbol.image)
XCTAssertEqual(context.roomName, creationParameters.name) XCTAssertEqual(context.roomName, creationParameters.name)
XCTAssertEqual(context.topic, creationParameters.topic) XCTAssertEqual(context.topic, creationParameters.topic)
@@ -50,26 +50,41 @@ struct SpaceCreationSettings: View {
@ViewBuilder @ViewBuilder
private var mainView: some View { private var mainView: some View {
ZStack(alignment: .center) { GeometryReader { geometryReader in
GeometryReader { geometryReader in ZStack(alignment: .center) {
ScrollView(.vertical, showsIndicators: false) { VStack(alignment: .center) {
VStack(alignment: .center) { if geometryReader.size.height > 650 {
VStack(alignment: .center) { Spacer().frame(height: 10)
headerView
Spacer()
avatarView
Spacer()
}
.background(theme.colors.background)
Spacer().frame(height:370)
} }
.frame(minWidth: geometryReader.size.width, minHeight: geometryReader.size.height - 2) headerView
if !viewModel.viewState.showRoomAddress {
Spacer().frame(height: geometryReader.size.height / 20)
} else {
Spacer().frame(height: geometryReader.size.height / 30)
}
avatarView
Spacer()
}
.background(theme.colors.background)
VStack(alignment: .center) {
if viewModel.viewState.showRoomAddress && geometryReader.size.height > 650 {
Spacer()
}
Spacer()
formView
if !viewModel.viewState.showRoomAddress {
if geometryReader.size.height > 650 {
Spacer().frame(height:geometryReader.size.height / 4)
} else {
Spacer().frame(height:geometryReader.size.height / 4)
}
} else {
if geometryReader.size.height > 650 {
Spacer().frame(height:geometryReader.size.height / 10)
}
}
footerView
} }
}
VStack(alignment: .center) {
Spacer()
formView
footerView
} }
} }
.padding(EdgeInsets(top: 0, leading: 16, bottom: 24, trailing: 16)) .padding(EdgeInsets(top: 0, leading: 16, bottom: 24, trailing: 16))
@@ -98,6 +113,7 @@ struct SpaceCreationSettings: View {
} }
}.padding(10) }.padding(10)
.gesture(TapGesture().onEnded { _ in .gesture(TapGesture().onEnded { _ in
ResponderManager.resignFirstResponder()
viewModel.send(viewAction: .pickImage(reader.frame(in: .global))) viewModel.send(viewAction: .pickImage(reader.frame(in: .global)))
}) })
} }