workspaces/cogito-ios-app/Cogito/Create identity/CreateIdentityViewController.swift
import UIKit
import ReSwift
import ReRxSwift
class CreateIdentityViewController: UIViewController, UITextFieldDelegate, Connectable {
@IBOutlet weak var descriptionField: UITextField!
@IBOutlet weak var createButton: UIButton!
@IBOutlet weak var closeButton: UIButton?
@IBOutlet weak var activityView: UIActivityIndicatorView!
@IBInspectable var showCloseButton: Bool = false {
didSet {
closeButton?.isHidden = !showCloseButton
}
}
var onDone: () -> Void = {}
override func viewDidLoad() {
super.viewDidLoad()
self.descriptionField.delegate = self
connection.bind(\Props.description, to: descriptionField.rx.text)
connection.bind(\Props.createButtonEnabled, to: createButton.rx.isEnabled)
connection.bind(\Props.pending, to: descriptionField.rx.isEnabled) { !$0 }
connection.bind(\Props.pending, to: activityView.rx.isHidden) { !$0 }
connection.bind(\Props.pending, to: createButton.rx.title()) {
$0 ? "Creating" : "Create"
}
connection.subscribe(\Props.fulfilled) { [unowned self] fulfilled in
if fulfilled {
self.onDone()
}
}
handleErrors()
}
private func handleErrors() {
connection.subscribe(\Props.error) { [unowned self] maybeError in
if let error = maybeError {
print("[error] createIdentity error: \(error)")
let alert = UIAlertController(
title: "Failed to create identity",
message: "Please make sure you have a passcode set on your device, and retry.",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: .cancel))
self.present(alert, animated: true)
}
}
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
closeButton?.isHidden = !showCloseButton
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
closeButton?.isHidden = !showCloseButton
connection.connect()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
connection.disconnect()
}
@IBAction func editingChanged() {
actions.setDescription(descriptionField.text ?? "")
}
@IBAction func editingDidEnd() {
actions.setDescription(descriptionField.text ?? "")
}
@IBAction func createTapped() {
descriptionField.resignFirstResponder()
self.actions.createIdentity()
}
@IBAction func cancelTapped() {
onDone()
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
struct Props {
let description: String
let pending: Bool
let fulfilled: Bool
let error: String?
let createButtonEnabled: Bool
}
struct Actions {
let setDescription: (String) -> Void
let createIdentity: () -> Void
}
let connection = Connection(store: appStore,
mapStateToProps: mapStateToProps,
mapDispatchToActions: mapDispatchToActions)
}
private func mapStateToProps(state: AppState) -> CreateIdentityViewController.Props {
return CreateIdentityViewController.Props(
description: state.createIdentity.description,
pending: state.createIdentity.pending,
fulfilled: state.createIdentity.newAddress != nil,
error: state.createIdentity.error,
createButtonEnabled:
state.createIdentity.description != "" &&
!state.createIdentity.pending
)
}
private func mapDispatchToActions(dispatch: @escaping DispatchFunction) -> CreateIdentityViewController.Actions {
return CreateIdentityViewController.Actions(
setDescription: { desc in dispatch(CreateIdentityActions.SetDescription(description: desc)) },
createIdentity: { dispatch(CreateIdentityActions.CreateIdentity()) }
)
}