123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- //
- // CredentialsController.swift
- // deltachat-ios
- //
- // Created by Jonas Reinsch on 15.11.17.
- // Copyright © 2017 Jonas Reinsch. All rights reserved.
- //
- import UIKit
- // valid security modes for IMAP and SMTP
- enum SecurityMode: String, CaseIterable {
- case automatic = "Automatic"
- case ssltls = "SSL/TLS"
- case starttls = "STARTTLS"
- case off = "Off"
- }
- typealias CredentialsModel = (
- email: String,
- password: String,
- imapLoginName: String?,
- imapServer: String?,
- imapPort: String?,
- imapSecurity: SecurityMode,
- smtpLoginName: String?,
- smtpPassword: String?,
- smtpServer: String?,
- smtpPort: String?,
- smtpSecurity: SecurityMode
- )
- class CredentialsController: UITableViewController {
- let emailCell = TextFieldCell.makeEmailCell()
- let passwordCell = TextFieldCell.makePasswordCell()
- let imapCellLoginName = TextFieldCell.makeConfigCell(label: "IMAP Login Name", placeholder: "Automatic")
- let imapCellServer = TextFieldCell.makeConfigCell(label: "IMAP Server", placeholder: "Automatic")
- let imapCellPort = TextFieldCell.makeConfigCell(label: "IMAP Port", placeholder: "Automatic")
- let imapCellSecurity = UITableViewCell(style: UITableViewCell.CellStyle.value1, reuseIdentifier: nil)
- let smtpCellLoginName = TextFieldCell.makeConfigCell(label: "SMTP Login Name", placeholder: "Automatic")
- let smtpCellPassword = TextFieldCell.makeConfigCell(label: "SMTP Password", placeholder: "As above")
- let smtpCellServer = TextFieldCell.makeConfigCell(label: "SMTP Server", placeholder: "Automatic")
- let smtpCellPort = TextFieldCell.makeConfigCell(label: "SMTP Port", placeholder: "Automatic")
- let smtpCellSecurity = UITableViewCell(style: UITableViewCell.CellStyle.value1, reuseIdentifier: nil)
- var doneButton: UIBarButtonItem?
- var advancedButton: UIBarButtonItem?
- let progressBar = UIProgressView(progressViewStyle: .default)
- func readyForLogin() -> Bool {
- return Utils.isValid(model.email) && !model.password.isEmpty
- }
- var advancedMode = false {
- didSet {
- if advancedMode {
- advancedButton?.title = "Standard"
- } else {
- advancedButton?.title = "Advanced"
- }
- tableView.reloadData()
- }
- }
- var model: CredentialsModel = ("", "", nil, nil, nil, SecurityMode.automatic, nil, nil, nil, nil, SecurityMode.automatic) {
- didSet {
- if readyForLogin() {
- doneButton?.isEnabled = true
- } else {
- doneButton?.isEnabled = false
- }
- smtpCellSecurity.detailTextLabel?.text = model.smtpSecurity.rawValue
- imapCellSecurity.detailTextLabel?.text = model.imapSecurity.rawValue
- logger.info("model: \(model)")
- }
- }
- let cells: [UITableViewCell]
- let isCancellable: Bool
- init(isCancellable: Bool = false) {
- cells = [emailCell, passwordCell]
- self.isCancellable = isCancellable
- super.init(style: .grouped)
- doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(didPressSaveAccountButton))
- doneButton?.isEnabled = false
- advancedButton = UIBarButtonItem(title: "Advanced", style: .done, target: self, action: #selector(didPressAdvancedButton))
- let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(didPressCancelButton))
- if isCancellable {
- navigationItem.rightBarButtonItems = [doneButton!, cancelButton]
- } else {
- navigationItem.rightBarButtonItem = doneButton
- }
- navigationItem.leftBarButtonItem = advancedButton
- // FIXME: refactor: do not use target/action here for text field changes
- // but text field delegate
- emailCell.textField.addTarget(self, action: #selector(emailTextChanged), for: UIControl.Event.editingChanged)
- passwordCell.textField.addTarget(self, action: #selector(passwordTextChanged), for: UIControl.Event.editingChanged)
- imapCellLoginName.textField.addTarget(self, action: #selector(imapLoginNameChanged), for: .editingChanged)
- imapCellServer.textField.addTarget(self, action: #selector(imapServerChanged), for: .editingChanged)
- imapCellPort.textField.addTarget(self, action: #selector(imapPortChanged), for: .editingChanged)
- smtpCellLoginName.textField.addTarget(self, action: #selector(smtpLoginNamedChanged), for: .editingChanged)
- smtpCellPassword.textField.addTarget(self, action: #selector(smtpPasswordChanged), for: .editingChanged)
- smtpCellServer.textField.addTarget(self, action: #selector(smtpServerChanged), for: .editingChanged)
- smtpCellPort.textField.addTarget(self, action: #selector(smtpPortChanged), for: .editingChanged)
- emailCell.textField.textContentType = UITextContentType.emailAddress
- emailCell.textField.delegate = self
- passwordCell.textField.delegate = self
- emailCell.textField.returnKeyType = .next
- passwordCell.textField.returnKeyType = .done
- }
- override func viewDidAppear(_: Bool) {
- emailCell.textField.becomeFirstResponder()
- }
- @objc func didPressCancelButton() {
- dismiss(animated: false) {
- AppDelegate.appCoordinator.setupInnerViewControllers()
- }
- }
- @objc func didPressSaveAccountButton() {
- let m = model
- let a = advancedMode
- dismiss(animated: true) {
- initCore(withCredentials: true, advancedMode: a, model: m, cancellableCredentialsUponFailure: self.isCancellable)
- }
- }
- @objc func didPressAdvancedButton() {
- advancedMode = !advancedMode
- }
- required init?(coder _: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- title = "Settings"
- navigationController?.navigationBar.prefersLargeTitles = true
- }
- override func numberOfSections(in _: UITableView) -> Int {
- return advancedMode ? 3 : 1
- }
- override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
- if section == 0 {
- return cells.count
- }
- if section == 1 {
- return 4
- }
- if section == 2 {
- return 5
- }
- return 0 // should never happen
- }
- override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
- if section == 1 {
- return "IMAP"
- }
- if section == 2 {
- return "SMTP"
- }
- return nil
- }
- override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
- let isIMAP = indexPath.section == 1
- let isSMTP = indexPath.section == 2
- if (isIMAP && (indexPath.row == 3)) || (isSMTP && (indexPath.row == 4)) {
- let actionSheet = UIAlertController(title: "Security", message: nil, preferredStyle: .actionSheet)
- for securityMode in SecurityMode.allCases {
- actionSheet.addAction(UIAlertAction(title: securityMode.rawValue, style: .default, handler: {
- [unowned self]
- _ in
- if isIMAP {
- self.model.imapSecurity = securityMode
- }
- if isSMTP {
- self.model.smtpSecurity = securityMode
- }
- }))
- }
- actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in }))
- if let popoverController = actionSheet.popoverPresentationController {
- if let cell = tableView.cellForRow(at: indexPath) {
- popoverController.sourceView = cell.detailTextLabel
- }
- }
- present(actionSheet, animated: true, completion: {})
- }
- }
- override func tableView(_: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let section = indexPath.section
- let row = indexPath.row
- if section == 0 {
- return cells[row]
- }
- if section == 1 {
- if row == 0 {
- return imapCellLoginName
- } else if row == 1 {
- return imapCellServer
- } else if row == 2 {
- return imapCellPort
- // } else if row == 3 {
- // return imapCellSecurity
- } else if row == 3 {
- // FIXME: support iPad
- imapCellSecurity.textLabel?.text = "Security:"
- imapCellSecurity.selectionStyle = .none
- imapCellSecurity.detailTextLabel?.text = model.imapSecurity.rawValue
- return imapCellSecurity
- }
- }
- if section == 2 {
- if row == 0 {
- return smtpCellLoginName
- } else if row == 1 {
- return smtpCellPassword
- } else if row == 2 {
- return smtpCellServer
- } else if row == 3 {
- return smtpCellPort
- } else if row == 4 {
- // FIXME: support iPad
- smtpCellSecurity.selectionStyle = .none
- smtpCellSecurity.textLabel?.text = "Security:"
- smtpCellSecurity.detailTextLabel?.text = model.smtpSecurity.rawValue
- return smtpCellSecurity
- }
- }
- return UITableViewCell()
- }
- override func didReceiveMemoryWarning() {
- super.didReceiveMemoryWarning()
- // Dispose of any resources that can be recreated.
- }
- }
- extension CredentialsController: UITextFieldDelegate {
- func textFieldShouldReturn(_ textField: UITextField) -> Bool {
- if textField == emailCell.textField {
- if let emailText = emailCell.textField.text {
- // only jump to next field if valid email
- if Utils.isValid(emailText) {
- passwordCell.textField.becomeFirstResponder()
- }
- }
- }
- if textField == passwordCell.textField {
- if readyForLogin() {
- didPressSaveAccountButton()
- }
- }
- return true
- }
- }
- extension CredentialsController {
- @objc func emailTextChanged() {
- let emailText = emailCell.textField.text ?? ""
- model.email = emailText
- }
- @objc func passwordTextChanged() {
- let passwordText = passwordCell.textField.text ?? ""
- model.password = passwordText
- }
- @objc func imapLoginNameChanged() {
- model.imapLoginName = imapCellLoginName.textField.text
- }
- @objc func imapServerChanged() {
- model.imapServer = imapCellServer.textField.text
- }
- @objc func imapPortChanged() {
- model.imapPort = imapCellPort.textField.text
- }
- @objc func smtpLoginNamedChanged() {
- model.smtpLoginName = smtpCellLoginName.textField.text
- }
- @objc func smtpPasswordChanged() {
- model.smtpPassword = smtpCellPassword.textField.text
- }
- @objc func smtpServerChanged() {
- model.smtpServer = smtpCellServer.textField.text
- }
- @objc func smtpPortChanged() {
- model.smtpPort = smtpCellPort.textField.text
- }
- }
|