浏览代码

added ProviderInfoCell and setup flow

nayooti 5 年之前
父节点
当前提交
487d5e5d09

+ 5 - 1
deltachat-ios.xcodeproj/project.pbxproj

@@ -152,6 +152,7 @@
 		AEE6EC3F2282C59C00EDC689 /* GroupMembersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE6EC3E2282C59C00EDC689 /* GroupMembersViewController.swift */; };
 		AEE6EC412282DF5700EDC689 /* MailboxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE6EC402282DF5700EDC689 /* MailboxViewController.swift */; };
 		AEE6EC482283045D00EDC689 /* EditSettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE6EC472283045D00EDC689 /* EditSettingsController.swift */; };
+		AEFBE22F23FEF23D0045327A /* ProviderInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEFBE22E23FEF23D0045327A /* ProviderInfoCell.swift */; };
 		B21005DB23383664004C70C5 /* SettingsClassicViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B21005DA23383664004C70C5 /* SettingsClassicViewController.swift */; };
 		B26B3BC7236DC3DC008ED35A /* SwitchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B26B3BC6236DC3DC008ED35A /* SwitchCell.swift */; };
 /* End PBXBuildFile section */
@@ -350,7 +351,7 @@
 		AE19887423EB264000B4CD5F /* HelpViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpViewController.swift; sourceTree = "<group>"; };
 		AE1988A423EB2FBA00B4CD5F /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = "<group>"; };
 		AE1988A623EB382A00B4CD5F /* Help */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Help; sourceTree = "<group>"; };
-		AE1988AA23EB3C7600B4CD5F /* Assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Assets; path = Assets; sourceTree = "<group>"; };
+		AE1988AA23EB3C7600B4CD5F /* Assets */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Assets; sourceTree = "<group>"; };
 		AE25F08F22807AD800CDEA66 /* AvatarSelectionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarSelectionCell.swift; sourceTree = "<group>"; };
 		AE38B31722672DFC00EC37A1 /* ActionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionCell.swift; sourceTree = "<group>"; };
 		AE38B3192267328200EC37A1 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
@@ -381,6 +382,7 @@
 		AEE6EC3E2282C59C00EDC689 /* GroupMembersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupMembersViewController.swift; sourceTree = "<group>"; };
 		AEE6EC402282DF5700EDC689 /* MailboxViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MailboxViewController.swift; sourceTree = "<group>"; };
 		AEE6EC472283045D00EDC689 /* EditSettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditSettingsController.swift; sourceTree = "<group>"; };
+		AEFBE22E23FEF23D0045327A /* ProviderInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderInfoCell.swift; sourceTree = "<group>"; };
 		B21005DA23383664004C70C5 /* SettingsClassicViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsClassicViewController.swift; sourceTree = "<group>"; };
 		B253ED992336E759004DD215 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = "<group>"; };
 		B253ED9A2336E759004DD215 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -787,6 +789,7 @@
 				AE9DAF0E22C278C6004C9591 /* ChatTitleView.swift */,
 				30F9B9EB235F2116006E7ACF /* MessageCounter.swift */,
 				305FE03523A81B4C0053BE90 /* PaddingLabel.swift */,
+				AEFBE22E23FEF23D0045327A /* ProviderInfoCell.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -1185,6 +1188,7 @@
 				AE1988A523EB2FBA00B4CD5F /* Errors.swift in Sources */,
 				305961DD2346125100C80F33 /* SenderType.swift in Sources */,
 				305961E32346125100C80F33 /* MessagesDataSource.swift in Sources */,
+				AEFBE22F23FEF23D0045327A /* ProviderInfoCell.swift in Sources */,
 				305961E22346125100C80F33 /* MessagesDisplayDelegate.swift in Sources */,
 				305962092346125100C80F33 /* AudioMessageSizeCalculator.swift in Sources */,
 				305961DB2346125100C80F33 /* AudioItem.swift in Sources */,

+ 237 - 182
deltachat-ios/Controller/AccountSetupController.swift

@@ -2,15 +2,15 @@ import SafariServices
 import UIKit
 
 class AccountSetupController: UITableViewController {
-
+    
     weak var coordinator: AccountSetupCoordinator?
-
+    
     private let dcContext: DcContext
     private var skipOauth = false
     private var backupProgressObserver: Any?
     private var configureProgressObserver: Any?
     private var oauth2Observer: Any?
-
+    
     private let tagEmailCell = 0
     private let tagPasswordCell = 1
     private let tagAdvancedCell = 2
@@ -27,7 +27,7 @@ class AccountSetupController: UITableViewController {
     private let tagEmptyServerCell = 13
     private let tagDeleteAccountCell = 14
     private let tagRestoreCell = 15
-
+    
     private let tagTextFieldEmail = 100
     private let tagTextFieldPassword = 200
     private let tagTextFieldImapServer = 300
@@ -35,16 +35,16 @@ class AccountSetupController: UITableViewController {
     private let tagTextFieldSmtpServer = 500
     private let tagTextFieldSmtpUser = 600
     private let tagTextFieldSmtpPassword = 700
-
+    
     // add cells to sections
-
+    
     let basicSection = 100
     let advancedSection = 200
     let restoreSection = 300
     let folderSection = 400
     let dangerSection = 500
     private var sections = [Int]()
-
+    
     private lazy var basicSectionCells: [UITableViewCell] = [emailCell, passwordCell]
     private lazy var restoreCells: [UITableViewCell] = [restoreCell]
     private lazy var advancedSectionCells: [UITableViewCell] = [
@@ -62,30 +62,33 @@ class AccountSetupController: UITableViewController {
     ]
     private lazy var folderCells: [UITableViewCell] = [inboxWatchCell, sentboxWatchCell, mvboxWatchCell, sendCopyToSelfCell, mvboxMoveCell]
     private lazy var dangerCells: [UITableViewCell] = [emptyServerCell, deleteAccountCell]
-
+    
     private let editView: Bool
     private var advancedSectionShowing: Bool = false
-
+    private var providerInfoShowing: Bool = false
+    
     private var provider: DcProvider?
-
-
-    // the progress dialog
-
+    
+    //MARK: -the progress dialog
+    
     private lazy var configProgressAlert: UIAlertController = {
         let alert = UIAlertController(title: "", message: "", preferredStyle: .alert)
-        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: { _ in
-            self.dcContext.stopOngoingProcess()
+        alert.addAction(UIAlertAction(
+            title: String.localized("cancel"),
+            style: .cancel,
+            handler: { _ in
+                self.dcContext.stopOngoingProcess()
         }))
         return alert
     }()
-
+    
     private func showProgressHud(title: String) {
         configProgressAlert.actions[0].isEnabled = true
         configProgressAlert.title = title
         configProgressAlert.message = String.localized("one_moment")
         present(configProgressAlert, animated: true, completion: nil)
     }
-
+    
     private func updateProgressHud(error message: String?) {
         DispatchQueue.main.async(execute: {
             self.configProgressAlert.dismiss(animated: false)
@@ -94,7 +97,7 @@ class AccountSetupController: UITableViewController {
             self.present(errorAlert, animated: true, completion: nil)
         })
     }
-
+    
     private func updateProgressHudSuccess() {
         updateProgressHudValue(value: 1000)
         DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
@@ -103,15 +106,15 @@ class AccountSetupController: UITableViewController {
             }
         })
     }
-
+    
     private func updateProgressHudValue(value: Int?) {
         if let value = value {
             configProgressAlert.message = String.localized("one_moment") + " " + String(value/10) + "%"
         }
     }
-
-    // cells
-
+    
+    // MARK: -cells
+    
     private lazy var emailCell: TextFieldCell = {
         let cell = TextFieldCell.makeEmailCell(delegate: self)
         cell.tag = tagEmailCell
@@ -121,7 +124,7 @@ class AccountSetupController: UITableViewController {
         cell.textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
         return cell
     }()
-
+    
     private lazy var passwordCell: TextFieldCell = {
         let cell = TextFieldCell.makePasswordCell(delegate: self)
         cell.tag = tagPasswordCell
@@ -132,6 +135,11 @@ class AccountSetupController: UITableViewController {
         return cell
     }()
 
+    private lazy var providerInfoCell: ProviderInfoCell = {
+        let cell = ProviderInfoCell()
+        return cell
+    }()
+    
     private lazy var restoreCell: UITableViewCell = {
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
         cell.textLabel?.text = String.localized("import_backup_title")
@@ -139,7 +147,7 @@ class AccountSetupController: UITableViewController {
         cell.tag = tagRestoreCell
         return cell
     }()
-
+    
     private lazy var emptyServerCell: ActionCell = {
         let cell = ActionCell(frame: .zero)
         cell.actionTitle = String.localized("pref_empty_server_title")
@@ -147,7 +155,7 @@ class AccountSetupController: UITableViewController {
         cell.tag = tagEmptyServerCell
         return cell
     }()
-
+    
     private lazy var deleteAccountCell: ActionCell = {
         let cell = ActionCell(frame: .zero)
         cell.actionTitle = String.localized("delete_account")
@@ -155,7 +163,7 @@ class AccountSetupController: UITableViewController {
         cell.tag = tagDeleteAccountCell
         return cell
     }()
-
+    
     lazy var advancedShowCell: UITableViewCell = {
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
         cell.textLabel?.text = String.localized("menu_advanced")
@@ -163,11 +171,12 @@ class AccountSetupController: UITableViewController {
         cell.tag = tagAdvancedCell
         return cell
     }()
-
+    
     lazy var imapServerCell: TextFieldCell = {
-        let cell = TextFieldCell(descriptionID: "login_imap_server",
-                                 placeholder: String.localized("automatic"),
-                                 delegate: self)
+        let cell = TextFieldCell(
+            descriptionID: "login_imap_server",
+            placeholder: String.localized("automatic"),
+            delegate: self)
         cell.tag = tagImapServerCell
         cell.setText(text: DcConfig.mailServer ?? nil)
         cell.textField.tag = tagTextFieldImapServer
@@ -176,15 +185,18 @@ class AccountSetupController: UITableViewController {
         cell.textField.autocapitalizationType = .none
         return cell
     }()
-
+    
     lazy var imapUserCell: TextFieldCell = {
-        let cell = TextFieldCell(descriptionID: "login_imap_login", placeholder: String.localized("automatic"), delegate: self)
+        let cell = TextFieldCell(
+            descriptionID: "login_imap_login",
+            placeholder: String.localized("automatic"),
+            delegate: self)
         cell.setText(text: DcConfig.mailUser ?? nil)
         cell.textField.tag = tagTextFieldImapLogin
         cell.tag = tagImapUserCell
         return cell
     }()
-
+    
     func editablePort(port: String?) -> String {
         if let port = port {
             if Int(port) == 0 {
@@ -195,18 +207,19 @@ class AccountSetupController: UITableViewController {
             return ""
         }
     }
-
+    
     lazy var imapPortCell: TextFieldCell = {
-        let cell = TextFieldCell(descriptionID: "login_imap_port",
-                                 placeholder: String.localized("automatic"),
-                                 delegate: self)
+        let cell = TextFieldCell(
+            descriptionID: "login_imap_port",
+            placeholder: String.localized("automatic"),
+            delegate: self)
         cell.tag = tagImapPortCell
         cell.setText(text: editablePort(port: DcConfig.mailPort))
         cell.textField.tag = tagImapPortCell
         cell.textField.keyboardType = .numberPad
         return cell
     }()
-
+    
     lazy var imapSecurityCell: UITableViewCell = {
         let text = "\(DcConfig.getImapSecurity())"
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
@@ -217,11 +230,12 @@ class AccountSetupController: UITableViewController {
         cell.tag = tagImapSecurityCell
         return cell
     }()
-
+    
     lazy var smtpServerCell: TextFieldCell = {
-        let cell = TextFieldCell(descriptionID: "login_smtp_server",
-                                 placeholder: String.localized("automatic"),
-                                 delegate: self)
+        let cell = TextFieldCell(
+            descriptionID: "login_smtp_server",
+            placeholder: String.localized("automatic"),
+            delegate: self)
         cell.textField.tag = tagTextFieldSmtpServer
         cell.setText(text: DcConfig.sendServer ?? nil)
         cell.tag = tagSmtpServerCell
@@ -230,28 +244,35 @@ class AccountSetupController: UITableViewController {
         cell.textField.autocapitalizationType = .none
         return cell
     }()
-
+    
     lazy var smtpUserCell: TextFieldCell = {
-        let cell = TextFieldCell(descriptionID: "login_smtp_login", placeholder: String.localized("automatic"), delegate: self)
+        let cell = TextFieldCell(
+            descriptionID: "login_smtp_login",
+            placeholder: String.localized("automatic"),
+            delegate: self)
         cell.textField.tag = tagTextFieldSmtpUser
         cell.setText(text: DcConfig.sendUser ?? nil)
         cell.tag = tagSmtpUserCell
         return cell
     }()
-
+    
     lazy var smtpPortCell: TextFieldCell = {
-        let cell = TextFieldCell(descriptionID: "login_smtp_port",
-                                 placeholder: String.localized("automatic"),
-                                 delegate: self)
+        let cell = TextFieldCell(
+            descriptionID: "login_smtp_port",
+            placeholder: String.localized("automatic"),
+            delegate: self)
         cell.tag = tagSmtpPortCell
         cell.setText(text: editablePort(port: DcConfig.sendPort))
         cell.textField.tag = tagSmtpPortCell
         cell.textField.keyboardType = .numberPad
         return cell
     }()
-
+    
     lazy var smtpPasswordCell: TextFieldCell = {
-        let cell = TextFieldCell(descriptionID: "login_smtp_password", placeholder: String.localized("automatic"), delegate: self)
+        let cell = TextFieldCell(
+            descriptionID: "login_smtp_password",
+            placeholder: String.localized("automatic"),
+            delegate: self)
         cell.textField.textContentType = UITextContentType.password
         cell.setText(text: DcConfig.sendPw ?? nil)
         cell.textField.isSecureTextEntry = true
@@ -259,7 +280,7 @@ class AccountSetupController: UITableViewController {
         cell.tag = tagSmtpPasswordCell
         return cell
     }()
-
+    
     lazy var smtpSecurityCell: UITableViewCell = {
         let security = "\(DcConfig.getSmtpSecurity())"
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
@@ -270,7 +291,7 @@ class AccountSetupController: UITableViewController {
         cell.selectionStyle = .none
         return cell
     }()
-
+    
     lazy var certCheckCell: UITableViewCell = {
         let certCheckType = CertificateCheckController.ValueConverter.convertHexToString(value: DcConfig.certificateChecks)
         let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
@@ -281,57 +302,67 @@ class AccountSetupController: UITableViewController {
         cell.selectionStyle = .none
         return cell
     }()
-
+    
     lazy var inboxWatchCell: SwitchCell = {
-        return SwitchCell(textLabel: String.localized("pref_watch_inbox_folder"),
-                          on: dcContext.getConfigBool("inbox_watch"),
-                          action: { cell in
-                              self.dcContext.setConfigBool("inbox_watch", cell.isOn)
-                          })
+        return SwitchCell(
+            textLabel: String.localized("pref_watch_inbox_folder"),
+            on: dcContext.getConfigBool("inbox_watch"),
+            action: { cell in
+                self.dcContext.setConfigBool("inbox_watch", cell.isOn)
+        })
     }()
-
+    
     lazy var sentboxWatchCell: SwitchCell = {
-        return SwitchCell(textLabel: String.localized("pref_watch_sent_folder"),
-                          on: dcContext.getConfigBool("sentbox_watch"),
-                          action: { cell in
-                              self.dcContext.setConfigBool("sentbox_watch", cell.isOn)
-                          })
+        return SwitchCell(
+            textLabel: String.localized("pref_watch_sent_folder"),
+            on: dcContext.getConfigBool("sentbox_watch"),
+            action: { cell in
+                self.dcContext.setConfigBool("sentbox_watch", cell.isOn)
+        })
     }()
-
+    
     lazy var mvboxWatchCell: SwitchCell = {
-        return SwitchCell(textLabel: String.localized("pref_watch_mvbox_folder"),
-                          on: dcContext.getConfigBool("mvbox_watch"),
-                          action: { cell in
-                              self.dcContext.setConfigBool("mvbox_watch", cell.isOn)
-                          })
+        return SwitchCell(
+            textLabel: String.localized("pref_watch_mvbox_folder"),
+            on: dcContext.getConfigBool("mvbox_watch"),
+            action: { cell in
+                self.dcContext.setConfigBool("mvbox_watch", cell.isOn)
+        })
     }()
-
+    
     lazy var sendCopyToSelfCell: SwitchCell = {
-        return SwitchCell(textLabel: String.localized("pref_send_copy_to_self"),
-                          on: dcContext.getConfigBool("bcc_self"),
-                          action: { cell in
-                              self.dcContext.setConfigBool("bcc_self", cell.isOn)
-                          })
+        return SwitchCell(
+            textLabel: String.localized("pref_send_copy_to_self"),
+            on: dcContext.getConfigBool("bcc_self"),
+            action: { cell in
+                self.dcContext.setConfigBool("bcc_self", cell.isOn)
+        })
     }()
-
+    
     lazy var mvboxMoveCell: SwitchCell = {
-        return SwitchCell(textLabel: String.localized("pref_auto_folder_moves"),
-                          on: dcContext.getConfigBool("mvbox_move"),
-                          action: { cell in
-                              self.dcContext.setConfigBool("mvbox_move", cell.isOn)
-                          })
+        return SwitchCell(
+            textLabel: String.localized("pref_auto_folder_moves"),
+            on: dcContext.getConfigBool("mvbox_move"),
+            action: { cell in
+                self.dcContext.setConfigBool("mvbox_move", cell.isOn)
+        })
     }()
-
+    
     private lazy var loginButton: UIBarButtonItem = {
-        let button = UIBarButtonItem(title: String.localized("login_title"), style: .done, target: self, action: #selector(loginButtonPressed))
+        let button = UIBarButtonItem(
+            title: String.localized("login_title"),
+            style: .done,
+            target: self,
+            action: #selector(loginButtonPressed))
         button.isEnabled = dc_is_configured(mailboxPointer) == 0
         return button
     }()
 
+    // MARK: - constructor
     init(dcContext: DcContext, editView: Bool) {
         self.editView = editView
         self.dcContext = dcContext
-
+        
         self.sections.append(basicSection)
         self.sections.append(advancedSection)
         if editView {
@@ -340,15 +371,16 @@ class AccountSetupController: UITableViewController {
         } else {
             self.sections.append(restoreSection)
         }
-
+        
         super.init(style: .grouped)
         hidesBottomBarWhenPushed = true
     }
-
+    
     required init?(coder _: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }
 
+    // MARK: -lifecycle
     override func viewDidLoad() {
         super.viewDidLoad()
         if editView {
@@ -358,23 +390,23 @@ class AccountSetupController: UITableViewController {
         }
         navigationItem.rightBarButtonItem = loginButton
     }
-
+    
     override func viewWillAppear(_ animated: Bool) {
         super.viewWillAppear(animated)
         initSelectionCells()
         handleLoginButton()
     }
-
+    
     override func viewDidAppear(_ animated: Bool) {
         super.viewDidAppear(animated)
     }
-
+    
     override func viewWillDisappear(_ animated: Bool) {
         resignFirstResponderOnAllCells()
     }
-
+    
     override func viewDidDisappear(_: Bool) {
-
+        
         let nc = NotificationCenter.default
         if let backupProgressObserver = self.backupProgressObserver {
             nc.removeObserver(backupProgressObserver)
@@ -386,13 +418,12 @@ class AccountSetupController: UITableViewController {
             nc.removeObserver(oauth2Observer)
         }
     }
-
+    
     // MARK: - Table view data source
-
     override func numberOfSections(in _: UITableView) -> Int {
         return sections.count
     }
-
+    
     override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
         if sections[section] == basicSection {
             return basicSectionCells.count
@@ -406,7 +437,7 @@ class AccountSetupController: UITableViewController {
             return advancedSectionShowing ? advancedSectionCells.count : 1
         }
     }
-
+    
     override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
         if sections[section] == basicSection && editView {
             return String.localized("login_header")
@@ -418,7 +449,7 @@ class AccountSetupController: UITableViewController {
             return nil
         }
     }
-
+    
     override func tableView(_: UITableView, titleForFooterInSection section: Int) -> String? {
         if sections[section] == basicSection {
             if provider != nil && (provider?.status==DC_PROVIDER_STATUS_PREPARATION || provider?.status==DC_PROVIDER_STATUS_BROKEN) {
@@ -451,11 +482,11 @@ class AccountSetupController: UITableViewController {
             return nil
         }
     }
-
+    
     override func tableView(_: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let section = indexPath.section
         let row = indexPath.row
-
+        
         if sections[section] == basicSection {
             return basicSectionCells[row]
         } else if sections[section] == restoreSection {
@@ -468,7 +499,7 @@ class AccountSetupController: UITableViewController {
             return advancedSectionCells[row]
         }
     }
-
+    
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         guard let tappedCell = tableView.cellForRow(at: indexPath) else { return }
         // handle tap on password -> show oAuthDialogue
@@ -499,19 +530,20 @@ class AccountSetupController: UITableViewController {
         }
     }
 
+    // MARK: -actions
     private func toggleAdvancedSection() {
         let willShow = !advancedSectionShowing
-
+        
         guard let advancedSectionIndex = sections.firstIndex(of: advancedSection) else { return }
         var advancedIndexPaths: [IndexPath] = advancedSectionCells.indices.map { IndexPath(row: $0, section: advancedSectionIndex) }
         advancedIndexPaths.removeFirst() // do not touch the first item that is the switch itself
-
+        
         // on expansion, replace the disclosureIndicator by an n-dash
         advancedShowCell.accessoryType = willShow ? .none : .disclosureIndicator
         advancedShowCell.detailTextLabel?.text = willShow ? "\u{2013}" : nil
-
+        
         advancedSectionShowing = willShow // set flag before delete/insert, because cellForRowAt will be triggered and uses this flag
-
+        
         if willShow {
             tableView.insertRows(at: advancedIndexPaths, with: .fade)
         } else {
@@ -519,92 +551,115 @@ class AccountSetupController: UITableViewController {
         }
         tableView.reloadData() // needed to force a redraw
     }
-
+    
     @objc private func loginButtonPressed() {
         guard let emailAddress = emailCell.getText() else {
             return // handle case when either email or pw fields are empty
         }
-
+        
         let oAuthStarted = showOAuthAlertIfNeeded(emailAddress: emailAddress, handleCancel: loginButtonPressed)
         // if canceled we will run this method again but this time oAuthStarted will be false
-
+        
         if oAuthStarted {
             // the loginFlow will be handled by oAuth2
             return
         }
-
+        
         let password = passwordCell.getText() ?? "" // empty passwords are ok -> for oauth there is no password needed
-
+        
         login(emailAddress: emailAddress, password: password)
     }
 
+    func updateProviderInfo() {
+        provider = dcContext.getProviderFromEmail(addr: emailCell.getText() ?? "")
+        if let hint = provider?.beforeLoginHint, let status = provider?.status, !hint.isEmpty {
+            showProviderInfo(with: hint, hintType: .preparation)
+        } else {
+            hideProviderInfo()
+        }
+    }
+
+    func showProviderInfo(with hint: String, hintType: ProviderInfoStatus) {
+        providerInfoCell.updateInfo(hint: hint, hintType: hintType)
+        basicSectionCells = [emailCell, passwordCell, providerInfoCell]
+        let providerInfoCellIndexPath = IndexPath(row: 2, section: 0)
+        tableView.insertRows(at: [providerInfoCellIndexPath], with: .automatic)
+    }
+
+    func hideProviderInfo() {
+        providerInfoCell.updateInfo(hint: nil, hintType: .none)
+        basicSectionCells = [emailCell, passwordCell]
+        let providerInfoCellIndexPath = IndexPath(row: 2, section: 0)
+        tableView.deleteRows(at: [providerInfoCellIndexPath], with: .automatic)
+    }
+    
     private func login(emailAddress: String, password: String, skipAdvanceSetup: Bool = false) {
         addProgressHudLoginListener()
         resignFirstResponderOnAllCells()	// this will resign focus from all textFieldCells so the keyboard wont pop up anymore
         DcConfig.addr = emailAddress
         DcConfig.mailPw = password
-
+        
         if !skipAdvanceSetup {
             evaluateAdvancedSetup() // this will set MRConfig related to advanced fields
         }
-
+        
         print("oAuth-Flag when loggin in: \(DcConfig.getAuthFlags())")
         dc_configure(mailboxPointer)
         showProgressHud(title: String.localized("login_header"))
     }
-
+    
     @objc func closeButtonPressed() {
         dismiss(animated: true, completion: nil)
     }
-
+    
     // returns true if needed
     private func showOAuthAlertIfNeeded(emailAddress: String, handleCancel: (() -> Void)?) -> Bool {
         return false
-
+        
         // disable oauth2 for now as not yet supported by deltachat-rust.
         /*
          if skipOauth {
-         	// user has previously denied oAuth2-setup
-         	return false
+         // user has previously denied oAuth2-setup
+         return false
          }
-
+         
          guard let oAuth2UrlPointer = dc_get_oauth2_url(mailboxPointer, emailAddress, "chat.delta:/auth") else {
-         	//MRConfig.setAuthFlags(flags: Int(DC_LP_AUTH_NORMAL)) -- do not reset, there may be different values
-         	return false
+         //MRConfig.setAuthFlags(flags: Int(DC_LP_AUTH_NORMAL)) -- do not reset, there may be different values
+         return false
          }
-
+         
          let oAuth2Url = String(cString: oAuth2UrlPointer)
-
+         
          if let url = URL(string: oAuth2Url) {
-         	let title = "Continue with simplified setup"
-         	// swiftlint:disable all
-         	let message = "The entered e-mail address supports a simplified setup (oAuth2).\n\nIn the next step, please allow Delta Chat to act as your Chat with E-Mail app.\n\nThere are no Delta Chat servers, your data stays on your device."
-
-         	let oAuthAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
-         	let confirm = UIAlertAction(title: "Confirm", style: .default, handler: {
-         		[unowned self] _ in
-         		let nc = NotificationCenter.default
-         		self.oauth2Observer = nc.addObserver(self, selector: #selector(self.oauthLoginApproved), name: NSNotification.Name("oauthLoginApproved"), object: nil)
-         		self.launchOAuthBrowserWindow(url: url)
-         	})
-         	let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: {
-         		_ in
-         		MRConfig.setAuthFlags(flags: Int(DC_LP_AUTH_NORMAL))
-         		self.skipOauth = true
-         		handleCancel?()
-
-         	})
-         	oAuthAlertController.addAction(confirm)
-         	oAuthAlertController.addAction(cancel)
-
-         	present(oAuthAlertController, animated: true, completion: nil)
-         	return true
+         let title = "Continue with simplified setup"
+         // swiftlint:disable all
+         let message = "The entered e-mail address supports a simplified setup (oAuth2).\n\nIn the next step, please allow Delta Chat to act as your Chat with E-Mail app.\n\nThere are no Delta Chat servers, your data stays on your device."
+         
+         let oAuthAlertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
+         let confirm = UIAlertAction(title: "Confirm", style: .default, handler: {
+         [unowned self] _ in
+         let nc = NotificationCenter.default
+         self.oauth2Observer = nc.addObserver(self, selector: #selector(self.oauthLoginApproved), name: NSNotification.Name("oauthLoginApproved"), object: nil)
+         self.launchOAuthBrowserWindow(url: url)
+         })
+         let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: {
+         _ in
+         MRConfig.setAuthFlags(flags: Int(DC_LP_AUTH_NORMAL))
+         self.skipOauth = true
+         handleCancel?()
+         
+         })
+         oAuthAlertController.addAction(confirm)
+         oAuthAlertController.addAction(cancel)
+         
+         present(oAuthAlertController, animated: true, completion: nil)
+         return true
          } else {
-         	return false
+         return false
          }
          */
     }
-
+    
     @objc func oauthLoginApproved(notification: Notification) {
         guard let userInfo = notification.userInfo, let token = userInfo["token"] as? String, let emailAddress = emailCell.getText() else {
             return
@@ -613,11 +668,11 @@ class AccountSetupController: UITableViewController {
         DcConfig.setAuthFlags(flags: Int(DC_LP_AUTH_OAUTH2))
         login(emailAddress: emailAddress, password: token, skipAdvanceSetup: true)
     }
-
+    
     private func launchOAuthBrowserWindow(url: URL) {
         UIApplication.shared.open(url) // this opens safari as seperate app
     }
-
+    
     private func addProgressHudLoginListener() {
         let nc = NotificationCenter.default
         configureProgressObserver = nc.addObserver(
@@ -637,7 +692,7 @@ class AccountSetupController: UITableViewController {
             }
         }
     }
-
+    
     private func addProgressHudBackupListener() {
         let nc = NotificationCenter.default
         backupProgressObserver = nc.addObserver(
@@ -657,7 +712,7 @@ class AccountSetupController: UITableViewController {
             }
         }
     }
-
+    
     private func evaluateAdvancedSetup() {
         for cell in advancedSectionCells {
             if let textFieldCell = cell as? TextFieldCell {
@@ -682,7 +737,7 @@ class AccountSetupController: UITableViewController {
             }
         }
     }
-
+    
     private func restoreBackup() {
         logger.info("restoring backup")
         if DcConfig.configured {
@@ -692,7 +747,7 @@ class AccountSetupController: UITableViewController {
         let documents = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
         if !documents.isEmpty {
             logger.info("looking for backup in: \(documents[0])")
-
+            
             if let cString = dc_imex_has_backup(mailboxPointer, documents[0]) {
                 let file = String(cString: cString)
                 dc_str_unref(cString)
@@ -701,21 +756,23 @@ class AccountSetupController: UITableViewController {
                 dc_imex(mailboxPointer, DC_IMEX_IMPORT_BACKUP, file, nil)
             }
             else {
-                let alert = UIAlertController(title: String.localized("import_backup_title"),
-                    message: String.localizedStringWithFormat(String.localized("import_backup_no_backup_found"),
+                let alert = UIAlertController(
+                    title: String.localized("import_backup_title"),
+                    message: String.localizedStringWithFormat(
+                        String.localized("import_backup_no_backup_found"),
                         "iTunes / <Your Device> / File Sharing / Delta Chat"), // TOOD: maybe better use an iOS-specific string here
                     preferredStyle: .alert)
                 alert.addAction(UIAlertAction(title: String.localized("ok"), style: .cancel))
                 present(alert, animated: true)
             }
         }
-
+        
         logger.error("no documents directory found")
     }
-
+    
     private func emptyServer() {
         let alert = UIAlertController(title: String.localized("pref_empty_server_title"),
-            message: String.localized("pref_empty_server_msg"), preferredStyle: .safeActionSheet)
+                                      message: String.localized("pref_empty_server_msg"), preferredStyle: .safeActionSheet)
         alert.addAction(UIAlertAction(title: String.localized("pref_empty_server_inbox"), style: .destructive, handler: { _ in
             self.emptyServer2ndConfirm(title: String.localized("pref_empty_server_inbox"), flags: Int(DC_EMPTY_INBOX))
         }))
@@ -725,9 +782,10 @@ class AccountSetupController: UITableViewController {
         alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel))
         present(alert, animated: true, completion: nil)
     }
-
+    
     private func emptyServer2ndConfirm(title: String, flags: Int) {
-        let alert = UIAlertController(title: title,
+        let alert = UIAlertController(
+            title: title,
             message: String.localized("pref_empty_server_msg"), preferredStyle: .alert)
         alert.addAction(UIAlertAction(title: String.localized("pref_empty_server_do_button"), style: .destructive, handler: { _ in
             self.dcContext.emptyServer(flags: flags)
@@ -735,18 +793,19 @@ class AccountSetupController: UITableViewController {
         alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel))
         present(alert, animated: true, completion: nil)
     }
-
+    
     private func deleteAccount() {
         guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
             return
         }
-
+        
         let dbfile = appDelegate.dbfile()
         let dburl = URL(fileURLWithPath: dbfile, isDirectory: false)
-        let alert = UIAlertController(title: String.localized("delete_account_ask"),
-                                      message: nil,
-                                      preferredStyle: .safeActionSheet)
-
+        let alert = UIAlertController(
+            title: String.localized("delete_account_ask"),
+            message: nil,
+            preferredStyle: .safeActionSheet)
+        
         alert.addAction(UIAlertAction(title: String.localized("delete_account"), style: .destructive, handler: { _ in
             appDelegate.stop()
             appDelegate.close()
@@ -755,16 +814,16 @@ class AccountSetupController: UITableViewController {
             } catch {
                 logger.error("failed to delete db: \(error)")
             }
-
+            
             appDelegate.open()
             appDelegate.start()
-
+            
             appDelegate.appCoordinator.presentLoginController()
         }))
         alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel))
         present(alert, animated: true, completion: nil)
     }
-
+    
     private func handleLoginSuccess() {
         // used when login hud successfully went trough
         dismiss(animated: true, completion: nil)
@@ -777,42 +836,38 @@ class AccountSetupController: UITableViewController {
             self.coordinator?.navigateBack()
         }
     }
-
+    
     private func initSelectionCells() {
         smtpSecurityCell.detailTextLabel?.text = SecurityConverter.convertHexToString(type: .SMTPSecurity, hex: DcConfig.getSmtpSecurity())
         imapSecurityCell.detailTextLabel?.text = SecurityConverter.convertHexToString(type: .IMAPSecurity, hex: DcConfig.getImapSecurity())
         certCheckCell.detailTextLabel?.text = CertificateCheckController.ValueConverter.convertHexToString(value: DcConfig.certificateChecks)
     }
-
+    
     private func resignFirstResponderOnAllCells() {
         let _ = basicSectionCells.map({
             resignCell(cell: $0)
         })
-
+        
         let _ = advancedSectionCells.map({
             resignCell(cell: $0)
-        }
+            }
         )
     }
-
+    
     private func handleLoginButton() {
         loginButton.isEnabled = !(emailCell.getText() ?? "").isEmpty && !(passwordCell.getText() ?? "").isEmpty
     }
-
+    
     func resignCell(cell: UITableViewCell) {
         if let c = cell as? TextFieldCell {
             c.textField.resignFirstResponder()
         }
     }
-
+    
     @objc private func textFieldDidChange() {
         handleLoginButton()
     }
 
-    func updateProviderInfo() {
-        provider = dcContext.getProviderFromEmail(addr: emailCell.getText() ?? "")
-        tableView.reloadData()
-    }
 }
 
 extension AccountSetupController: UITextFieldDelegate {
@@ -833,20 +888,20 @@ extension AccountSetupController: UITextFieldDelegate {
             return true
         }
     }
-
+    
     func textFieldDidBeginEditing(_ textField: UITextField) {
         if textField.tag == tagTextFieldEmail {
             // this will re-enable possible oAuth2-login
             skipOauth = false
         }
     }
-
+    
     func textFieldDidEndEditing(_ textField: UITextField) {
         if textField.tag == tagTextFieldEmail {
             let _ = showOAuthAlertIfNeeded(emailAddress: textField.text ?? "", handleCancel: {
                 self.passwordCell.textField.becomeFirstResponder()
             })
-
+            
             updateProviderInfo()
         }
     }

+ 83 - 0
deltachat-ios/View/ProviderInfoCell.swift

@@ -0,0 +1,83 @@
+//
+//  ProviderInfoCell.swift
+//  deltachat-ios
+//
+//  Created by Bastian van de Wetering on 20.02.20.
+//  Copyright © 2020 Jonas Reinsch. All rights reserved.
+//
+
+import UIKit
+
+enum ProviderInfoStatus {
+     case preparation
+     case broken
+     case ok
+ }
+
+class ProviderInfoCell: UITableViewCell {
+
+    private var hintBackgroundView: UIView = {
+        let view = UIView()
+        return view
+    }()
+
+    private var hintLabel: UILabel = {
+        let label = UILabel()
+        return label
+    }()
+
+    private var infoButton: UIButton = {
+        let button = UIButton()
+        button.setTitle("more_info_desktop".lowercased(), for: .normal)
+        return button
+    }()
+
+    init() {
+        super.init(style: .default, reuseIdentifier: nil)
+        setupSubviews()
+    }
+
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    private func setupSubviews() {
+
+        let margin: CGFloat = 20
+
+        contentView.addSubview(hintBackgroundView)
+        hintBackgroundView.addSubview(hintLabel)
+        hintBackgroundView.addSubview(infoButton)
+
+        contentView.translatesAutoresizingMaskIntoConstraints = false
+        contentView.translatesAutoresizingMaskIntoConstraints = false
+        contentView.translatesAutoresizingMaskIntoConstraints = false
+
+        hintBackgroundView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: margin).isActive = true
+        hintBackgroundView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5).isActive = true
+        hintBackgroundView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -margin).isActive = true
+        hintBackgroundView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true
+
+        hintLabel.leadingAnchor.constraint(equalTo: hintBackgroundView.leadingAnchor, constant: 5).isActive = true
+        hintLabel.topAnchor.constraint(equalTo: hintBackgroundView.topAnchor, constant: 5).isActive = true
+        hintLabel.trailingAnchor.constraint(equalTo: hintBackgroundView.trailingAnchor, constant: -5).isActive = true
+
+        infoButton.topAnchor.constraint(equalTo: hintLabel.bottomAnchor, constant: 10).isActive = true
+        infoButton.leadingAnchor.constraint(equalTo: hintBackgroundView.leadingAnchor, constant: 5).isActive = true
+        infoButton.bottomAnchor.constraint(equalTo: hintBackgroundView.bottomAnchor, constant: -5).isActive = true
+    }
+
+    func updateInfo(hint text: String?, hintType: ProviderInfoStatus?) {
+        hintLabel.text = text
+        switch hintType {
+        case .preparation:
+            hintBackgroundView.backgroundColor = SystemColor.yellow.uiColor
+        case .broken:
+            hintBackgroundView.backgroundColor = SystemColor.red.uiColor
+        case .ok:
+            hintBackgroundView.backgroundColor = .clear
+        case .none:
+            break
+        }
+    }
+}