Prechádzať zdrojové kódy

Merge pull request #246 from deltachat/remove_contact_tab

remove contacts tab
björn petersen 5 rokov pred
rodič
commit
f2b3287d4c

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

@@ -26,7 +26,6 @@
 		78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3921D3CFBC00D4B15E /* SettingsController.swift */; };
 		78E45E3C21D3D03700D4B15E /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3B21D3D03700D4B15E /* TextFieldTableViewCell.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 */; };
 		78E45E4C21D404AE00D4B15E /* CustomMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4B21D404AE00D4B15E /* CustomMessageCell.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>"; };
 		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>"; };
-		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>"; };
 		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>"; };
@@ -359,7 +357,6 @@
 				7092474020B3869500AF8799 /* ContactDetailViewController.swift */,
 				7AE0A5481FC42F65005ECB4B /* NewChatViewController.swift */,
 				AE0D26FC1FB1FE88002FAFCE /* ChatListController.swift */,
-				78E45E3F21D3D70700D4B15E /* ContactListController.swift */,
 				78ED838E21D5927A00243125 /* ProfileViewController.swift */,
 				30149D9222F21129003C12B5 /* NewProfileViewController.swift */,
 				78E45E3921D3CFBC00D4B15E /* SettingsController.swift */,
@@ -724,7 +721,6 @@
 				70B08FCD21073B910097D3EA /* NewGroupMemberChoiceController.swift in Sources */,
 				30BD261422F8679200F399DF /* ProfileView.swift in Sources */,
 				78E45E3E21D3D28C00D4B15E /* DcNavigationController.swift in Sources */,
-				78E45E4021D3D70700D4B15E /* ContactListController.swift in Sources */,
 				AE18F294228C602A0007B1BE /* SecuritySettingsController.swift in Sources */,
 				78ED838D21D577D000243125 /* events.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 {
                     cell = ContactCell(style: .default, reuseIdentifier: "contactCell")
                 }
-                let contact: ContactWithSearchResults = isFiltering() ? filteredContacts[row] : contacts[row]
+                let contact: ContactWithSearchResults = contactSearchResultByRow(row)
                 updateContactCell(cell: cell, contactWithHighlight: contact)
                 return cell
             } else {
@@ -222,7 +222,7 @@ class NewChatViewController: UITableViewController {
                 cell = ContactCell(style: .default, reuseIdentifier: "contactCell")
             }
 
-            let contact: ContactWithSearchResults = isFiltering() ? filteredContacts[row] : contacts[row]
+            let contact: ContactWithSearchResults = contactSearchResultByRow(row)
             updateContactCell(cell: cell, contactWithHighlight: contact)
             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) {
         let dcContact = DcContact(id: contactId)
         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) {
         if searchController.isActive {
             // 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: {
                 self.askToChatWith(contactId: contactId)
             })
@@ -300,6 +355,7 @@ class NewChatViewController: UITableViewController {
 
         cell.initialsLabel.text = Utils.getInitials(inputName: displayName)
         cell.setColor(contact.color)
+        cell.setVerified(isVerified: contact.isVerified)
 
         if let emailHighlightedIndexes = contactWithHighlight.indexesToHighlight.filter({ $0.contactDetail == .EMAIL }).first {
             // 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 {
     private let window: UIWindow
     private let dcContext: DcContext
+    private let mailboxTab = 0
+    private let profileTab = 1
+    private let chatsTab = 2
+    private let settingsTab = 3
 
     var rootViewController: UIViewController {
         return tabBarController
@@ -15,7 +19,7 @@ class AppCoordinator: NSObject, Coordinator {
 
     private lazy var tabBarController: UITabBarController = {
         let tabBarController = UITabBarController()
-        tabBarController.viewControllers = [contactListController, mailboxController, profileController, chatListController, settingsController]
+        tabBarController.viewControllers = [mailboxController, profileController, chatListController, settingsController]
         // put viewControllers here
         tabBarController.delegate = self
         tabBarController.tabBar.tintColor = DcColors.primary
@@ -25,23 +29,12 @@ class AppCoordinator: NSObject, Coordinator {
 
     // 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 = {
         let controller = MailboxViewController(dcContext: dcContext, chatId: Int(DC_CHAT_ID_DEADDROP), title: String.localized("menu_deaddrop"))
         controller.disableWriting = true
         let nav = DcNavigationController(rootViewController: controller)
         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)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -52,7 +45,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = NewProfileViewController(dcContext: dcContext)
         let nav = DcNavigationController(rootViewController: controller)
         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)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -63,7 +56,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = ChatListController(dcContext: dcContext, showArchive: false)
         let nav = DcNavigationController(rootViewController: controller)
         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)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -74,7 +67,7 @@ class AppCoordinator: NSObject, Coordinator {
         let controller = SettingsViewController()
         let nav = DcNavigationController(rootViewController: controller)
         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)
         self.childCoordinators.append(coordinator)
         controller.coordinator = coordinator
@@ -91,7 +84,7 @@ class AppCoordinator: NSObject, Coordinator {
 
     public func start() {
         print(tabBarController.selectedIndex)
-        showTab(index: 3)
+        showTab(index: chatsTab)
     }
 
     func showTab(index: Int) {
@@ -99,7 +92,7 @@ class AppCoordinator: NSObject, Coordinator {
     }
 
     func showChat(chatId: Int) {
-        showTab(index: 3)
+        showTab(index: chatsTab)
         guard let navController = self.chatListController as? UINavigationController else {
             assertionFailure("huh? why no nav controller?")
             return
@@ -124,9 +117,9 @@ extension AppCoordinator: UITabBarControllerDelegate {
     func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
         if let dcNav = viewController as? DcNavigationController {
             switch tabBarController.selectedIndex {
-            case 0, 3, 4:
+            case chatsTab, settingsTab:
                 dcNav.navigationBar.prefersLargeTitles = true
-            case 1, 2:
+            case mailboxTab, profileTab:
                 dcNav.navigationBar.prefersLargeTitles = false
             default:
                 // 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
 class MailboxCoordinator: ChatViewCoordinator {
 
@@ -384,6 +338,15 @@ class NewChatCoordinator: Coordinator {
         navigationController.pushViewController(chatViewController, animated: true)
         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 {

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

@@ -13,6 +13,10 @@ class DcContext {
         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 {
         let chatlistPointer = dc_get_chatlist(contextPointer, flags, queryString, UInt32(queryId))
         let chatlist = DcChatlist(chatListPointer: chatlistPointer)

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

@@ -500,6 +500,9 @@
 // dc_str_* resources
 "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
 "welcome_desktop" = "Welcome to DeltaChat";
 "login_known_accounts_title_desktop" = "Known accounts";

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

@@ -198,7 +198,7 @@
 // search
 "search" = "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
@@ -361,7 +361,7 @@
 "pref_other" = "Diğer";
 "pref_backup" = "Yedekleme";
 "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_written_to_x" = "Yedek %1$@ üzerine başarıyla yazıldı";
 "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_contact_title" = "QR davet kodu";
 "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_not_verified" = "%1$@ doğrulanamıyor";
 // translators: "setup" is the "encryption setup" here, as in "Autocrypt Setup Message"