Browse Source

Merge pull request #293 from deltachat/tweak-account-setup

tweak account setup
björn petersen 5 years ago
parent
commit
ed06b2d9f2

+ 93 - 97
deltachat-ios/Controller/AccountSetupController.swift

@@ -94,13 +94,30 @@ class AccountSetupController: UITableViewController {
         return cell
     }()
 
-    private lazy var restoreCell: ActionCell = {
-        let cell = ActionCell(frame: .zero)
-        cell.actionTitle = String.localized("import_backup_title")
+    private lazy var restoreCell: UITableViewCell = {
+        let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
+        cell.textLabel?.text = String.localized("import_backup_title")
+        cell.accessoryType = .disclosureIndicator
         cell.accessibilityIdentifier = "restoreCell"
         return cell
     }()
 
+    private lazy var deleteAccountCell: ActionCell = {
+        let cell = ActionCell(frame: .zero)
+        cell.actionTitle = String.localized("delete_account")
+        cell.actionColor = UIColor.red
+        cell.accessibilityIdentifier = "deleteAccountCell"
+        return cell
+    }()
+
+    lazy var advancedShowCell: UITableViewCell = {
+        let cell = UITableViewCell(style: .value1, reuseIdentifier: nil)
+        cell.textLabel?.text = String.localized("menu_advanced")
+        cell.accessoryType = .disclosureIndicator
+        cell.accessibilityIdentifier = "advancedShowCell"
+        return cell
+    }()
+
     lazy var imapServerCell: TextFieldCell = {
         let cell = TextFieldCell(descriptionID: "login_imap_server",
                                  placeholder: DcConfig.mailServer ?? DcConfig.configuredMailServer,
@@ -201,11 +218,13 @@ class AccountSetupController: UITableViewController {
     let basicSection = 0
     let restoreSection = 1
     let advancedSection = 2
-    let sectionCount = 3
+    let dangerSection = 3
+    private var sections = [Int]()
 
     private lazy var basicSectionCells: [UITableViewCell] = [emailCell, passwordCell]
     private lazy var restoreCells: [UITableViewCell] = [restoreCell]
     private lazy var advancedSectionCells: [UITableViewCell] = [
+        advancedShowCell,
         imapServerCell,
         imapUserCell,
         imapPortCell,
@@ -216,11 +235,21 @@ class AccountSetupController: UITableViewController {
         smtpPasswordCell,
         smtpSecurityCell
     ]
+    private lazy var dangerCells: [UITableViewCell] = [deleteAccountCell]
 
     private var advancedSectionShowing: Bool = false
 
-    init(dcContext: DcContext) {
+    init(dcContext: DcContext, editView: Bool) {
         self.dcContext = dcContext
+
+        self.sections.append(basicSection)
+        self.sections.append(advancedSection)
+        if editView {
+            self.sections.append(dangerSection)
+        } else {
+            self.sections.append(restoreSection)
+        }
+
         super.init(style: .grouped)
         hidesBottomBarWhenPushed = true
     }
@@ -232,7 +261,6 @@ class AccountSetupController: UITableViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         title = String.localized("login_header")
-        // navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close", style: .plain, target: self, action: #selector(closeButtonPressed))
         navigationItem.rightBarButtonItem = loginButton
     }
 
@@ -271,35 +299,24 @@ class AccountSetupController: UITableViewController {
     // MARK: - Table view data source
 
     override func numberOfSections(in _: UITableView) -> Int {
-        return sectionCount
+        return sections.count
     }
 
     override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
-        if section == basicSection {
+        if sections[section] == basicSection {
             return basicSectionCells.count
-        } else if section == restoreSection {
+        } else if sections[section] == restoreSection {
             return restoreCells.count
+        } else if sections[section] == dangerSection {
+            return dangerCells.count
         } else {
-            return advancedSectionShowing ? advancedSectionCells.count : 0
+            return advancedSectionShowing ? advancedSectionCells.count : 1
         }
     }
 
     override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
-        if section == advancedSection {
-            return String.localized("menu_advanced")
-        } else {
-            return nil
-        }
-    }
-
-    override func tableView(_: UITableView, viewForHeaderInSection section: Int) -> UIView? {
-        if section == advancedSection {
-            // Advanced Header
-            let advancedView = AdvancedSectionHeader()
-            advancedView.handleTap = toggleAdvancedSection
-            // set tapHandler
-            return advancedView
-
+        if sections[section] == dangerSection {
+            return String.localized("danger")
         } else {
             return nil
         }
@@ -310,14 +327,10 @@ class AccountSetupController: UITableViewController {
     }
 
     override func tableView(_: UITableView, titleForFooterInSection section: Int) -> String? {
-        if section == basicSection {
+        if sections[section] == basicSection {
             return String.localized("login_no_servers_hint")
-        } else if section == advancedSection {
-            if advancedSectionShowing {
-                return String.localized("login_subheader")
-            } else {
-                return nil
-            }
+        } else if sections[section] == advancedSection {
+            return String.localized("login_subheader")
         } else {
             return nil
         }
@@ -327,10 +340,12 @@ class AccountSetupController: UITableViewController {
         let section = indexPath.section
         let row = indexPath.row
 
-        if section == basicSection {
+        if sections[section] == basicSection {
             return basicSectionCells[row]
-        } else if section == restoreSection {
+        } else if sections[section] == restoreSection {
             return restoreCells[row]
+        } else if sections[section] == dangerSection {
+            return dangerCells[row]
         } else {
             return advancedSectionCells[row]
         }
@@ -348,7 +363,12 @@ class AccountSetupController: UITableViewController {
         }
 
         if tappedCell.accessibilityIdentifier == "restoreCell" {
+            tableView.reloadData() // otherwise the disclosureIndicator may stay selected
             restoreBackup()
+        } else if tappedCell.accessibilityIdentifier == "deleteAccountCell" {
+            deleteAccount()
+        } else if tappedCell.accessibilityIdentifier == "advancedShowCell" {
+            toggleAdvancedSection()
         } else if tappedCell.accessibilityIdentifier == "IMAPPortCell" {
             coordinator?.showImapPortOptions()
         } else if tappedCell.accessibilityIdentifier == "SMTPPortCell" {
@@ -360,25 +380,21 @@ class AccountSetupController: UITableViewController {
         }
     }
 
-    private func toggleAdvancedSection(button: UILabel) {
+    private func toggleAdvancedSection() {
         let willShow = !advancedSectionShowing
 
-        // extract indexPaths from advancedCells
-        let advancedIndexPaths: [IndexPath] = advancedSectionCells.indices.map { IndexPath(row: $0, section: advancedSection) }
-
-        // advancedSectionCells.indices.map({indexPaths.append(IndexPath(row: $0, section: 1))}
+        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
 
-        // set flag before delete/insert operation, because cellForRowAt will be triggered and uses this flag
-        advancedSectionShowing = willShow
-
-        button.text = String.localized(willShow ? "hide" : "pref_notifications_show")
+        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 {
             tableView.deleteRows(at: advancedIndexPaths, with: .fade)
         }
-        tableView.reloadData() // to re-organize footer view (without that sometimes advanced section footer is still visible)
+        tableView.reloadData() // needed to force a redraw
     }
 
     @objc private func loginButtonPressed() {
@@ -574,6 +590,39 @@ class AccountSetupController: UITableViewController {
         logger.error("no documents directory found")
     }
 
+    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_message"),
+                                      message: nil,
+                                      preferredStyle: .actionSheet)
+
+        alert.addAction(UIAlertAction(title: String.localized("delete_account"), style: .destructive, handler: { _ in
+            appDelegate.stop()
+            appDelegate.close()
+            do {
+                try FileManager.default.removeItem(at: dburl)
+            } catch {
+                logger.error("failed to delete db: \(error)")
+            }
+
+            appDelegate.open()
+            appDelegate.start()
+
+            self.coordinator?.navigationController.popToRootViewController(animated: true)
+            appDelegate.appCoordinator.presentLoginController()
+        }))
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel))
+        present(alert, animated: true, completion: nil)
+
+
+        coordinator?.navigationController.popToRootViewController(animated: true)
+    }
+
     private func handleLoginSuccess() {
         // used when login hud successfully went trough
         dismiss(animated: true, completion: nil)
@@ -628,56 +677,3 @@ extension AccountSetupController: UITextFieldDelegate {
         }
     }
 }
-
-class AdvancedSectionHeader: UIView {
-    var handleTap: ((UILabel) -> Void)?
-
-    private var label: UILabel = {
-        let label = UILabel()
-        label.text = String.localized("menu_advanced").uppercased()
-        label.font = UIFont.systemFont(ofSize: 15)
-        label.textColor = UIColor.darkGray
-        return label
-    }()
-
-    /*
-     why UILabel, why no UIButton? For unknown reasons UIButton's target function was not triggered when one of the textfields in the tableview was active -> used label as workaround
-     */
-    private lazy var toggleButton: UILabel = {
-        let label = UILabel()
-        label.text = String.localized("pref_notifications_show")
-        label.font = UIFont.systemFont(ofSize: 15, weight: .medium)
-        label.textColor = UIColor.systemBlue
-        return label
-    }()
-
-    init() {
-        super.init(frame: .zero) // will be constraint from tableViewDelegate
-        setupSubviews()
-        let tap = UITapGestureRecognizer(target: self, action: #selector(viewTapped)) // use this if the whole header is supposed to be clickable
-        addGestureRecognizer(tap)
-    }
-
-    required init?(coder _: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-
-    func setupSubviews() {
-        addSubview(label)
-        label.translatesAutoresizingMaskIntoConstraints = false
-        label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15).isActive = true
-        label.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
-        addSubview(toggleButton)
-        toggleButton.translatesAutoresizingMaskIntoConstraints = false
-        toggleButton.leadingAnchor.constraint(equalTo: trailingAnchor, constant: -60).isActive = true // since button will change title it should be left aligned
-        toggleButton.centerYAnchor.constraint(equalTo: label.centerYAnchor, constant: 0).isActive = true
-    }
-
-    @objc func buttonTapped(_: UIButton) {
-        // handleTap?(button)
-    }
-
-    @objc func viewTapped() {
-        handleTap?(toggleButton)
-    }
-}

+ 4 - 53
deltachat-ios/Controller/SettingsController.swift

@@ -96,13 +96,13 @@ internal final class SettingsViewController: QuickTableViewController {
                 rows: [
                     NavigationRow(text: DcConfig.displayname ?? String.localized("pref_your_name"),
                         detailText: .subtitle(subtitle),
-                        action: { [weak self] in
-                            self?.editNameAndStatus($0)
+                        action: { _ in
+                            self.coordinator?.showEditSettingsController()
                     }),
                     NavigationRow(text: String.localized("pref_password_and_account_settings"),
                         detailText: .none,
-                        action: { [weak self] in
-                            self?.presentAccountSetup($0)
+                        action: { _ in
+                            self.coordinator?.showAccountSetupController()
                     }),
                 ]
             ),
@@ -184,13 +184,6 @@ internal final class SettingsViewController: QuickTableViewController {
                 ],
                 footer: String.localized("pref_backup_explain")
             ),
-
-            Section(
-                title: String.localized("danger"),
-                rows: [
-                    TapActionRow(text: String.localized("delete_account"), action: { [weak self] in self?.deleteAccount($0) }),
-                ]
-            ),
         ]
     }
 
@@ -256,46 +249,4 @@ internal final class SettingsViewController: QuickTableViewController {
         hudHandler.showHud(String.localized("configuring_account"))
         dc_configure(mailboxPointer)
     }
-
-    private func deleteAccount(_: Row) {
-        logger.info("deleting account")
-        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_message"),
-                                      message: nil,
-                                      preferredStyle: .actionSheet)
-
-        alert.addAction(UIAlertAction(title: String.localized("delete_account"), style: .destructive, handler: { _ in
-            appDelegate.stop()
-            appDelegate.close()
-            do {
-                try FileManager.default.removeItem(at: dburl)
-            } catch {
-                logger.error("failed to delete db: \(error)")
-            }
-
-            appDelegate.open()
-            appDelegate.start()
-
-            // refresh our view
-            self.setTable()
-            self.tableView.reloadData()
-            self.dismiss(animated: false, completion: nil)
-            self.coordinator?.showLoginController()
-        }))
-        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel))
-        present(alert, animated: true, completion: nil)
-    }
-
-    private func presentAccountSetup(_: Row) {
-        coordinator?.showAccountSetupController()
-    }
-
-    private func editNameAndStatus(_ row: Row) {
-        coordinator?.showEditSettingsController()
-    }
 }

+ 7 - 14
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -102,9 +102,9 @@ class AppCoordinator: NSObject, Coordinator {
     }
 
     func presentLoginController() {
-        let accountSetupController = AccountSetupController(dcContext: dcContext)
+        let accountSetupController = AccountSetupController(dcContext: dcContext, editView: false)
         let accountSetupNav = DcNavigationController(rootViewController: accountSetupController)
-        let coordinator = AccountSetupCoordinator(navigationController: accountSetupNav)
+        let coordinator = AccountSetupCoordinator(dcContext: dcContext, navigationController: accountSetupNav)
         childCoordinators.append(coordinator)
         accountSetupController.coordinator = coordinator
         rootViewController.present(accountSetupNav, animated: false, completion: nil)
@@ -188,8 +188,8 @@ class SettingsCoordinator: Coordinator {
     }
 
     func showAccountSetupController() {
-        let accountSetupVC = AccountSetupController(dcContext: dcContext)
-        let coordinator = AccountSetupCoordinator(navigationController: navigationController)
+        let accountSetupVC = AccountSetupController(dcContext: dcContext, editView: true)
+        let coordinator = AccountSetupCoordinator(dcContext: dcContext, navigationController: navigationController)
         childCoordinators.append(coordinator)
         accountSetupVC.coordinator = coordinator
         navigationController.pushViewController(accountSetupVC, animated: true)
@@ -200,15 +200,6 @@ class SettingsCoordinator: Coordinator {
         navigationController.pushViewController(editController, animated: true)
     }
 
-    func showLoginController() {
-        let accountSetupVC = AccountSetupController(dcContext: dcContext)
-        let coordinator = AccountSetupCoordinator(navigationController: navigationController)
-        childCoordinators.append(coordinator)
-        accountSetupVC.coordinator = coordinator
-        let accountSetupNavigationController = DcNavigationController(rootViewController: accountSetupVC)
-        navigationController.present(accountSetupNavigationController, animated: true, completion: nil)
-    }
-
     func showClassicMail() {
         let settingsClassicViewController = SettingsClassicViewController(dcContext: dcContext)
         navigationController.pushViewController(settingsClassicViewController, animated: true)
@@ -221,9 +212,11 @@ class SettingsCoordinator: Coordinator {
 }
 
 class AccountSetupCoordinator: Coordinator {
+    var dcContext: DcContext
     let navigationController: UINavigationController
 
-    init(navigationController: UINavigationController) {
+    init(dcContext: DcContext, navigationController: UINavigationController) {
+        self.dcContext = dcContext
         self.navigationController = navigationController
     }