Bläddra i källkod

had issue that deleting a group member caused the header to disappear - fixed by making header UIView (before was UITableViewCell)

nayooti 5 år sedan
förälder
incheckning
0c5f2fd202

+ 9 - 8
deltachat-ios/Controller/ContactDetailViewController.swift

@@ -96,12 +96,12 @@ class ContactDetailViewController: UITableViewController {
         let cellType = viewModel.typeFor(section: indexPath.section)
         switch cellType {
         case .chatActions:
-            if row == 0 {
+            switch viewModel.actionFor(row: row) {
+            case .archiveChat:
                 return archiveChatCell
-            } else if row == 1 {
+            case .blockChat:
                 return blockContactCell
-            } else {
-                safe_assert(row == 2)
+            case .deleteChat:
                 return deleteChatCell
             }
         case .startChat:
@@ -146,12 +146,13 @@ class ContactDetailViewController: UITableViewController {
     // MARK: -actions
 
     private func handleCellAction(for index: Int) {
-        if index == 0 {
+        let action = viewModel.actionFor(row: index)
+        switch action {
+        case .archiveChat:
             toggleArchiveChat()
-        } else if index == 1 {
+        case .blockChat:
             toggleBlockContact()
-        } else {
-            safe_assert(index == 2)
+        case .deleteChat:
             showDeleteChatConfirmationAlert()
         }
     }

+ 18 - 6
deltachat-ios/Controller/GroupChatDetailViewController.swift

@@ -116,6 +116,7 @@ class GroupChatDetailViewController: UIViewController {
         updateGroupMembers()
         tableView.reloadData() // to display updates
         editBarButtonItem.isEnabled = currentUser != nil
+        updateHeader()
         //update chat object, maybe chat name was edited
         chat = DcChat(id: chat.id)
     }
@@ -126,6 +127,13 @@ class GroupChatDetailViewController: UIViewController {
         tableView.reloadData()
     }
 
+    private func updateHeader() {
+        headerCell.updateDetails(
+            title: chat.name,
+            subtitle: String.localizedStringWithFormat(String.localized("n_members"), chat.contactIds.count)
+        )
+    }
+
     // MARK: -actions
     @objc func editButtonPressed() {
         coordinator?.showGroupChatEdit(chat: chat)
@@ -227,8 +235,8 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
                 coordinator?.showQrCodeInvite(chatId: chat.id)
             }
         case .members:
-            let contact = getGroupMember(at: row)
-            coordinator?.showContactDetail(of: contact.id)
+            let member = getGroupMember(at: row)
+            coordinator?.showContactDetail(of: member.id)
         case .chatActions:
             if row == 0 {
                 toggleArchiveChat()
@@ -268,14 +276,13 @@ 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.groupMemberIds.remove(at: row)
-                        tableView.deleteRows(at: [indexPath], with: .fade)
-                        tableView.reloadData()
+                        self.removeGroupeMemberFromTableAt(indexPath)
                     }
                 }))
                 alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil))
                 self.present(alert, animated: true, completion: nil)
-            }
+
+ }
             delete.backgroundColor = UIColor.red
             return [delete]
         }
@@ -286,6 +293,11 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
         return DcContact(id: groupMemberIds[row])
     }
 
+    func removeGroupeMemberFromTableAt(_ indexPath: IndexPath) {
+        self.groupMemberIds.remove(at: indexPath.row)
+        self.tableView.deleteRows(at: [indexPath], with: .automatic)
+        updateHeader()  // to display correct group size
+    }
 }
 
 // MARK: -alerts

+ 75 - 3
deltachat-ios/View/ContactDetailHeader.swift

@@ -1,19 +1,91 @@
 import UIKit
 
-class ContactDetailHeader: ContactCell {
+class ContactDetailHeader: UIView {
+
+    public static let headerHeight: CGFloat = 74.5
+
+    let badgeSize: CGFloat = 54
+
+    private lazy var avatar: InitialsBadge = {
+        let badge = InitialsBadge(size: badgeSize)
+        badge.setColor(UIColor.lightGray)
+        badge.isAccessibilityElement = false
+        return badge
+    }()
+
+    private var titleLabel: UILabel = {
+        let label = UILabel()
+        label.font = UIFont.systemFont(ofSize: 16, weight: .medium)
+        label.lineBreakMode = .byTruncatingTail
+        label.textColor = DcColors.defaultTextColor
+        label.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1), for: NSLayoutConstraint.Axis.horizontal)
+        return label
+    }()
+
+    private var subtitleLabel: UILabel = {
+        let label = UILabel()
+        label.font = UIFont.systemFont(ofSize: 14)
+        label.textColor = UIColor(hexString: "848ba7")
+        label.lineBreakMode = .byTruncatingTail
+        return label
+    }()
+
     init() {
-        super.init(style: .default, reuseIdentifier: nil)
+        super.init(frame: .zero)
         let bg = UIColor(red: 248 / 255, green: 248 / 255, blue: 255 / 255, alpha: 1.0)
         backgroundColor = bg
-        selectionStyle = .none
+        setupSubviews()
     }
 
     required init?(coder _: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }
 
+    private func setupSubviews() {
+        let margin: CGFloat = 10
+        let verticalStackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
+
+        addSubview(avatar)
+        addSubview(verticalStackView)
+
+        avatar.translatesAutoresizingMaskIntoConstraints = false
+        verticalStackView.translatesAutoresizingMaskIntoConstraints = false
+
+        addConstraints([
+            avatar.constraintWidthTo(badgeSize),
+            avatar.constraintHeightTo(badgeSize),
+            avatar.constraintAlignLeadingTo(self, paddingLeading: badgeSize / 4),
+            avatar.constraintCenterYTo(self),
+        ])
+
+
+        verticalStackView.clipsToBounds = true
+        verticalStackView.leadingAnchor.constraint(equalTo: avatar.trailingAnchor, constant: margin).isActive = true
+        verticalStackView.centerYAnchor.constraint(equalTo: avatar.centerYAnchor).isActive = true
+        verticalStackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -margin).isActive = true
+        verticalStackView.axis = .vertical
+    }
+
     func updateDetails(title: String?, subtitle: String?) {
         titleLabel.text = title
         subtitleLabel.text = subtitle
     }
+
+    func setImage(_ image: UIImage) {
+        avatar.setImage(image)
+    }
+
+    func resetBackupImage() {
+        avatar.setColor(UIColor.clear)
+        avatar.setName("")
+    }
+
+    func setBackupImage(name: String, color: UIColor) {
+        avatar.setColor(color)
+        avatar.setName(name)
+    }
+
+    func setVerified(isVerified: Bool) {
+        avatar.setVerified(isVerified)
+    }
 }

+ 21 - 2
deltachat-ios/ViewModel/ContactDetailViewModel.swift

@@ -7,6 +7,7 @@ protocol ContactDetailViewModelProtocol {
     var chatIsArchived: Bool { get }
     func numberOfRowsInSection(_ : Int) -> Int
     func typeFor(section: Int) -> ContactDetailViewModel.ProfileSections
+    func actionFor(row: Int) -> ContactDetailViewModel.ChatAction
     func update(sharedChatCell: ContactCell, row index: Int)
     func getSharedChatIdAt(indexPath: IndexPath) -> Int
     func titleFor(section: Int) -> String?
@@ -22,6 +23,12 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
         case chatActions //  archive chat, block chat, delete chats
     }
 
+    enum ChatAction {
+        case archiveChat
+        case blockChat
+        case deleteChat
+    }
+
     var contactId: Int
 
     var contact: DcContact
@@ -29,6 +36,7 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
     private let sharedChats: DcChatlist
     private let startChatOption: Bool
     private var sections: [ProfileSections] = []
+    private var actions: [ChatAction] = [] // chatDetail: archive, block, delete - else: block
 
     /// if chatId is nil this is a contact detail with 'start chat'-option
     init(contactId: Int, chatId: Int?, context: DcContext) {
@@ -46,15 +54,26 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
             sections.append(.sharedChats)
         }
         sections.append(.chatActions)
+
+        if chatId != nil {
+            actions = [.archiveChat, .blockChat, .deleteChat]
+        } else {
+            actions = [.blockChat]
+        }
+
     }
 
     func typeFor(section: Int) -> ContactDetailViewModel.ProfileSections {
         return sections[section]
     }
 
+    func actionFor(row: Int) -> ContactDetailViewModel.ChatAction {
+        return actions[row]
+    }
+
     var chatIsArchived: Bool {
         guard let chatId = chatId else {
-            safe_fatalError("This is a ContactDetail view with no chat id")
+           // safe_fatalError("This is a ContactDetail view with no chat id")
             return false
         }
         return DcChat(id: chatId).isArchived
@@ -68,7 +87,7 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
         switch sections[section] {
         case .sharedChats: return sharedChats.length
         case .startChat: return 1
-        case .chatActions: return 3
+        case .chatActions: return actions.count
         }
     }