Просмотр исходного кода

clean up groupChatDetailViewController

nayooti 5 лет назад
Родитель
Сommit
16ef00a123

+ 160 - 81
deltachat-ios/Controller/GroupChatDetailViewController.swift

@@ -2,8 +2,16 @@ import UIKit
 
 class GroupChatDetailViewController: UIViewController {
 
+    enum ProfileSections {
+        case memberManagement // add member, qr invideCode
+        case members // contactCells
+        case chatActions // archive, leave, delete
+    }
+
     weak var coordinator: GroupChatDetailCoordinator?
 
+    let sections: [ProfileSections] = [.memberManagement, .members, .chatActions]
+
     private let sectionMembers = 0
     private let sectionMembersRowAddMember = 0
     private let sectionMembersRowJoinQR = 1
@@ -15,7 +23,11 @@ class GroupChatDetailViewController: UIViewController {
     private let sectionCount = 2
 
     private var currentUser: DcContact? {
-        return groupMembers.filter { $0.email == DcConfig.addr }.first
+        let myId = groupMemberIds.filter { DcContact(id: $0).email == DcConfig.addr }.first
+        guard let currentUserId = myId else {
+            return nil
+        }
+        return DcContact(id: currentUserId)
     }
 
     fileprivate var chat: DcChat
@@ -56,6 +68,14 @@ class GroupChatDetailViewController: UIViewController {
         return cell
     }()
 
+    private lazy var leaveGroupCell: ActionCell = {
+        let cell = ActionCell()
+        cell.actionTitle = String.localized("menu_leave_group")
+        cell.actionColor = UIColor.red
+        return cell
+    }()
+
+
     private lazy var deleteChatCell: ActionCell = {
         let cell = ActionCell()
         cell.actionTitle = String.localized("menu_delete_chat")
@@ -88,7 +108,8 @@ class GroupChatDetailViewController: UIViewController {
         UIBarButtonItem(title: String.localized("global_menu_edit_desktop"), style: .plain, target: self, action: #selector(editButtonPressed))
     }()
 
-    private var groupMembers: [DcContact] = []
+    // stores contactIds
+    private var groupMemberIds: [Int] = []
 
     // MARK: -lifecycle
     override func viewDidLoad() {
@@ -109,8 +130,7 @@ class GroupChatDetailViewController: UIViewController {
 
     // MARK: -update
     private func updateGroupMembers() {
-        let ids = chat.contactIds
-        groupMembers = ids.map { DcContact(id: $0) }
+        groupMemberIds = chat.contactIds
         tableView.reloadData()
     }
 
@@ -144,89 +164,120 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
     }
 
     func numberOfSections(in _: UITableView) -> Int {
-        if currentUser == nil {
-            return sectionCount-1 // leave out last section (leaveSection)
-        }
-        return sectionCount
+        return sections.count
     }
 
     func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int {
-        switch section {
-        case sectionMembers:
-            return sectionMembersStaticRowCount + groupMembers.count
-        case sectionLeaveGroup:
-            return sectionLeaveGroupRowCount
-        default:
-            return 0
+        let sectionType = sections[section]
+        switch sectionType {
+        case .memberManagement:
+            return 2
+        case .members:
+            return groupMemberIds.count
+        case .chatActions:
+            return 3
         }
     }
 
     func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
-        let section = indexPath.section
-        let row = indexPath.row
-        switch section {
-        case sectionMembers:
-            switch row {
-            case sectionMembersRowAddMember:
-                return Constants.defaultCellHeight
-            case sectionMembersRowJoinQR:
-                return Constants.defaultCellHeight
-            default:
-                return ContactCell.cellHeight
-            }
-        case sectionLeaveGroup:
+        let sectionType = sections[indexPath.section]
+        switch sectionType {
+        case .memberManagement:
+            return Constants.defaultCellHeight
+        case .members:
+            return ContactCell.cellHeight
+        case .chatActions:
             return Constants.defaultCellHeight
-        default:
-            return 0
         }
     }
 
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
-        let section = indexPath.section
         let row = indexPath.row
-        switch section {
-        case sectionMembers:
-            switch row {
-            case sectionMembersRowAddMember:
-                let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath)
-                if let actionCell = cell as? ActionCell {
-                    actionCell.actionTitle = String.localized("group_add_members")
-                    actionCell.actionColor = UIColor.systemBlue
-                }
-                return cell
-            case sectionMembersRowJoinQR:
-                let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath)
-                if let actionCell = cell as? ActionCell {
-                    actionCell.actionTitle = String.localized("qrshow_join_group_title")
-                    actionCell.actionColor = UIColor.systemBlue
-                }
-                return cell
-            default:
-                let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath)
-                if let contactCell = cell as? ContactCell {
-                    let contact = groupMembers[row - sectionMembersStaticRowCount]
-                    let displayName = contact.displayName
-                    contactCell.titleLabel.text = displayName
-                    contactCell.subtitleLabel.text = contact.email
-                    contactCell.avatar.setName(displayName)
-                    contactCell.avatar.setColor(contact.color)
-                    if let profileImage = contact.profileImage {
-                        contactCell.avatar.setImage(profileImage)
-                    }
-                    contactCell.setVerified(isVerified: contact.isVerified)
-                }
-                return cell
+        let sectionType = sections[indexPath.section]
+        switch sectionType {
+        case .memberManagement:
+            guard let actionCell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath) as? ActionCell else {
+                safe_fatalError("could not dequeu action cell")
+                break
             }
-        case sectionLeaveGroup:
-            let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath)
-            if let actionCell = cell as? ActionCell {
-                actionCell.actionTitle = String.localized("menu_leave_group")
-                actionCell.actionColor = UIColor.red
+            if row == 0 {
+                actionCell.actionTitle = String.localized("group_add_members")
+                actionCell.actionColor = UIColor.systemBlue
+
+            } else {
+                actionCell.actionTitle = String.localized("qrshow_join_group_title")
+                actionCell.actionColor = UIColor.systemBlue
+
+            }
+            return actionCell
+        case .members:
+            guard let contactCell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as? ContactCell else {
+                safe_fatalError("could not dequeu contactCell cell")
+                break
+
+            }
+            let cellData = ContactCellData(contactId: groupMemberIds[row])
+            let cellViewModel = ContactCellViewModel(contactData: cellData)
+            contactCell.updateCell(cellViewModel: cellViewModel)
+            return contactCell
+        case .chatActions:
+            if row == 0 {
+                return archiveChatCell
+            } else if row == 1 {
+                return leaveGroupCell
+            } else if row == 2 {
+                return deleteChatCell
             }
-            return cell
-        default:
-            return UITableViewCell(frame: .zero)
         }
+        // should never get here
+        return UITableViewCell(frame: .zero)
+        /*
+         let section = indexPath.section
+         let row = indexPath.row
+         switch section {
+         case sectionMembers:
+         switch row {
+         case sectionMembersRowAddMember:
+         let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath)
+         if let actionCell = cell as? ActionCell {
+         actionCell.actionTitle = String.localized("group_add_members")
+         actionCell.actionColor = UIColor.systemBlue
+         }
+         return cell
+         case sectionMembersRowJoinQR:
+         let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath)
+         if let actionCell = cell as? ActionCell {
+         actionCell.actionTitle = String.localized("qrshow_join_group_title")
+         actionCell.actionColor = UIColor.systemBlue
+         }
+         return cell
+         default:
+         let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath)
+         if let contactCell = cell as? ContactCell {
+         let contact = groupMembers[row - sectionMembersStaticRowCount]
+         let displayName = contact.displayName
+         contactCell.titleLabel.text = displayName
+         contactCell.subtitleLabel.text = contact.email
+         contactCell.avatar.setName(displayName)
+         contactCell.avatar.setColor(contact.color)
+         if let profileImage = contact.profileImage {
+         contactCell.avatar.setImage(profileImage)
+         }
+         contactCell.setVerified(isVerified: contact.isVerified)
+         }
+         return cell
+         }
+         case sectionLeaveGroup:
+         let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath)
+         if let actionCell = cell as? ActionCell {
+         actionCell.actionTitle = String.localized("menu_leave_group")
+         actionCell.actionColor = UIColor.red
+         }
+         return cell
+         default:
+         return UITableViewCell(frame: .zero)
+         }
+         */
     }
 
     func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
@@ -247,20 +298,48 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
     }
 
     func tableView(_: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
-        let section = indexPath.section
+        guard let currentUser = self.currentUser else {
+            return false
+        }
         let row = indexPath.row
-
-        if let currentUser = currentUser {
-            if section == sectionMembers, row >= sectionMembersStaticRowCount, groupMembers[row - sectionMembersStaticRowCount].id != currentUser.id {
-                return true
-            }
+        let sectionType = sections[indexPath.section]
+        if sectionType == .members && groupMemberIds[row] != currentUser.id {
+            return true
         }
         return false
     }
 
     func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
-        let section = indexPath.section
+        guard let currentUser = self.currentUser else {
+            return nil
+        }
         let row = indexPath.row
+        let sectionType = sections[indexPath.section]
+        if sectionType == .members && groupMemberIds[row] != currentUser.id {
+            // action set for members except for current user
+            let delete = UITableViewRowAction(style: .destructive, title: String.localized("remove_desktop")) { [unowned self] _, indexPath in
+
+                let contact = self.getGroupMember(at: row)
+                let title = String.localizedStringWithFormat(String.localized("ask_remove_members"), contact.nameNAddr)
+                let alert = UIAlertController(title: title, message: nil, preferredStyle: .safeActionSheet)
+                alert.addAction(UIAlertAction(title: String.localized("remove_desktop"), style: .destructive, handler: { _ in
+                    let success = dc_remove_contact_from_chat(mailboxPointer, UInt32(self.chat.id), UInt32(contact.id))
+                    if success == 1 {
+                        self.groupMemberIds.remove(at: row)
+                        tableView.deleteRows(at: [indexPath], with: .fade)
+                        tableView.reloadData()
+                    }
+                }))
+                alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil))
+                self.present(alert, animated: true, completion: nil)
+            }
+            delete.backgroundColor = UIColor.red
+            return [delete]
+        }
+        return nil
+
+        /*
+
 
         // assigning swipe by delete to members (except for current user)
         if section == sectionMembers, row >= sectionMembersStaticRowCount, groupMembers[row - sectionMembersStaticRowCount].id != currentUser?.id {
@@ -272,7 +351,7 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
                 alert.addAction(UIAlertAction(title: String.localized("remove_desktop"), style: .destructive, handler: { _ in
                     let success = dc_remove_contact_from_chat(mailboxPointer, UInt32(self.chat.id), UInt32(contact.id))
                     if success == 1 {
-                        self.groupMembers.remove(at: row - self.sectionMembersStaticRowCount)
+                        self.groupMemberIds.remove(at: row - self.sectionMembersStaticRowCount)
                         tableView.deleteRows(at: [indexPath], with: .fade)
                         tableView.reloadData()
                     }
@@ -285,11 +364,11 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
         } else {
             return nil
         }
+        */
     }
 
     func getGroupMember(at row: Int) -> DcContact {
-        let memberId = self.groupMembers[row - self.sectionMembersStaticRowCount].id
-        return DcContact(id: memberId)
+        return DcContact(id: groupMemberIds[row])
     }
 
 }

+ 4 - 4
deltachat-ios/ViewModel/ContactDetailViewModel.swift

@@ -6,7 +6,7 @@ protocol ContactDetailViewModelProtocol {
     var numberOfSections: Int { get }
     var chatIsArchived: Bool { get }
     func numberOfRowsInSection(_ : Int) -> Int
-    func typeFor(section: Int) -> ContactDetailViewModel.SectionType
+    func typeFor(section: Int) -> ContactDetailViewModel.ProfileSections
     func update(sharedChatCell: ContactCell, row index: Int)
     func getSharedChatIdAt(indexPath: IndexPath) -> Int
     func titleFor(section: Int) -> String?
@@ -15,7 +15,7 @@ protocol ContactDetailViewModelProtocol {
 class ContactDetailViewModel: ContactDetailViewModelProtocol {
 
     let context: DcContext
-    enum SectionType {
+    enum ProfileSections {
         case startChat
         case sharedChats
         case chatActions //  archive chat, block chat, delete chats
@@ -27,7 +27,7 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
     private let chatId: Int?
     private let sharedChats: DcChatlist
     private let startChatOption: Bool
-    private var sections: [SectionType] = []
+    private var sections: [ProfileSections] = []
 
     /// if chatId is nil this is a contact detail with 'start chat'-option
     init(contactId: Int, chatId: Int?, context: DcContext) {
@@ -47,7 +47,7 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
         sections.append(.chatActions)
     }
 
-    func typeFor(section: Int) -> ContactDetailViewModel.SectionType {
+    func typeFor(section: Int) -> ContactDetailViewModel.ProfileSections {
         return sections[section]
     }