浏览代码

groups can add new members now

Bastian van de Wetering 6 年之前
父节点
当前提交
195b0064c4

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

@@ -106,6 +106,7 @@
 		AEE56D7D2253ADB4007DC082 /* HudHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE56D7C2253ADB4007DC082 /* HudHandler.swift */; };
 		AEE56D80225504DB007DC082 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE56D7F225504DB007DC082 /* Extensions.swift */; };
 		AEE6EC382281AF2D00EDC689 /* InitialsBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE6EC372281AF2D00EDC689 /* InitialsBadge.swift */; };
+		AEE6EC3F2282C59C00EDC689 /* AddGroupMembersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEE6EC3E2282C59C00EDC689 /* AddGroupMembersViewController.swift */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -301,6 +302,7 @@
 		AEE56D7C2253ADB4007DC082 /* HudHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HudHandler.swift; sourceTree = "<group>"; };
 		AEE56D7F225504DB007DC082 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
 		AEE6EC372281AF2D00EDC689 /* InitialsBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialsBadge.swift; sourceTree = "<group>"; };
+		AEE6EC3E2282C59C00EDC689 /* AddGroupMembersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupMembersViewController.swift; sourceTree = "<group>"; };
 		FECB35E2B04CD5F5D02C157A /* Pods-deltachat-iosTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-deltachat-iosTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-deltachat-iosTests/Pods-deltachat-iosTests.release.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
@@ -600,6 +602,7 @@
 				7070FB3C20FDD9FE000DC258 /* NewGroupViewController.swift */,
 				7070FB9A2101ECBB000DC258 /* GroupNameController.swift */,
 				AE851ACF227DF50900ED86F0 /* SingleChatDetailViewController.swift */,
+				AEE6EC3E2282C59C00EDC689 /* AddGroupMembersViewController.swift */,
 			);
 			path = Controller;
 			sourceTree = "<group>";
@@ -963,6 +966,7 @@
 				AE851AC7227C776400ED86F0 /* Location.swift in Sources */,
 				7AE0A5491FC42F65005ECB4B /* NewChatViewController.swift in Sources */,
 				AE25F09022807AD800CDEA66 /* GroupNameCell.swift in Sources */,
+				AEE6EC3F2282C59C00EDC689 /* AddGroupMembersViewController.swift in Sources */,
 				78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */,
 				AE8519EA2272FDCA00ED86F0 /* DeviceContactsHandler.swift in Sources */,
 				78ED838321D5379000243125 /* TextFieldCell.swift in Sources */,

+ 136 - 0
deltachat-ios/Controller/AddGroupMembersViewController.swift

@@ -0,0 +1,136 @@
+//
+//  GroupMemberViewController.swift
+//  deltachat-ios
+//
+//  Created by Bastian van de Wetering on 08.05.19.
+//  Copyright © 2019 Jonas Reinsch. All rights reserved.
+//
+
+import UIKit
+
+class AddGroupMembersViewController: GroupMembersViewController {
+
+	private var chatId: Int?
+
+	private lazy var resetButton: UIBarButtonItem = {
+		let button = UIBarButtonItem(title: "Reset", style: .plain, target: self, action: #selector(resetButtonPressed))
+		button.isEnabled = false
+		return button
+	}()
+
+	override var selectedContactIds: Set<Int> {
+		didSet {
+			resetButton.isEnabled = !selectedContactIds.isEmpty
+		}
+	}
+
+
+	private lazy var chat: MRChat? = {
+		if let chatId = chatId {
+			return MRChat(id: chatId)
+		}
+		return nil
+	}()
+
+	private lazy var chatMemberIds: [Int] = {
+		if let chat = chat {
+			return chat.contactIds
+		}
+		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)
+	}()
+
+
+	convenience init(chatId: Int) {
+		self.init(nibName: nil, bundle: nil)
+		self.chatId = chatId
+	}
+
+	override func viewDidLoad() {
+		super.viewDidLoad()
+		super.contactIds = memberCandidateIds
+		super.navigationItem.rightBarButtonItem = resetButton
+		title = "Add Group Members"
+		// Do any additional setup after loading the view.
+	}
+
+	override func viewWillDisappear(_ animated: Bool) {
+		guard let chatId = chatId else {
+			return
+		}
+		for contactId in selectedContactIds {
+			dc_add_contact_to_chat(mailboxPointer, UInt32(chatId), UInt32(contactId))
+		}
+	}
+
+	@objc func resetButtonPressed() {
+		selectedContactIds = []
+		tableView.reloadData()
+	}
+}
+
+
+class GroupMembersViewController : UITableViewController {
+
+	let contactCellReuseIdentifier = "contactCell"
+
+	var contactIds: [Int] = [] {
+		didSet {
+			tableView.reloadData()
+		}
+	}
+
+	var selectedContactIds: Set<Int> = []
+
+	override func viewDidLoad() {
+		 tableView.register(ContactCell.self, forCellReuseIdentifier: contactCellReuseIdentifier)
+	}
+
+	override func numberOfSections(in _: UITableView) -> Int {
+		return 1
+	}
+
+	override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
+		return contactIds.count
+	}
+
+	override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+		guard let cell: ContactCell = tableView.dequeueReusableCell(withIdentifier: contactCellReuseIdentifier, for: indexPath) as? ContactCell else {
+			fatalError("shouldn't happen")
+		}
+
+		let row = indexPath.row
+		let contactRow = row
+
+		let contact = MRContact(id: contactIds[contactRow])
+		cell.nameLabel.text = contact.name
+		cell.emailLabel.text = contact.email
+		cell.initialsLabel.text = Utils.getInitials(inputName: contact.name)
+		cell.accessoryType = selectedContactIds.contains(contactIds[row]) ? .checkmark : .none
+		cell.setColor(contact.color)
+
+		return cell
+	}
+
+	override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+		let row = indexPath.row
+		if let cell = tableView.cellForRow(at: indexPath) {
+			tableView.deselectRow(at: indexPath, animated: true)
+			let contactId = contactIds[row]
+			if selectedContactIds.contains(contactId) {
+				selectedContactIds.remove(contactId)
+				cell.accessoryType = .none
+			} else {
+				selectedContactIds.insert(contactId)
+				cell.accessoryType = .checkmark
+			}
+		}
+	}
+}

+ 0 - 1
deltachat-ios/Controller/ChatViewController.swift

@@ -82,7 +82,6 @@ class ChatViewController: MessagesViewController {
 			navigationItem.rightBarButtonItem = UIBarButtonItem(customView: initialsLabel)
 		}
 
-
     configureMessageMenu()
 
     if #available(iOS 11.0, *) {

+ 30 - 18
deltachat-ios/Controller/SingleChatDetailViewController.swift

@@ -154,19 +154,21 @@ extension SingleChatDetailViewController: UITableViewDelegate, UITableViewDataSo
 
 class GroupChatDetailViewController: ChatDetailViewController {
 
-	var currentUser: MRContact? {
+	private var currentUser: MRContact? {
 		return groupMembers.filter({$0.email == MRConfig.addr}).first
 	}
 
-	let editGroupCell = GroupLabelCell()
+	private let editGroupCell = GroupLabelCell()
 
-	var editingGroupName: Bool = false
+	private var editingGroupName: Bool = false
 
-	lazy var editBarButtonItem: UIBarButtonItem = {
+	private lazy var editBarButtonItem: UIBarButtonItem = {
 		UIBarButtonItem(title: editingGroupName ? "Done" : "Edit", style: .plain, target: self, action: #selector(editButtonPressed))
 	}()
 
-	var groupMembers: [MRContact] = []
+	private var groupMembers: [MRContact] = []
+
+	private let staticCellCountMemberSection = 1 //
 
 	override func viewDidLoad() {
 		super.viewDidLoad()
@@ -266,7 +268,7 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
 		if section == 0 {
 			return 1
 		} else if section == 1 {
-			return groupMembers.count
+			return groupMembers.count + staticCellCountMemberSection // first cell is addGroupMemberCell
 		} else if section == 2 {
 			return 1
 		} else {
@@ -284,13 +286,20 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
 			cell.selectionStyle = .none
 			return cell
 		} else  if section == 1 {
-			let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactCell
-			let contact = groupMembers[row]
-			cell.nameLabel.text = contact.name
-			cell.emailLabel.text = contact.email
-			cell.initialsLabel.text = Utils.getInitials(inputName: contact.name)
-			cell.setColor(contact.color)
-			return cell
+
+			if row == 0 {
+				let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath) as! ActionCell
+				cell.actionTitle = "Add Members"
+				return cell
+			} else {
+				let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath) as! ContactCell
+				let contact = groupMembers[row - staticCellCountMemberSection]
+				cell.nameLabel.text = contact.name
+				cell.emailLabel.text = contact.email
+				cell.initialsLabel.text = Utils.getInitials(inputName: contact.name)
+				cell.setColor(contact.color)
+				return cell
+			}
 		} else if section == 2 {
 			let cell = tableView.dequeueReusableCell(withIdentifier: "actionCell", for: indexPath) as! ActionCell
 			cell.actionTitle = "Leave Group"
@@ -308,6 +317,9 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
 		if section == 0 {
 			showNotificationSetup()
 		} else if section == 1 {
+			if row == 0 {
+				coordinator?.showAddGroupMember(chatId: self.chat.id)
+			}
 			// ignore for now - in Telegram tapping a contactCell leads into ContactDetail
 		} else if section == 2 {
 			leaveGroup()
@@ -319,7 +331,7 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
 		let row = indexPath.row
 
 		if let currentUser = currentUser {
-			if section == 1 && groupMembers[row].id != currentUser.id {
+			if section == 1 && row > 0 && groupMembers[row - staticCellCountMemberSection].id != currentUser.id {
 				return true
 			}
 		}
@@ -332,13 +344,13 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
 		let row = indexPath.row
 
 		// assigning swipe by delete to members (except for current user)
-		if section == 1 && groupMembers[row].id != currentUser?.id {
-			let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
+		if section == 1 && row >= staticCellCountMemberSection && groupMembers[row - staticCellCountMemberSection].id != currentUser?.id {
+			let delete = UITableViewRowAction(style: .destructive, title: "Delete") { [unowned self] (action, indexPath) in
 
-				let memberId = self.groupMembers[row].id
+				let memberId = self.groupMembers[row - self.staticCellCountMemberSection].id
 				let success = dc_remove_contact_from_chat(mailboxPointer, UInt32(self.chat.id), UInt32(memberId))
 				if success == 1 {
-					self.groupMembers.remove(at: row)
+					self.groupMembers.remove(at: row - self.staticCellCountMemberSection)
 					tableView.deleteRows(at: [indexPath], with: .fade)
 					tableView.reloadData()
 				}

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

@@ -240,6 +240,11 @@ class ChatDetailCoordinator: Coordinator {
 		let newContactController = NewContactController(contactIdForUpdate: contactId)
 		navigationController.pushViewController(newContactController, animated: true)
 	}
+
+	func showAddGroupMember(chatId: Int) {
+		let groupMemberViewController = AddGroupMembersViewController(chatId: chatId)
+		navigationController.pushViewController(groupMemberViewController, animated: true)
+	}
 }
 
 class ChatViewCoordinator: Coordinator {