-
Dariusz Rybicki authoredDariusz Rybicki authored
MyContactView.swift 7.95 KiB
import ComposableArchitecture
import SwiftUI
import XXModels
public struct MyContactView: View {
public init(store: Store<MyContactState, MyContactAction>) {
self.store = store
}
let store: Store<MyContactState, MyContactAction>
@FocusState var focusedField: MyContactState.Field?
struct ViewState: Equatable {
init(state: MyContactState) {
contact = state.contact
focusedField = state.focusedField
email = state.email
emailConfirmation = state.emailConfirmationID != nil
emailCode = state.emailConfirmationCode
isRegisteringEmail = state.isRegisteringEmail
isConfirmingEmail = state.isConfirmingEmail
isUnregisteringEmail = state.isUnregisteringEmail
phone = state.phone
phoneConfirmation = state.phoneConfirmationID != nil
phoneCode = state.phoneConfirmationCode
isRegisteringPhone = state.isRegisteringPhone
isConfirmingPhone = state.isConfirmingPhone
isUnregisteringPhone = state.isUnregisteringPhone
isLoadingFacts = state.isLoadingFacts
}
var contact: XXModels.Contact?
var focusedField: MyContactState.Field?
var email: String
var emailConfirmation: Bool
var emailCode: String
var isRegisteringEmail: Bool
var isConfirmingEmail: Bool
var isUnregisteringEmail: Bool
var phone: String
var phoneConfirmation: Bool
var phoneCode: String
var isRegisteringPhone: Bool
var isConfirmingPhone: Bool
var isUnregisteringPhone: Bool
var isLoadingFacts: Bool
}
public var body: some View {
WithViewStore(store, observe: ViewState.init) { viewStore in
Form {
Section {
Text(viewStore.contact?.username ?? "")
} header: {
Label("Username", systemImage: "person")
}
Section {
if let contact = viewStore.contact {
if let email = contact.email {
Text(email)
Button(role: .destructive) {
viewStore.send(.unregisterEmailTapped)
} label: {
HStack {
Text("Unregister")
Spacer()
if viewStore.isUnregisteringEmail {
ProgressView()
}
}
}
.disabled(viewStore.isUnregisteringEmail)
} else {
TextField(
text: viewStore.binding(
get: \.email,
send: { MyContactAction.set(\.$email, $0) }
),
prompt: Text("Enter email"),
label: { Text("Email") }
)
.focused($focusedField, equals: .email)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.disabled(viewStore.isRegisteringEmail || viewStore.emailConfirmation)
if viewStore.emailConfirmation {
TextField(
text: viewStore.binding(
get: \.emailCode,
send: { MyContactAction.set(\.$emailConfirmationCode, $0) }
),
prompt: Text("Enter confirmation code"),
label: { Text("Confirmation code") }
)
.focused($focusedField, equals: .emailCode)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.disabled(viewStore.isConfirmingEmail)
Button {
viewStore.send(.confirmEmailTapped)
} label: {
HStack {
Text("Confirm")
Spacer()
if viewStore.isConfirmingEmail {
ProgressView()
}
}
}
.disabled(viewStore.isConfirmingEmail)
} else {
Button {
viewStore.send(.registerEmailTapped)
} label: {
HStack {
Text("Register")
Spacer()
if viewStore.isRegisteringEmail {
ProgressView()
}
}
}
.disabled(viewStore.isRegisteringEmail)
}
}
} else {
Text("")
}
} header: {
Label("Email", systemImage: "envelope")
}
Section {
if let contact = viewStore.contact {
if let phone = contact.phone {
Text(phone)
Button(role: .destructive) {
viewStore.send(.unregisterPhoneTapped)
} label: {
HStack {
Text("Unregister")
Spacer()
if viewStore.isUnregisteringPhone {
ProgressView()
}
}
}
.disabled(viewStore.isUnregisteringPhone)
} else {
TextField(
text: viewStore.binding(
get: \.phone,
send: { MyContactAction.set(\.$phone, $0) }
),
prompt: Text("Enter phone"),
label: { Text("Phone") }
)
.focused($focusedField, equals: .phone)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.disabled(viewStore.isRegisteringPhone || viewStore.phoneConfirmation)
if viewStore.phoneConfirmation {
TextField(
text: viewStore.binding(
get: \.phoneCode,
send: { MyContactAction.set(\.$phoneConfirmationCode, $0) }
),
prompt: Text("Enter confirmation code"),
label: { Text("Confirmation code") }
)
.focused($focusedField, equals: .phoneCode)
.textInputAutocapitalization(.never)
.disableAutocorrection(true)
.disabled(viewStore.isConfirmingPhone)
Button {
viewStore.send(.confirmPhoneTapped)
} label: {
HStack {
Text("Confirm")
Spacer()
if viewStore.isConfirmingPhone {
ProgressView()
}
}
}
.disabled(viewStore.isConfirmingPhone)
} else {
Button {
viewStore.send(.registerPhoneTapped)
} label: {
HStack {
Text("Register")
Spacer()
if viewStore.isRegisteringPhone {
ProgressView()
}
}
}
.disabled(viewStore.isRegisteringPhone)
}
}
} else {
Text("")
}
} header: {
Label("Phone", systemImage: "phone")
}
Section {
Button {
viewStore.send(.loadFactsTapped)
} label: {
HStack {
Text("Reload facts")
Spacer()
if viewStore.isLoadingFacts {
ProgressView()
}
}
}
.disabled(viewStore.isLoadingFacts)
} header: {
Text("Actions")
}
}
.navigationTitle("My Contact")
.task { viewStore.send(.start) }
.onChange(of: viewStore.focusedField) { focusedField = $0 }
.onChange(of: focusedField) { viewStore.send(.set(\.$focusedField, $0)) }
.alert(store.scope(state: \.alert), dismiss: .alertDismissed)
}
}
}
#if DEBUG
public struct MyContactView_Previews: PreviewProvider {
public static var previews: some View {
NavigationView {
MyContactView(store: Store(
initialState: MyContactState(),
reducer: .empty,
environment: ()
))
}
}
}
#endif