소스 검색

Merge pull request #246 from deltachat/remove_contact_tab

remove contacts tab
björn petersen 5 년 전
부모
커밋
f2b3287d4c

+ 0 - 4
deltachat-ios.xcodeproj/project.pbxproj

@@ -26,7 +26,6 @@
 		78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3921D3CFBC00D4B15E /* SettingsController.swift */; };
 		78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3921D3CFBC00D4B15E /* SettingsController.swift */; };
 		78E45E3C21D3D03700D4B15E /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3B21D3D03700D4B15E /* TextFieldTableViewCell.swift */; };
 		78E45E3C21D3D03700D4B15E /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3B21D3D03700D4B15E /* TextFieldTableViewCell.swift */; };
 		78E45E3E21D3D28C00D4B15E /* DcNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3D21D3D28C00D4B15E /* DcNavigationController.swift */; };
 		78E45E3E21D3D28C00D4B15E /* DcNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3D21D3D28C00D4B15E /* DcNavigationController.swift */; };
-		78E45E4021D3D70700D4B15E /* ContactListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3F21D3D70700D4B15E /* ContactListController.swift */; };
 		78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */; };
 		78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */; };
 		78E45E4C21D404AE00D4B15E /* CustomMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4B21D404AE00D4B15E /* CustomMessageCell.swift */; };
 		78E45E4C21D404AE00D4B15E /* CustomMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4B21D404AE00D4B15E /* CustomMessageCell.swift */; };
 		78ED838321D5379000243125 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED838221D5379000243125 /* TextFieldCell.swift */; };
 		78ED838321D5379000243125 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED838221D5379000243125 /* TextFieldCell.swift */; };
@@ -164,7 +163,6 @@
 		78E45E3921D3CFBC00D4B15E /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
 		78E45E3921D3CFBC00D4B15E /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
 		78E45E3B21D3D03700D4B15E /* TextFieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewCell.swift; sourceTree = "<group>"; };
 		78E45E3B21D3D03700D4B15E /* TextFieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewCell.swift; sourceTree = "<group>"; };
 		78E45E3D21D3D28C00D4B15E /* DcNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DcNavigationController.swift; sourceTree = "<group>"; };
 		78E45E3D21D3D28C00D4B15E /* DcNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DcNavigationController.swift; sourceTree = "<group>"; };
-		78E45E3F21D3D70700D4B15E /* ContactListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactListController.swift; sourceTree = "<group>"; };
 		78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extension.swift"; sourceTree = "<group>"; };
 		78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extension.swift"; sourceTree = "<group>"; };
 		78E45E4B21D404AE00D4B15E /* CustomMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMessageCell.swift; sourceTree = "<group>"; };
 		78E45E4B21D404AE00D4B15E /* CustomMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMessageCell.swift; sourceTree = "<group>"; };
 		78ED838221D5379000243125 /* TextFieldCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldCell.swift; sourceTree = "<group>"; };
 		78ED838221D5379000243125 /* TextFieldCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldCell.swift; sourceTree = "<group>"; };
@@ -359,7 +357,6 @@
 				7092474020B3869500AF8799 /* ContactDetailViewController.swift */,
 				7092474020B3869500AF8799 /* ContactDetailViewController.swift */,
 				7AE0A5481FC42F65005ECB4B /* NewChatViewController.swift */,
 				7AE0A5481FC42F65005ECB4B /* NewChatViewController.swift */,
 				AE0D26FC1FB1FE88002FAFCE /* ChatListController.swift */,
 				AE0D26FC1FB1FE88002FAFCE /* ChatListController.swift */,
-				78E45E3F21D3D70700D4B15E /* ContactListController.swift */,
 				78ED838E21D5927A00243125 /* ProfileViewController.swift */,
 				78ED838E21D5927A00243125 /* ProfileViewController.swift */,
 				30149D9222F21129003C12B5 /* NewProfileViewController.swift */,
 				30149D9222F21129003C12B5 /* NewProfileViewController.swift */,
 				78E45E3921D3CFBC00D4B15E /* SettingsController.swift */,
 				78E45E3921D3CFBC00D4B15E /* SettingsController.swift */,
@@ -724,7 +721,6 @@
 				70B08FCD21073B910097D3EA /* NewGroupMemberChoiceController.swift in Sources */,
 				70B08FCD21073B910097D3EA /* NewGroupMemberChoiceController.swift in Sources */,
 				30BD261422F8679200F399DF /* ProfileView.swift in Sources */,
 				30BD261422F8679200F399DF /* ProfileView.swift in Sources */,
 				78E45E3E21D3D28C00D4B15E /* DcNavigationController.swift in Sources */,
 				78E45E3E21D3D28C00D4B15E /* DcNavigationController.swift in Sources */,
-				78E45E4021D3D70700D4B15E /* ContactListController.swift in Sources */,
 				AE18F294228C602A0007B1BE /* SecuritySettingsController.swift in Sources */,
 				AE18F294228C602A0007B1BE /* SecuritySettingsController.swift in Sources */,
 				78ED838D21D577D000243125 /* events.swift in Sources */,
 				78ED838D21D577D000243125 /* events.swift in Sources */,
 				AE851AC7227C776400ED86F0 /* Location.swift in Sources */,
 				AE851AC7227C776400ED86F0 /* Location.swift in Sources */,

+ 0 - 246
deltachat-ios/Controller/ContactListController.swift

@@ -1,246 +0,0 @@
-import UIKit
-import Contacts
-
-class ContactListController: UITableViewController {
-    weak var coordinator: ContactListCoordinator?
-
-    private lazy var searchController: UISearchController = {
-        let searchController = UISearchController(searchResultsController: nil)
-        searchController.searchResultsUpdater = self
-        searchController.obscuresBackgroundDuringPresentation = false
-        searchController.searchBar.placeholder = "Search Contact"
-        return searchController
-    }()
-
-    var contactIds: [Int] = Utils.getContactIds()
-
-    // contactWithSearchResults.indexesToHightLight empty by default
-    var contacts: [ContactWithSearchResults] {
-        return contactIds.map { ContactWithSearchResults(contact: DcContact(id: $0), indexesToHighlight: []) }
-    }
-
-    // used when seachbar is active
-    var filteredContacts: [ContactWithSearchResults] = []
-
-    // searchBar active?
-    func isFiltering() -> Bool {
-        return searchController.isActive && !searchBarIsEmpty()
-    }
-
-    let contactCellReuseIdentifier = "ChatCell"
-
-    lazy var deviceContactHandler: DeviceContactsHandler = {
-        let handler = DeviceContactsHandler()
-        handler.contactListDelegate = self
-        return handler
-    }()
-
-    lazy var newContactButton: UIBarButtonItem = {
-        let button = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(newContactButtonPressed))
-        // UIBarButtonItem(image: #imageLiteral(resourceName: "ic_add").withRenderingMode(.alwaysTemplate), style: .plain, target: self, action: #selector(newContactButtonPressed))
-        return button
-    }()
-
-    var deviceContactAccessGranted: Bool = false {
-        didSet {
-            tableView.reloadData()
-        }
-    }
-
-    override func viewDidLoad() {
-        super.viewDidLoad()
-        title = "Contacts"
-        navigationController?.navigationBar.prefersLargeTitles = true
-        navigationItem.searchController = searchController
-        tableView.register(ContactCell.self, forCellReuseIdentifier: contactCellReuseIdentifier)
-        tableView.register(ActionCell.self, forCellReuseIdentifier: "actionCell")
-
-        navigationItem.rightBarButtonItem = newContactButton
-    }
-
-    private func getContactIds() {
-        contactIds = Utils.getContactIds()
-        tableView.reloadData()
-    }
-
-    private func searchBarIsEmpty() -> Bool {
-        return searchController.searchBar.text?.isEmpty ?? true
-    }
-
-    private func filterContentForSearchText(_ searchText: String, scope _: String = String.localized("pref_show_emails_all")) {
-        let contactsWithHighlights: [ContactWithSearchResults] = contacts.map { contact in
-            let indexes = contact.contact.contains(searchText: searchText)
-            return ContactWithSearchResults(contact: contact.contact, indexesToHighlight: indexes)
-        }
-
-        filteredContacts = contactsWithHighlights.filter { !$0.indexesToHighlight.isEmpty }
-        tableView.reloadData()
-    }
-
-    override func viewWillAppear(_ animated: Bool) {
-        super.viewWillAppear(animated)
-        if #available(iOS 11.0, *) {
-            navigationController?.navigationBar.prefersLargeTitles = true
-        }
-        deviceContactHandler.importDeviceContacts()
-        deviceContactAccessGranted = CNContactStore.authorizationStatus(for: .contacts) == .authorized
-        searchController.searchBar.text = nil
-        getContactIds()
-    }
-
-    override func viewWillDisappear(_ animated: Bool) {
-        super.viewWillDisappear(animated)
-        if #available(iOS 11.0, *) {
-            navigationController?.navigationBar.prefersLargeTitles = false
-        }
-    }
-
-    override func didReceiveMemoryWarning() {
-        super.didReceiveMemoryWarning()
-    }
-
-    override func numberOfSections(in _: UITableView) -> Int {
-        return deviceContactAccessGranted ? 1 : 2
-    }
-
-    override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
-        if !deviceContactAccessGranted && section == 0 {
-            return 1
-        }
-        return isFiltering() ? filteredContacts.count : contactIds.count
-    }
-
-    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        let section = indexPath.section
-
-        if !deviceContactAccessGranted && section == 0 {
-            let cell: ActionCell
-            if let c = tableView.dequeueReusableCell(withIdentifier: "actionCell") as? ActionCell {
-                cell = c
-            } else {
-                cell = ActionCell(style: .default, reuseIdentifier: "actionCell")
-            }
-            cell.actionTitle = String.localized("import_contacts")
-            return cell
-        } else {
-
-            let cell: ContactCell
-            if let c = tableView.dequeueReusableCell(withIdentifier: contactCellReuseIdentifier) as? ContactCell {
-                cell = c
-            } else {
-                cell = ContactCell(style: .subtitle, reuseIdentifier: contactCellReuseIdentifier)
-            }
-            let row = indexPath.row
-            let contactRow = row
-
-            if contactRow < contactIds.count {
-                let contact: ContactWithSearchResults = isFiltering() ? filteredContacts[contactRow] : contacts[contactRow]
-                updateContactCell(cell: cell, contactWithHighlight: contact)
-                cell.selectionStyle = .none
-
-                cell.setVerified(isVerified: contact.contact.isVerified)
-            }
-            return cell
-        }
-    }
-
-    override func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
-        if !deviceContactAccessGranted && indexPath.section == 0 {
-            showSettingsAlert()
-        } else {
-            let contact = contactByIndexPath(indexPath)
-            let contactId = contact.contact.id
-            let chatId = dc_create_chat_by_contact_id(mailboxPointer, UInt32(contactId))
-
-            if searchController.isActive {
-                searchController.dismiss(animated: false) {
-                    self.coordinator?.showChat(chatId: Int(chatId))
-                }
-            } else {
-                self.coordinator?.showChat(chatId: Int(chatId))
-            }
-        }
-    }
-
-    override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
-        let contactId = contactByIndexPath(indexPath).contact.id
-
-        // assigning swipe by delete to chats
-        let edit = UITableViewRowAction(style: .default, title: String.localized("global_menu_edit_desktop")) { [unowned self] _, _ in
-            if self.searchController.isActive {
-                self.searchController.dismiss(animated: false) {
-                    self.coordinator?.showContactDetail(contactId: contactId)
-                }
-            } else {
-                self.coordinator?.showContactDetail(contactId: contactId)
-            }
-        }
-        edit.backgroundColor = DcColors.primary
-        return [edit]
-    }
-
-    @objc func newContactButtonPressed() {
-        coordinator?.showNewContactController()
-    }
-
-    private func updateContactCell(cell: ContactCell, contactWithHighlight: ContactWithSearchResults) {
-        let contact = contactWithHighlight.contact
-        let displayName = contact.displayName
-
-        if let nameHighlightedIndexes = contactWithHighlight.indexesToHighlight.filter({ $0.contactDetail == .NAME }).first,
-            let emailHighlightedIndexes = contactWithHighlight.indexesToHighlight.filter({ $0.contactDetail == .EMAIL }).first {
-            // gets here when contact is a result of current search -> highlights relevant indexes
-            let nameLabelFontSize = cell.nameLabel.font.pointSize
-            let emailLabelFontSize = cell.emailLabel.font.pointSize
-
-            cell.nameLabel.attributedText = displayName.boldAt(indexes: nameHighlightedIndexes.indexes, fontSize: nameLabelFontSize)
-            cell.emailLabel.attributedText = contact.email.boldAt(indexes: emailHighlightedIndexes.indexes, fontSize: emailLabelFontSize)
-        } else {
-            cell.nameLabel.text = displayName
-            cell.emailLabel.text = contact.email
-        }
-        cell.initialsLabel.text = Utils.getInitials(inputName: displayName)
-        cell.setColor(contact.color)
-    }
-
-    private func contactByIndexPath(_ indexPath: IndexPath) -> ContactWithSearchResults {
-        return isFiltering() ? filteredContacts[indexPath.row] : contacts[indexPath.row]
-    }
-}
-
-extension ContactListController: ContactListDelegate {
-    func deviceContactsImported() {
-        contactIds = Utils.getContactIds()
-    }
-
-    func accessGranted() {
-        deviceContactAccessGranted = true
-    }
-
-    func accessDenied() {
-        deviceContactAccessGranted = false
-        getContactIds()
-    }
-
-    private func showSettingsAlert() {
-        let alert = UIAlertController(
-            title: String.localized("import_contacts"),
-            message: String.localized("import_contacts_message"),
-            preferredStyle: .alert
-        )
-        alert.addAction(UIAlertAction(title: String.localized("menu_settings"), style: .default) { _ in
-            UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
-        })
-        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel) { _ in
-        })
-        present(alert, animated: true)
-    }
-}
-
-extension ContactListController: UISearchResultsUpdating {
-    func updateSearchResults(for searchController: UISearchController) {
-        if let searchText = searchController.searchBar.text {
-            filterContentForSearchText(searchText)
-        }
-    }
-}

+ 59 - 3
deltachat-ios/Controller/NewChatViewController.swift

@@ -200,7 +200,7 @@ class NewChatViewController: UITableViewController {
                 } else {
                 } else {
                     cell = ContactCell(style: .default, reuseIdentifier: "contactCell")
                     cell = ContactCell(style: .default, reuseIdentifier: "contactCell")
                 }
                 }
-                let contact: ContactWithSearchResults = isFiltering() ? filteredContacts[row] : contacts[row]
+                let contact: ContactWithSearchResults = contactSearchResultByRow(row)
                 updateContactCell(cell: cell, contactWithHighlight: contact)
                 updateContactCell(cell: cell, contactWithHighlight: contact)
                 return cell
                 return cell
             } else {
             } else {
@@ -222,7 +222,7 @@ class NewChatViewController: UITableViewController {
                 cell = ContactCell(style: .default, reuseIdentifier: "contactCell")
                 cell = ContactCell(style: .default, reuseIdentifier: "contactCell")
             }
             }
 
 
-            let contact: ContactWithSearchResults = isFiltering() ? filteredContacts[row] : contacts[row]
+            let contact: ContactWithSearchResults = contactSearchResultByRow(row)
             updateContactCell(cell: cell, contactWithHighlight: contact)
             updateContactCell(cell: cell, contactWithHighlight: contact)
             return cell
             return cell
         }
         }
@@ -263,6 +263,61 @@ class NewChatViewController: UITableViewController {
         }
         }
     }
     }
 
 
+    override func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
+        let contactId = contactIdByRow(indexPath.row)
+
+        let edit = UITableViewRowAction(style: .normal, title: String.localized("global_menu_edit_desktop")) { [unowned self] _, _ in
+            if self.searchController.isActive {
+                self.searchController.dismiss(animated: false) {
+                    self.coordinator?.showContactDetail(contactId: contactId)
+                }
+            } else {
+                self.coordinator?.showContactDetail(contactId: contactId)
+            }
+        }
+
+        let delete = UITableViewRowAction(style: .destructive, title: String.localized("delete")) { [unowned self] _, _ in
+            //handle delete
+            if let dcContext = self.coordinator?.dcContext {
+                let contactId = self.contactIdByRow(indexPath.row)
+                self.askToDeleteContact(contactId: contactId, context: dcContext)
+            }
+        }
+
+        edit.backgroundColor = DcColors.primary
+        return [edit, delete]
+    }
+
+    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
+        return true
+    }
+
+    private func contactIdByRow(_ row: Int) -> Int {
+        return isFiltering() ? filteredContacts[row].contact.id : contactIds[row]
+    }
+
+    private func contactSearchResultByRow(_ row: Int) -> ContactWithSearchResults {
+        return isFiltering() ? filteredContacts[row] : contacts[row]
+    }
+
+    private func askToDeleteContact(contactId: Int, context: DcContext) {
+        let contact = DcContact(id: contactId)
+        let alert = UIAlertController(title: String.localized("delete"),
+                                      message: String.localizedStringWithFormat(String.localized("delete_contact"), contact.nameNAddr),
+                                      preferredStyle: .alert)
+        alert.addAction(UIAlertAction(title: String.localized("ok"), style: .default, handler: { _ in
+            self.dismiss(animated: true, completion: nil)
+            if context.deleteContact(contactId: contactId) {
+                self.contactIds = Utils.getContactIds()
+                self.tableView.reloadData()
+            }
+        }))
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: { _ in
+            self.dismiss(animated: true, completion: nil)
+        }))
+        present(alert, animated: true, completion: nil)
+    }
+
     private func askToChatWith(contactId: Int) {
     private func askToChatWith(contactId: Int) {
         let dcContact = DcContact(id: contactId)
         let dcContact = DcContact(id: contactId)
         let alert = UIAlertController(title: String.localizedStringWithFormat(String.localized("ask_start_chat_with"), dcContact.nameNAddr),
         let alert = UIAlertController(title: String.localizedStringWithFormat(String.localized("ask_start_chat_with"), dcContact.nameNAddr),
@@ -281,7 +336,7 @@ class NewChatViewController: UITableViewController {
     private func showChatAt(row: Int) {
     private func showChatAt(row: Int) {
         if searchController.isActive {
         if searchController.isActive {
             // edge case: when searchController is active but searchBar is empty -> filteredContacts is empty, so we fallback to contactIds
             // edge case: when searchController is active but searchBar is empty -> filteredContacts is empty, so we fallback to contactIds
-            let contactId = isFiltering() ? filteredContacts[row].contact.id : contactIds[row]
+            let contactId = contactIdByRow(row)
             searchController.dismiss(animated: false, completion: {
             searchController.dismiss(animated: false, completion: {
                 self.askToChatWith(contactId: contactId)
                 self.askToChatWith(contactId: contactId)
             })
             })
@@ -300,6 +355,7 @@ class NewChatViewController: UITableViewController {
 
 
         cell.initialsLabel.text = Utils.getInitials(inputName: displayName)
         cell.initialsLabel.text = Utils.getInitials(inputName: displayName)
         cell.setColor(contact.color)
         cell.setColor(contact.color)
+        cell.setVerified(isVerified: contact.isVerified)
 
 
         if let emailHighlightedIndexes = contactWithHighlight.indexesToHighlight.filter({ $0.contactDetail == .EMAIL }).first {
         if let emailHighlightedIndexes = contactWithHighlight.indexesToHighlight.filter({ $0.contactDetail == .EMAIL }).first {
             // gets here when contact is a result of current search -> highlights relevant indexes
             // gets here when contact is a result of current search -> highlights relevant indexes

+ 22 - 59
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -6,6 +6,10 @@ import MobileCoreServices
 class AppCoordinator: NSObject, Coordinator {
 class AppCoordinator: NSObject, Coordinator {
     private let window: UIWindow
     private let window: UIWindow
     private let dcContext: DcContext
     private let dcContext: DcContext
+    private let mailboxTab = 0
+    private let profileTab = 1
+    private let chatsTab = 2
+    private let settingsTab = 3
 
 
     var rootViewController: UIViewController {
     var rootViewController: UIViewController {
         return tabBarController
         return tabBarController
@@ -15,7 +19,7 @@ class AppCoordinator: NSObject, Coordinator {
 
 
     private lazy var tabBarController: UITabBarController = {
     private lazy var tabBarController: UITabBarController = {
         let tabBarController = UITabBarController()
         let tabBarController = UITabBarController()
-        tabBarController.viewControllers = [contactListController, mailboxController, profileController, chatListController, settingsController]
+        tabBarController.viewControllers = [mailboxController, profileController, chatListController, settingsController]
         // put viewControllers here
         // put viewControllers here
         tabBarController.delegate = self
         tabBarController.delegate = self
         tabBarController.tabBar.tintColor = DcColors.primary
         tabBarController.tabBar.tintColor = DcColors.primary
@@ -25,23 +29,12 @@ class AppCoordinator: NSObject, Coordinator {
 
 
     // MARK: viewControllers
     // MARK: viewControllers
 
 
-    private lazy var contactListController: UIViewController = {
-        let controller = ContactListController()
-        let nav = DcNavigationController(rootViewController: controller)
-        let settingsImage = UIImage(named: "contacts")
-        nav.tabBarItem = UITabBarItem(title: String.localized("contacts_title"), image: settingsImage, tag: 0)
-        let coordinator = ContactListCoordinator(dcContext: dcContext, navigationController: nav)
-        self.childCoordinators.append(coordinator)
-        controller.coordinator = coordinator
-        return nav
-    }()
-
     private lazy var mailboxController: UIViewController = {
     private lazy var mailboxController: UIViewController = {
         let controller = MailboxViewController(dcContext: dcContext, chatId: Int(DC_CHAT_ID_DEADDROP), title: String.localized("menu_deaddrop"))
         let controller = MailboxViewController(dcContext: dcContext, chatId: Int(DC_CHAT_ID_DEADDROP), title: String.localized("menu_deaddrop"))
         controller.disableWriting = true
         controller.disableWriting = true
         let nav = DcNavigationController(rootViewController: controller)
         let nav = DcNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "message")
         let settingsImage = UIImage(named: "message")
-        nav.tabBarItem = UITabBarItem(title: String.localized("menu_deaddrop"), image: settingsImage, tag: 1)
+        nav.tabBarItem = UITabBarItem(title: String.localized("menu_deaddrop"), image: settingsImage, tag: mailboxTab)
         let coordinator = MailboxCoordinator(dcContext: dcContext, navigationController: nav)
         let coordinator = MailboxCoordinator(dcContext: dcContext, navigationController: nav)
         self.childCoordinators.append(coordinator)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
         controller.coordinator = coordinator
@@ -52,7 +45,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = NewProfileViewController(dcContext: dcContext)
         let controller = NewProfileViewController(dcContext: dcContext)
         let nav = DcNavigationController(rootViewController: controller)
         let nav = DcNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "report_card")
         let settingsImage = UIImage(named: "report_card")
-        nav.tabBarItem = UITabBarItem(title: String.localized("pref_profile_info_headline"), image: settingsImage, tag: 2)
+        nav.tabBarItem = UITabBarItem(title: String.localized("pref_profile_info_headline"), image: settingsImage, tag: profileTab)
         let coordinator = ProfileCoordinator(navigationController: nav)
         let coordinator = ProfileCoordinator(navigationController: nav)
         self.childCoordinators.append(coordinator)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
         controller.coordinator = coordinator
@@ -63,7 +56,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = ChatListController(dcContext: dcContext, showArchive: false)
         let controller = ChatListController(dcContext: dcContext, showArchive: false)
         let nav = DcNavigationController(rootViewController: controller)
         let nav = DcNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "chat")
         let settingsImage = UIImage(named: "chat")
-        nav.tabBarItem = UITabBarItem(title: String.localized("pref_chats"), image: settingsImage, tag: 3)
+        nav.tabBarItem = UITabBarItem(title: String.localized("pref_chats"), image: settingsImage, tag: chatsTab)
         let coordinator = ChatListCoordinator(dcContext: dcContext, navigationController: nav)
         let coordinator = ChatListCoordinator(dcContext: dcContext, navigationController: nav)
         self.childCoordinators.append(coordinator)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
         controller.coordinator = coordinator
@@ -74,7 +67,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = SettingsViewController()
         let controller = SettingsViewController()
         let nav = DcNavigationController(rootViewController: controller)
         let nav = DcNavigationController(rootViewController: controller)
         let settingsImage = UIImage(named: "settings")
         let settingsImage = UIImage(named: "settings")
-        nav.tabBarItem = UITabBarItem(title: String.localized("menu_settings"), image: settingsImage, tag: 4)
+        nav.tabBarItem = UITabBarItem(title: String.localized("menu_settings"), image: settingsImage, tag: settingsTab)
         let coordinator = SettingsCoordinator(navigationController: nav)
         let coordinator = SettingsCoordinator(navigationController: nav)
         self.childCoordinators.append(coordinator)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
         controller.coordinator = coordinator
@@ -91,7 +84,7 @@ class AppCoordinator: NSObject, Coordinator {
 
 
     public func start() {
     public func start() {
         print(tabBarController.selectedIndex)
         print(tabBarController.selectedIndex)
-        showTab(index: 3)
+        showTab(index: chatsTab)
     }
     }
 
 
     func showTab(index: Int) {
     func showTab(index: Int) {
@@ -99,7 +92,7 @@ class AppCoordinator: NSObject, Coordinator {
     }
     }
 
 
     func showChat(chatId: Int) {
     func showChat(chatId: Int) {
-        showTab(index: 3)
+        showTab(index: chatsTab)
         guard let navController = self.chatListController as? UINavigationController else {
         guard let navController = self.chatListController as? UINavigationController else {
             assertionFailure("huh? why no nav controller?")
             assertionFailure("huh? why no nav controller?")
             return
             return
@@ -124,9 +117,9 @@ extension AppCoordinator: UITabBarControllerDelegate {
     func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
     func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
         if let dcNav = viewController as? DcNavigationController {
         if let dcNav = viewController as? DcNavigationController {
             switch tabBarController.selectedIndex {
             switch tabBarController.selectedIndex {
-            case 0, 3, 4:
+            case chatsTab, settingsTab:
                 dcNav.navigationBar.prefersLargeTitles = true
                 dcNav.navigationBar.prefersLargeTitles = true
-            case 1, 2:
+            case mailboxTab, profileTab:
                 dcNav.navigationBar.prefersLargeTitles = false
                 dcNav.navigationBar.prefersLargeTitles = false
             default:
             default:
                 // should never get here
                 // should never get here
@@ -136,45 +129,6 @@ extension AppCoordinator: UITabBarControllerDelegate {
     }
     }
 }
 }
 
 
-
-class ContactListCoordinator: Coordinator {
-    var dcContext: DcContext
-    let navigationController: UINavigationController
-
-    var childCoordinators: [Coordinator] = []
-
-    init(dcContext: DcContext, navigationController: UINavigationController) {
-        self.dcContext = dcContext
-        self.navigationController = navigationController
-    }
-
-    func showContactDetail(contactId: Int) {
-        let contactDetailController = ContactDetailViewController(contactId: contactId)
-        contactDetailController.showChatCell = true
-        let coordinator = ContactDetailCoordinator(dcContext: dcContext, navigationController: navigationController)
-        childCoordinators.append(coordinator)
-        contactDetailController.coordinator = coordinator
-        navigationController.pushViewController(contactDetailController, animated: true)
-    }
-
-    func showChat(chatId: Int) {
-        let chatVC = ChatViewController(dcContext: dcContext, chatId: chatId)
-        let coordinator = ChatViewCoordinator(dcContext: dcContext, navigationController: navigationController, chatId: chatId)
-        childCoordinators.append(coordinator)
-        chatVC.coordinator = coordinator
-        navigationController.pushViewController(chatVC, animated: true)
-    }
-
-    func showNewContactController() {
-        let newContactController = NewContactController()
-        let coordinator = EditContactCoordinator(dcContext: dcContext, navigationController: navigationController)
-        childCoordinators.append(coordinator)
-        newContactController.coordinator = coordinator
-        newContactController.hidesBottomBarWhenPushed = true
-        navigationController.pushViewController(newContactController, animated: true)
-    }
-}
-
 // since mailbox and chatView -tab both use ChatViewController we want to be able to assign different functionality via coordinators -> therefore we override unneeded functions such as showChatDetail -> maybe find better solution in longterm
 // since mailbox and chatView -tab both use ChatViewController we want to be able to assign different functionality via coordinators -> therefore we override unneeded functions such as showChatDetail -> maybe find better solution in longterm
 class MailboxCoordinator: ChatViewCoordinator {
 class MailboxCoordinator: ChatViewCoordinator {
 
 
@@ -384,6 +338,15 @@ class NewChatCoordinator: Coordinator {
         navigationController.pushViewController(chatViewController, animated: true)
         navigationController.pushViewController(chatViewController, animated: true)
         navigationController.viewControllers.remove(at: 1)
         navigationController.viewControllers.remove(at: 1)
     }
     }
+
+    func showContactDetail(contactId: Int) {
+        let contactDetailController = ContactDetailViewController(contactId: contactId)
+        contactDetailController.showChatCell = true
+        let coordinator = ContactDetailCoordinator(dcContext: dcContext, navigationController: navigationController)
+        childCoordinators.append(coordinator)
+        contactDetailController.coordinator = coordinator
+        navigationController.pushViewController(contactDetailController, animated: true)
+    }
 }
 }
 
 
 class GroupChatDetailCoordinator: Coordinator {
 class GroupChatDetailCoordinator: Coordinator {

+ 4 - 0
deltachat-ios/DC/Wrapper.swift

@@ -13,6 +13,10 @@ class DcContext {
         dc_context_unref(contextPointer)
         dc_context_unref(contextPointer)
     }
     }
 
 
+    func deleteContact(contactId: Int) -> Bool {
+        return dc_delete_contact(self.contextPointer, UInt32(contactId)) == 1
+    }
+
     func getChatlist(flags: Int32, queryString: String?, queryId: Int) -> DcChatlist {
     func getChatlist(flags: Int32, queryString: String?, queryId: Int) -> DcChatlist {
         let chatlistPointer = dc_get_chatlist(contextPointer, flags, queryString, UInt32(queryId))
         let chatlistPointer = dc_get_chatlist(contextPointer, flags, queryString, UInt32(queryId))
         let chatlist = DcChatlist(chatListPointer: chatlistPointer)
         let chatlist = DcChatlist(chatListPointer: chatlistPointer)

+ 3 - 0
deltachat-ios/en.lproj/Localizable.strings

@@ -500,6 +500,9 @@
 // dc_str_* resources
 // dc_str_* resources
 "encrypted_message" = "Encrypted message";
 "encrypted_message" = "Encrypted message";
 
 
+// iOS specific strings
+"delete_contact" = "Permanently delete contact %1$@?\n\nContacts with ongoing chats and contacts from the system\'s address book cannot be deleted permanently.";
+
 // desktop specific strings
 // desktop specific strings
 "welcome_desktop" = "Welcome to DeltaChat";
 "welcome_desktop" = "Welcome to DeltaChat";
 "login_known_accounts_title_desktop" = "Known accounts";
 "login_known_accounts_title_desktop" = "Known accounts";

+ 4 - 4
deltachat-ios/tr.lproj/Localizable.strings

@@ -198,7 +198,7 @@
 // search
 // search
 "search" = "Ara";
 "search" = "Ara";
 "search_explain" = "Sohbetleri, kişileri ve iletileri ara";
 "search_explain" = "Sohbetleri, kişileri ve iletileri ara";
-"search_no_result_for_x" = "\"%s\" için sonuç bulunamadı";
+"search_no_result_for_x" = "\"%s\" için hiç sonuç bulunmadı";
 
 
 
 
 // create/edit groups, contact/group profile
 // create/edit groups, contact/group profile
@@ -361,7 +361,7 @@
 "pref_other" = "Diğer";
 "pref_other" = "Diğer";
 "pref_backup" = "Yedekleme";
 "pref_backup" = "Yedekleme";
 "pref_backup_explain" = "Sohbetleri dış depolamaya yedekle";
 "pref_backup_explain" = "Sohbetleri dış depolamaya yedekle";
-"pref_backup_export_explain" = "Bir yedek, bu ya da başka bir aygıtta yeni bir kurulum ayarlamak için size yardım eder.\n\nYedek, tüm iletileri, kişileri ve sohbetleri ve uçtan uca Autocrypt ayarlamanızı içerecek. Yedek dosyasını güvenli bir yerde tutun ya da olanaklıysa en kısa sürede silin.";
+"pref_backup_export_explain" = "Bir yedek, bu ya da başka bir aygıtta yeni bir kurulum ayarlamanıza yardım eder.\n\nYedek, tüm iletileri, kişileri ve sohbetleri ve uçtan uca Autocrypt ayarlamanızı içerecek. Yedek dosyasını güvenli bir yerde tutun ya da olanaklıysa en kısa sürede silin.";
 "pref_backup_export_start_button" = "Yedeklemeye başla";
 "pref_backup_export_start_button" = "Yedeklemeye başla";
 "pref_backup_written_to_x" = "Yedek %1$@ üzerine başarıyla yazıldı";
 "pref_backup_written_to_x" = "Yedek %1$@ üzerine başarıyla yazıldı";
 "pref_managekeys_menu_title" = "Anahtarları yönet";
 "pref_managekeys_menu_title" = "Anahtarları yönet";
@@ -457,8 +457,8 @@
 "qrshow_join_group_hint" = "\"%1$@\" grubuna katılmak için bunu tarayın.";
 "qrshow_join_group_hint" = "\"%1$@\" grubuna katılmak için bunu tarayın.";
 "qrshow_join_contact_title" = "QR davet kodu";
 "qrshow_join_contact_title" = "QR davet kodu";
 "qrshow_join_contact_hint" = "%1$@ ile bir iletişim ayarlamak için bunu tarayın";
 "qrshow_join_contact_hint" = "%1$@ ile bir iletişim ayarlamak için bunu tarayın";
-"qrshow_join_contact_no_connection_hint" = "QR kodu ayarlaması bir internet bağlantısı gerektirir. İşlemden önce lütfen bir ağa bağlanın.";
-"qrshow_join_contact_no_connection_toast" = "İnternet bağlantısı yok, QR kodu ayarlaması gerçekleştirilemiyor.";
+"qrshow_join_contact_no_connection_hint" = "QR kodu ayarlaması bir Internet bağlantısı gerektirir. İşlemden önce lütfen bir ağa bağlanın.";
+"qrshow_join_contact_no_connection_toast" = "Internet bağlantısı yok, QR kodu ayarlaması gerçekleştirilemiyor.";
 "contact_verified" = "%1$@ doğrulandı.";
 "contact_verified" = "%1$@ doğrulandı.";
 "contact_not_verified" = "%1$@ doğrulanamıyor";
 "contact_not_verified" = "%1$@ doğrulanamıyor";
 // translators: "setup" is the "encryption setup" here, as in "Autocrypt Setup Message"
 // translators: "setup" is the "encryption setup" here, as in "Autocrypt Setup Message"