Преглед на файлове

Merge pull request #297 from deltachat/new_contact_in_add_members_context

New contact in add members context
björn petersen преди 5 години
родител
ревизия
84b0db9135

+ 115 - 14
deltachat-ios/Controller/GroupMembersViewController.swift

@@ -28,7 +28,12 @@ class NewGroupViewController: GroupMembersViewController {
 }
 
 class AddGroupMembersViewController: GroupMembersViewController {
+    weak var coordinator: AddGroupMembersCoordinator?
     private var chatId: Int?
+    private let sectionNewContact = 0
+    private let sectionMemberList = 1
+
+    private var contactAddedObserver: NSObjectProtocol?
 
     private lazy var resetButton: UIBarButtonItem = {
         let button = UIBarButtonItem(title: String.localized("reset"), style: .plain, target: self, action: #selector(resetButtonPressed))
@@ -56,17 +61,11 @@ class AddGroupMembersViewController: GroupMembersViewController {
         return []
     }()
 
-    private lazy var memberCandidateIds: [Int] = {
-        var contactIds = Set(Utils.getContactIds()) // turn into set to speed up search
-        for member in chatMemberIds {
-            contactIds.remove(member)
-        }
-        return Array(contactIds)
-    }()
-
     init(chatId: Int) {
         super.init()
         self.chatId = chatId
+        numberOfSections = 2
+
     }
 
     required init?(coder _: NSCoder) {
@@ -75,25 +74,111 @@ class AddGroupMembersViewController: GroupMembersViewController {
 
     override func viewDidLoad() {
         super.viewDidLoad()
-        super.contactIds = memberCandidateIds
+
         super.navigationItem.rightBarButtonItem = resetButton
         title = String.localized("group_add_members")
+        super.contactIds = loadMemberCandidates()
         // Do any additional setup after loading the view.
+        let nc = NotificationCenter.default
+        contactAddedObserver = nc.addObserver(
+            forName: dcNotificationContactChanged,
+            object: nil,
+            queue: nil
+        ) { notification in
+            if let ui = notification.userInfo {
+                if let contactId = ui["contact_id"] as? Int {
+                    if contactId == 0 {
+                        return
+                    }
+                    self.contactIds = self.loadMemberCandidates()
+                    if self.contactIds.contains(contactId) {
+                        self.selectedContactIds.insert(contactId)
+                        self.tableView.reloadData()
+                    }
+
+                }
+            }
+        }
     }
 
     override func viewWillDisappear(_: Bool) {
+        if !isMovingFromParent {
+            // a subview was added to the navigation stack, no action needed
+            return
+        }
         guard let chatId = chatId else {
             return
         }
         for contactId in selectedContactIds {
             dc_add_contact_to_chat(mailboxPointer, UInt32(chatId), UInt32(contactId))
         }
+
+        let nc = NotificationCenter.default
+        if let observer = self.contactAddedObserver {
+            nc.removeObserver(observer)
+        }
+    }
+
+    override func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
+        switch section {
+        case sectionNewContact:
+            return 1
+        case sectionMemberList:
+            return getNumberOfRowsForContactList()
+        default:
+            return 0
+        }
+    }
+
+    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        switch indexPath.section {
+        case sectionNewContact:
+            return getNewContactCell()
+        case sectionMemberList:
+            return getContactCell(cellForRowAt: indexPath)
+        default:
+            return UITableViewCell(style: .default, reuseIdentifier: nil)
+        }
+    }
+
+    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        switch indexPath.section {
+        case sectionNewContact:
+            tableView.deselectRow(at: indexPath, animated: true)
+            coordinator?.showNewContactController()
+        case sectionMemberList:
+            didSelectContactCell(at: indexPath)
+        default:
+            fatalError("unexpected section selected in GroupMembersViewController")
+        }
+    }
+
+    func loadMemberCandidates() -> [Int] {
+        var contactIds = Set(Utils.getContactIds()) // turn into set to speed up search
+        for member in chatMemberIds {
+            contactIds.remove(member)
+        }
+        return Array(contactIds)
     }
 
     @objc func resetButtonPressed() {
         selectedContactIds = []
         tableView.reloadData()
     }
+
+    func getNewContactCell() -> UITableViewCell {
+        let cell: UITableViewCell
+        if let c = tableView.dequeueReusableCell(withIdentifier: "actionCell") {
+            cell = c
+        } else {
+            cell = UITableViewCell(style: .default, reuseIdentifier: "actionCell")
+        }
+        cell.textLabel?.text = String.localized("menu_new_contact")
+        cell.textLabel?.textColor = view.tintColor
+        cell.textLabel?.textAlignment = .center
+
+        return cell
+    }
 }
 
 class BlockedContactsViewController: GroupMembersViewController, GroupMemberSelectionDelegate {
@@ -149,6 +234,7 @@ class GroupMembersViewController: UITableViewController, UISearchResultsUpdating
     let contactCellReuseIdentifier = "contactCell"
     weak var groupMemberSelectionDelegate: GroupMemberSelectionDelegate?
     var enableCheckmarks = true
+    var numberOfSections = 1
 
     var contactIds: [Int] = [] {
         didSet {
@@ -193,7 +279,7 @@ class GroupMembersViewController: UITableViewController, UISearchResultsUpdating
     var selectedContactIds: Set<Int> = []
 
     init() {
-        super.init(nibName: nil, bundle: nil)
+        super.init(style: .grouped)
         hidesBottomBarWhenPushed = true
     }
 
@@ -204,19 +290,34 @@ class GroupMembersViewController: UITableViewController, UISearchResultsUpdating
     override func viewDidLoad() {
         tableView.register(ContactCell.self, forCellReuseIdentifier: contactCellReuseIdentifier)
         navigationItem.searchController = searchController
-        navigationItem.hidesSearchBarWhenScrolling = false
+        if #available(iOS 11.0, *) {
+            navigationItem.hidesSearchBarWhenScrolling = false
+        }
         definesPresentationContext = true
     }
 
     override func numberOfSections(in _: UITableView) -> Int {
-        return 1
+        return numberOfSections
     }
 
     override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
-        return isFiltering() ? filteredContacts.count : contacts.count
+        return getNumberOfRowsForContactList()
     }
 
+
     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        return getContactCell(cellForRowAt: indexPath)
+    }
+
+    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+        didSelectContactCell(at: indexPath)
+    }
+
+    func getNumberOfRowsForContactList() -> Int {
+        return isFiltering() ? filteredContacts.count : contacts.count
+    }
+
+    func getContactCell(cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         guard let cell: ContactCell = tableView.dequeueReusableCell(withIdentifier: contactCellReuseIdentifier, for: indexPath) as? ContactCell else {
             fatalError("shouldn't happen")
         }
@@ -229,7 +330,7 @@ class GroupMembersViewController: UITableViewController, UISearchResultsUpdating
         return cell
     }
 
-    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+    func didSelectContactCell(at indexPath: IndexPath) {
         let row = indexPath.row
         if let cell = tableView.cellForRow(at: indexPath) {
             tableView.deselectRow(at: indexPath, animated: true)

+ 6 - 1
deltachat-ios/Controller/NewContactController.swift

@@ -3,6 +3,7 @@ import UIKit
 class NewContactController: UITableViewController {
 
     weak var coordinator: EditContactCoordinatorProtocol?
+    var openChatOnSave = true
 
     let emailCell = TextFieldCell.makeEmailCell()
     let nameCell = TextFieldCell.makeNameCell()
@@ -75,7 +76,11 @@ class NewContactController: UITableViewController {
     @objc func saveContactButtonPressed() {
         let contactId = dc_create_contact(mailboxPointer, model.name, model.email)
         let chatId = Int(dc_create_chat_by_contact_id(mailboxPointer, UInt32(contactId)))
-        coordinator?.showChat(chatId: chatId)
+        if openChatOnSave {
+            coordinator?.showChat(chatId: chatId)
+        } else {
+            coordinator?.navigateBack()
+        }
     }
 
     @objc func cancelButtonPressed() {

+ 24 - 0
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -350,6 +350,9 @@ class GroupChatDetailCoordinator: Coordinator {
 
     func showAddGroupMember(chatId: Int) {
         let groupMemberViewController = AddGroupMembersViewController(chatId: chatId)
+        let coordinator = AddGroupMembersCoordinator(dcContext: dcContext, navigationController: navigationController)
+        childCoordinators.append(coordinator)
+        groupMemberViewController.coordinator = coordinator
         navigationController.pushViewController(groupMemberViewController, animated: true)
     }
 
@@ -538,6 +541,27 @@ class NewGroupCoordinator: Coordinator {
     }
 }
 
+class AddGroupMembersCoordinator: Coordinator {
+    var dcContext: DcContext
+    let navigationController: UINavigationController
+
+    private var childCoordinators: [Coordinator] = []
+
+    init(dcContext: DcContext, navigationController: UINavigationController) {
+        self.dcContext = dcContext
+        self.navigationController = navigationController
+    }
+
+    func showNewContactController() {
+        let newContactController = NewContactController()
+        newContactController.openChatOnSave = false
+        let coordinator = EditContactCoordinator(dcContext: dcContext, navigationController: navigationController)
+        childCoordinators.append(coordinator)
+        newContactController.coordinator = coordinator
+        navigationController.pushViewController(newContactController, animated: true)
+    }
+}
+
 class GroupNameCoordinator: Coordinator {
     var dcContext: DcContext
     let navigationController: UINavigationController

+ 13 - 0
deltachat-ios/DC/events.swift

@@ -9,6 +9,7 @@ let dcNotificationConfigureProgress = Notification.Name(rawValue: "MrEventConfig
 let dcNotificationSecureJoinerProgress = Notification.Name(rawValue: "MrEventSecureJoinerProgress")
 let dcNotificationSecureInviterProgress = Notification.Name(rawValue: "MrEventSecureInviterProgress")
 let dcNotificationViewChat = Notification.Name(rawValue: "MrEventViewChat")
+let dcNotificationContactChanged = Notification.Name(rawValue: "MrEventContactsChanged")
 
 @_silgen_name("callbackSwift")
 
@@ -176,6 +177,18 @@ public func callbackSwift(event: CInt, data1: CUnsignedLong, data2: CUnsignedLon
                 ]
             )
         }
+    case DC_EVENT_CONTACTS_CHANGED:
+        logger.info("contact changed: \(data1)")
+        let nc = NotificationCenter.default
+        DispatchQueue.main.async {
+            nc.post(
+                name: dcNotificationContactChanged,
+                object: nil,
+                userInfo: [
+                    "contact_id": Int(data1)
+                ]
+            )
+        }
 
     case DC_EVENT_GET_STRING:
         var string = ""