فهرست منبع

extracted ContactDetailHeader for re-usage - GroupChatDetail will edit name now in EditGroupChatDetailViewControlelr

Bastian van de Wetering 6 سال پیش
والد
کامیت
da262a3060

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

@@ -92,6 +92,8 @@
 		AE25F09022807AD800CDEA66 /* GroupNameCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE25F08F22807AD800CDEA66 /* GroupNameCell.swift */; };
 		AE38B31822672DFC00EC37A1 /* ActionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE38B31722672DFC00EC37A1 /* ActionCell.swift */; };
 		AE38B31A2267328200EC37A1 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE38B3192267328200EC37A1 /* Colors.swift */; };
+		AE52EA19229EB53C00C586C9 /* ContactDetailHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE52EA18229EB53C00C586C9 /* ContactDetailHeader.swift */; };
+		AE52EA20229EB9F000C586C9 /* EditGroupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE52EA1F229EB9F000C586C9 /* EditGroupViewController.swift */; };
 		AE728F15229D5C390047565B /* PhotoPickerAlertAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE728F14229D5C390047565B /* PhotoPickerAlertAction.swift */; };
 		AE8519EA2272FDCA00ED86F0 /* DeviceContactsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE8519E92272FDCA00ED86F0 /* DeviceContactsHandler.swift */; };
 		AE851A04227AECDE00ED86F0 /* deltachat_iosTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE851A03227AECDE00ED86F0 /* deltachat_iosTests.swift */; };
@@ -99,7 +101,7 @@
 		AE851AC7227C776400ED86F0 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE851AC6227C776400ED86F0 /* Location.swift */; };
 		AE851AC9227C77CF00ED86F0 /* Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE851AC8227C77CF00ED86F0 /* Media.swift */; };
 		AE851ACE227CA54400ED86F0 /* InitialsLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE851ACD227CA54300ED86F0 /* InitialsLabel.swift */; };
-		AE851AD0227DF50900ED86F0 /* SingleChatDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE851ACF227DF50900ED86F0 /* SingleChatDetailViewController.swift */; };
+		AE851AD0227DF50900ED86F0 /* GroupChatDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE851ACF227DF50900ED86F0 /* GroupChatDetailViewController.swift */; };
 		AEACE2DD1FB323CA00DCDD78 /* ChatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEACE2DC1FB323CA00DCDD78 /* ChatViewController.swift */; };
 		AEACE2DF1FB3246400DCDD78 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEACE2DE1FB3246400DCDD78 /* Message.swift */; };
 		AEACE2E31FB32B5C00DCDD78 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEACE2E21FB32B5C00DCDD78 /* Constants.swift */; };
@@ -289,6 +291,8 @@
 		AE25F08F22807AD800CDEA66 /* GroupNameCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupNameCell.swift; sourceTree = "<group>"; };
 		AE38B31722672DFC00EC37A1 /* ActionCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionCell.swift; sourceTree = "<group>"; };
 		AE38B3192267328200EC37A1 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
+		AE52EA18229EB53C00C586C9 /* ContactDetailHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDetailHeader.swift; sourceTree = "<group>"; };
+		AE52EA1F229EB9F000C586C9 /* EditGroupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditGroupViewController.swift; sourceTree = "<group>"; };
 		AE728F14229D5C390047565B /* PhotoPickerAlertAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoPickerAlertAction.swift; sourceTree = "<group>"; };
 		AE8519E92272FDCA00ED86F0 /* DeviceContactsHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceContactsHandler.swift; sourceTree = "<group>"; };
 		AE851A01227AECDE00ED86F0 /* deltachat-iosTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "deltachat-iosTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -298,7 +302,7 @@
 		AE851AC6227C776400ED86F0 /* Location.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Location.swift; sourceTree = "<group>"; };
 		AE851AC8227C77CF00ED86F0 /* Media.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Media.swift; sourceTree = "<group>"; };
 		AE851ACD227CA54300ED86F0 /* InitialsLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialsLabel.swift; sourceTree = "<group>"; };
-		AE851ACF227DF50900ED86F0 /* SingleChatDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleChatDetailViewController.swift; sourceTree = "<group>"; };
+		AE851ACF227DF50900ED86F0 /* GroupChatDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupChatDetailViewController.swift; sourceTree = "<group>"; };
 		AEA9CC2F22522DA20061D113 /* librpgp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = librpgp.h; sourceTree = "<group>"; };
 		AEACE2DC1FB323CA00DCDD78 /* ChatViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatViewController.swift; sourceTree = "<group>"; };
 		AEACE2DE1FB3246400DCDD78 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = "<group>"; };
@@ -618,10 +622,11 @@
 				78ED838E21D5927A00243125 /* ProfileViewController.swift */,
 				78E45E3921D3CFBC00D4B15E /* SettingsController.swift */,
 				7070FB9A2101ECBB000DC258 /* GroupNameController.swift */,
-				AE851ACF227DF50900ED86F0 /* SingleChatDetailViewController.swift */,
+				AE851ACF227DF50900ED86F0 /* GroupChatDetailViewController.swift */,
 				AEE6EC3E2282C59C00EDC689 /* GroupMembersViewController.swift */,
 				AEE6EC402282DF5700EDC689 /* MailboxViewController.swift */,
 				AEE6EC472283045D00EDC689 /* EditSettingsController.swift */,
+				AE52EA1F229EB9F000C586C9 /* EditGroupViewController.swift */,
 			);
 			path = Controller;
 			sourceTree = "<group>";
@@ -662,6 +667,7 @@
 				AE25F08F22807AD800CDEA66 /* GroupNameCell.swift */,
 				AEE6EC372281AF2D00EDC689 /* InitialsBadge.swift */,
 				AE728F14229D5C390047565B /* PhotoPickerAlertAction.swift */,
+				AE52EA18229EB53C00C586C9 /* ContactDetailHeader.swift */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -972,10 +978,12 @@
 				AEACE2DF1FB3246400DCDD78 /* Message.swift in Sources */,
 				7070FB9B2101ECBB000DC258 /* GroupNameController.swift in Sources */,
 				7070FB6D20FF345F000DC258 /* dc_imex.c in Sources */,
+				AE52EA19229EB53C00C586C9 /* ContactDetailHeader.swift in Sources */,
 				7070FB6620FF345F000DC258 /* dc_param.c in Sources */,
 				7070FB9220FF4118000DC258 /* dc_imap.c in Sources */,
 				7070FB7720FF345F000DC258 /* dc_qr.c in Sources */,
 				78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */,
+				AE52EA20229EB9F000C586C9 /* EditGroupViewController.swift in Sources */,
 				70B08FCD21073B910097D3EA /* NewGroupMemberChoiceController.swift in Sources */,
 				78E45E3E21D3D28C00D4B15E /* NavigationController.swift in Sources */,
 				78E45E4021D3D70700D4B15E /* ContactListController.swift in Sources */,
@@ -1035,7 +1043,7 @@
 				7092474120B3869500AF8799 /* ContactDetailViewController.swift in Sources */,
 				7070FB5E20FF345F000DC258 /* dc_token.c in Sources */,
 				AE18F292228C17BC0007B1BE /* PortSettingsController.swift in Sources */,
-				AE851AD0227DF50900ED86F0 /* SingleChatDetailViewController.swift in Sources */,
+				AE851AD0227DF50900ED86F0 /* GroupChatDetailViewController.swift in Sources */,
 				7070FB6C20FF345F000DC258 /* dc_keyring.c in Sources */,
 				7A451DB01FB1F84900177250 /* AppCoordinator.swift in Sources */,
 				AE38B31822672DFC00EC37A1 /* ActionCell.swift in Sources */,

+ 6 - 11
deltachat-ios/Controller/ContactDetailViewController.swift

@@ -120,21 +120,15 @@ class ContactDetailViewController: UITableViewController {
 	}
 
 	override func tableView(_: UITableView, viewForHeaderInSection section: Int) -> UIView? {
-		let bg = UIColor(red: 248 / 255, green: 248 / 255, blue: 255 / 255, alpha: 1.0)
 		if section == 0 {
-			let contactCell = ContactCell()
-			contactCell.backgroundColor = bg
-			contactCell.nameLabel.text = contact.name
-			contactCell.emailLabel.text = contact.email
-			contactCell.darkMode = false
-			contactCell.selectionStyle = .none
+			let header = ContactDetailHeader()
+			header.updateDetails(title: contact.name, subtitle: contact.email)
 			if let img = contact.profileImage {
-				contactCell.setImage(img)
+				header.setImage(img)
 			} else {
-				contactCell.setBackupImage(name: contact.name, color: contact.color)
+				header.setBackupImage(name: contact.name, color: contact.color)
 			}
-			contactCell.setVerified(isVerified: contact.isVerified)
-			return contactCell
+			header.setVerified(isVerified: contact.isVerified)
 		}
 		return nil
 	}
@@ -160,3 +154,4 @@ class ContactDetailViewController: UITableViewController {
 		coordinator?.showEditContact(contactId: contactId)
 	}
 }
+

+ 77 - 0
deltachat-ios/Controller/EditGroupViewController.swift

@@ -0,0 +1,77 @@
+//
+//  EditGroupViewController.swift
+//  deltachat-ios
+//
+//  Created by Bastian van de Wetering on 29.05.19.
+//  Copyright © 2019 Jonas Reinsch. All rights reserved.
+//
+
+import UIKit
+
+class EditGroupViewController: UITableViewController {
+
+	weak var coordinator: EditGroupCoordinator?
+
+	private let chat: MRChat
+
+	lazy var groupNameCell: GroupLabelCell = {
+		let cell = GroupLabelCell(style: .default, reuseIdentifier: nil)
+		cell.onTextChanged = groupNameEdited(_:)
+		return cell
+	}()
+
+	lazy var doneButton: UIBarButtonItem = {
+		let button = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(saveContactButtonPressed))
+		button.isEnabled = false
+		return button
+	}()
+
+	lazy var cancelButton: UIBarButtonItem = {
+		let button = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelButtonPressed))
+		return button
+	}()
+
+	init(chat: MRChat) {
+		self.chat = chat
+		super.init(style: .grouped)
+		groupNameCell.inputField.text = chat.name
+		groupNameCell.groupBadge.setText(chat.name)
+		groupNameCell.groupBadge.setColor(chat.color)
+	}
+
+	required init?(coder aDecoder: NSCoder) {
+		fatalError("init(coder:) has not been implemented")
+	}
+
+	override func viewDidLoad() {
+		super.viewDidLoad()
+		navigationItem.rightBarButtonItem = doneButton
+		navigationItem.leftBarButtonItem = cancelButton
+	}
+
+	override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+		return groupNameCell
+	}
+
+	override func numberOfSections(in tableView: UITableView) -> Int {
+		return 1
+	}
+
+	override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+		return 1
+	}
+
+	@objc func saveContactButtonPressed() {
+		let newName = groupNameCell.getGroupName()
+		dc_set_chat_name(mailboxPointer, UInt32(chat.id), newName)
+		coordinator?.navigateBack()
+	}
+
+	@objc func cancelButtonPressed() {
+		coordinator?.navigateBack()
+	}
+
+	private func groupNameEdited(_ newName: String) {
+		doneButton.isEnabled = true
+	}
+}

+ 15 - 43
deltachat-ios/Controller/SingleChatDetailViewController.swift → deltachat-ios/Controller/GroupChatDetailViewController.swift

@@ -13,11 +13,7 @@ class GroupChatDetailViewController: UIViewController {
     return groupMembers.filter { $0.email == MRConfig.addr }.first
   }
 
-  private let editGroupCell = GroupLabelCell()
-
-  private var editingGroupName: Bool = false
-
-	weak var coordinator: ChatDetailCoordinator?
+	weak var coordinator: GroupChatDetailCoordinator?
 
 	fileprivate var chat: MRChat
 
@@ -51,7 +47,6 @@ class GroupChatDetailViewController: UIViewController {
 		chatDetailTable.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
 	}
 
-
 	private func showNotificationSetup() {
 		let notificationSetupAlert = UIAlertController(title: "Notifications Setup is not implemented yet", message: "But you get an idea where this is going", preferredStyle: .actionSheet)
 		let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
@@ -59,9 +54,8 @@ class GroupChatDetailViewController: UIViewController {
 		present(notificationSetupAlert, animated: true, completion: nil)
 	}
 
-
   private lazy var editBarButtonItem: UIBarButtonItem = {
-    UIBarButtonItem(title: editingGroupName ? "Done" : "Edit", style: .plain, target: self, action: #selector(editButtonPressed))
+    UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editButtonPressed))
   }()
 
   private var groupMembers: [MRContact] = []
@@ -78,9 +72,9 @@ class GroupChatDetailViewController: UIViewController {
 
   override func viewWillAppear(_ animated: Bool) {
 		super.viewWillAppear(animated)
-		chatDetailTable.reloadData() // to display updates
 		updateGroupMembers()
-    editBarButtonItem.isEnabled = currentUser != nil
+		chatDetailTable.reloadData() // to display updates
+		editBarButtonItem.isEnabled = currentUser != nil
   }
 
   private func updateGroupMembers() {
@@ -90,15 +84,7 @@ class GroupChatDetailViewController: UIViewController {
   }
 
   @objc func editButtonPressed() {
-    if editingGroupName {
-      let newName = editGroupCell.getGroupName()
-      dc_set_chat_name(mailboxPointer, UInt32(chat.id), newName)
-      chat = MRChat(id: chat.id) // reload
-    }
-
-    editingGroupName = !editingGroupName
-    editBarButtonItem.title = editingGroupName ? "Save" : "Edit"
-    chatDetailTable.reloadData()
+		coordinator?.showGroupChatEdit(chat: chat)
   }
 
   private func leaveGroup() {
@@ -120,30 +106,16 @@ extension GroupChatDetailViewController: UITableViewDelegate, UITableViewDataSou
 
   func tableView(_: UITableView, viewForHeaderInSection section: Int) -> UIView? {
     if section == 0 {
-      let bg = UIColor(red: 248 / 255, green: 248 / 255, blue: 255 / 255, alpha: 1.0)
-
-      if editingGroupName {
-        editGroupCell.groupBadge.setColor(chat.color)
-        editGroupCell.backgroundColor = bg
-        editGroupCell.inputField.text = chat.name
-        editGroupCell.groupBadge.setText(chat.name)
-        return editGroupCell
-      } else {
-        let contactCell = ContactCell()
-        contactCell.backgroundColor = bg
-        contactCell.nameLabel.text = chat.name
-        contactCell.emailLabel.text = chat.subtitle
-        contactCell.darkMode = false
-        contactCell.selectionStyle = .none
-        if let img = chat.profileImage {
-          contactCell.setImage(img)
-        } else {
-          contactCell.setBackupImage(name: chat.name, color: chat.color)
-        }
-        contactCell.setVerified(isVerified: chat.isVerified)
-        return contactCell
-      }
-    } else {
+			let header = ContactDetailHeader()
+			header.updateDetails(title: chat.name, subtitle: chat.subtitle)
+			if let img = chat.profileImage {
+				header.setImage(img)
+			} else {
+				header.setBackupImage(name: chat.name, color: chat.color)
+			}
+			header.setVerified(isVerified: chat.isVerified)
+			return header
+		} else {
       return nil
     }
   }

+ 1 - 1
deltachat-ios/Controller/GroupNameController.swift

@@ -69,7 +69,7 @@ class GroupNameController: UITableViewController {
 
     if section == 0 {
       let cell = tableView.dequeueReusableCell(withIdentifier: "groupLabelCell", for: indexPath) as! GroupLabelCell
-      cell.groupNameUpdated = updateGroupName
+      cell.onTextChanged = updateGroupName
 
       return cell
 

+ 2 - 2
deltachat-ios/Controller/NewContactController.swift

@@ -65,11 +65,11 @@ class NewContactController: UITableViewController {
     nameCell.textField.returnKeyType = .done
 
     title = "New Contact"
-    doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(NewContactController.saveContactButtonPressed))
+    doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(saveContactButtonPressed))
     doneButton?.isEnabled = false
     navigationItem.rightBarButtonItem = doneButton
 
-    cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(NewContactController.cancelButtonPressed))
+    cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelButtonPressed))
     navigationItem.leftBarButtonItem = cancelButton
 
     emailCell.textField.addTarget(self, action: #selector(NewContactController.emailTextChanged), for: UIControl.Event.editingChanged)

+ 79 - 59
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -10,13 +10,13 @@ import UIKit
 
 class AppCoordinator: NSObject, Coordinator, UITabBarControllerDelegate {
 	private let window: UIWindow
-	
+
 	var rootViewController: UIViewController {
 		return tabBarController
 	}
-	
+
 	private var childCoordinators: [Coordinator] = []
-	
+
 	private lazy var tabBarController: UITabBarController = {
 		let tabBarController = UITabBarController()
 		tabBarController.viewControllers = [contactListController, mailboxController, profileController, chatListController, settingsController]
@@ -26,9 +26,9 @@ class AppCoordinator: NSObject, Coordinator, UITabBarControllerDelegate {
 		// tabBarController.tabBar.isTranslucent = false
 		return tabBarController
 	}()
-	
+
 	// MARK: viewControllers
-	
+
 	private lazy var contactListController: UIViewController = {
 		let controller = ContactListController()
 		let nav = NavigationController(rootViewController: controller)
@@ -39,7 +39,7 @@ class AppCoordinator: NSObject, Coordinator, UITabBarControllerDelegate {
 		controller.coordinator = coordinator
 		return nav
 	}()
-	
+
 	private lazy var mailboxController: UIViewController = {
 		let controller = MailboxViewController(chatId: Int(DC_CHAT_ID_DEADDROP), title: "Mailbox")
 		controller.disableWriting = true
@@ -51,7 +51,7 @@ class AppCoordinator: NSObject, Coordinator, UITabBarControllerDelegate {
 		controller.coordinator = coordinator
 		return nav
 	}()
-	
+
 	private lazy var profileController: UIViewController = {
 		let controller = ProfileViewController()
 		let nav = NavigationController(rootViewController: controller)
@@ -62,7 +62,7 @@ class AppCoordinator: NSObject, Coordinator, UITabBarControllerDelegate {
 		controller.coordinator = coordinator
 		return nav
 	}()
-	
+
 	private lazy var chatListController: UIViewController = {
 		let controller = ChatListController()
 		let nav = NavigationController(rootViewController: controller)
@@ -73,7 +73,7 @@ class AppCoordinator: NSObject, Coordinator, UITabBarControllerDelegate {
 		controller.coordinator = coordinator
 		return nav
 	}()
-	
+
 	private lazy var settingsController: UIViewController = {
 		let controller = SettingsViewController()
 		let nav = NavigationController(rootViewController: controller)
@@ -84,22 +84,22 @@ class AppCoordinator: NSObject, Coordinator, UITabBarControllerDelegate {
 		controller.coordinator = coordinator
 		return nav
 	}()
-	
+
 	init(window: UIWindow) {
 		self.window = window
 		super.init()
 		window.rootViewController = rootViewController
 		window.makeKeyAndVisible()
 	}
-	
+
 	public func start() {
 		showTab(index: 3)
 	}
-	
+
 	func showTab(index: Int) {
 		tabBarController.selectedIndex = index
 	}
-	
+
 	func presentLoginController() {
 		let accountSetupController = AccountSetupController()
 		let accountSetupNavigationController = UINavigationController(rootViewController: accountSetupController)
@@ -111,7 +111,7 @@ extension AppCoordinator: UITabBarDelegate {
 	func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
 		print("item selected")
 	}
-	
+
 	func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
 		print("shouldSelect")
 		return true 
@@ -120,13 +120,13 @@ extension AppCoordinator: UITabBarDelegate {
 
 class ContactListCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	var childCoordinators: [Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showContactDetail(contactId: Int) {
 		let contactDetailController = ContactDetailViewController(contactId: contactId)
 		contactDetailController.showChatCell = true
@@ -135,7 +135,7 @@ class ContactListCoordinator: Coordinator {
 		contactDetailController.coordinator = coordinator
 		navigationController.pushViewController(contactDetailController, animated: true)
 	}
-	
+
 	func showChat(chatId: Int) {
 		let chatVC = ChatViewController(chatId: chatId)
 		let coordinator = ChatViewCoordinator(navigationController: navigationController)
@@ -154,7 +154,7 @@ class MailboxCoordinator: ChatViewCoordinator {
 
 class ProfileCoordinator: Coordinator {
 	var rootViewController: UIViewController
-	
+
 	init(rootViewController: UIViewController) {
 		self.rootViewController = rootViewController
 	}
@@ -162,13 +162,13 @@ class ProfileCoordinator: Coordinator {
 
 class ChatListCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	var childCoordinators: [Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showNewChatController() {
 		let newChatVC = NewChatViewController()
 		let coordinator = NewChatCoordinator(navigationController: navigationController)
@@ -176,7 +176,7 @@ class ChatListCoordinator: Coordinator {
 		newChatVC.coordinator = coordinator
 		navigationController.pushViewController(newChatVC, animated: true)
 	}
-	
+
 	func showChat(chatId: Int) {
 		let chatVC = ChatViewController(chatId: chatId)
 		let coordinator = ChatViewCoordinator(navigationController: navigationController)
@@ -188,13 +188,13 @@ class ChatListCoordinator: Coordinator {
 
 class SettingsCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	var childCoordinators:[Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showAccountSetupController() {
 		let accountSetupVC = AccountSetupController()
 		let coordinator = AccountSetupCoordinator(navigationController: navigationController)
@@ -202,7 +202,7 @@ class SettingsCoordinator: Coordinator {
 		accountSetupVC.coordinator = coordinator
 		navigationController.pushViewController(accountSetupVC, animated: true)
 	}
-	
+
 	func showEditSettingsController(option: SettingsEditOption) {
 		let editController = EditSettingsController()
 		editController.activateField(option: option)
@@ -212,11 +212,11 @@ class SettingsCoordinator: Coordinator {
 
 class AccountSetupCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showImapPortOptions() {
 		let currentMailPort = MRConfig.mailPort ?? MRConfig.configuredMailPort
 		let currentPort = Int(currentMailPort)
@@ -228,7 +228,7 @@ class AccountSetupCoordinator: Coordinator {
 		}
 		navigationController.pushViewController(portSettingsController, animated: true)
 	}
-	
+
 	func showImapSecurityOptions() {
 		let currentSecurityOption = MRConfig.getImapSecurity()
 		let convertedOption = SecurityConverter.convertHexToString(type: .IMAPSecurity, hex: currentSecurityOption)
@@ -243,7 +243,7 @@ class AccountSetupCoordinator: Coordinator {
 		}
 		navigationController.pushViewController(securitySettingsController, animated: true)
 	}
-	
+
 	func showSmtpPortsOptions() {
 		let currentMailPort = MRConfig.sendPort ?? MRConfig.configuredSendPort
 		let currentPort = Int(currentMailPort)
@@ -255,7 +255,7 @@ class AccountSetupCoordinator: Coordinator {
 		}
 		navigationController.pushViewController(portSettingsController, animated: true)
 	}
-	
+
 	func showSmptpSecurityOptions() {
 		let currentSecurityOption = MRConfig.getSmtpSecurity()
 		let convertedOption = SecurityConverter.convertHexToString(type: .SMTPSecurity, hex: currentSecurityOption)
@@ -274,13 +274,13 @@ class AccountSetupCoordinator: Coordinator {
 
 class NewChatCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	private var childCoordinators: [Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showNewGroupController() {
 		let newGroupController = NewGroupViewController()
 		let coordinator = NewGroupCoordinator(navigationController: navigationController)
@@ -288,23 +288,23 @@ class NewChatCoordinator: Coordinator {
 		newGroupController.coordinator = coordinator
 		navigationController.pushViewController(newGroupController, animated: true)
 	}
-	
+
 	func showQRCodeController() {
 		let controller = QrCodeReaderController()
 		// controller.delegate = self
 		// present(controller, animated: true, completion: nil)
 	}
-	
+
 	func showNewContactController() {
 		let newContactController = NewContactController()
 		navigationController.pushViewController(newContactController, animated: true)
 	}
-	
+
 	func showNewChat(contactId: Int) {
 		let chatId = dc_create_chat_by_contact_id(mailboxPointer, UInt32(contactId))
 		showChat(chatId: Int(chatId))
 	}
-	
+
 	func showChat(chatId: Int) {
 		let chatViewController = ChatViewController(chatId: chatId)
 		let coordinator = ChatViewCoordinator(navigationController: navigationController)
@@ -315,35 +315,43 @@ class NewChatCoordinator: Coordinator {
 	}
 }
 
-class ChatDetailCoordinator: Coordinator {
+class GroupChatDetailCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	private var childCoordinators: [Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showSingleChatEdit(contactId: Int) {
 		let newContactController = NewContactController(contactIdForUpdate: contactId)
 		navigationController.pushViewController(newContactController, animated: true)
 	}
-	
+
 	func showAddGroupMember(chatId: Int) {
 		let groupMemberViewController = AddGroupMembersViewController(chatId: chatId)
 		navigationController.pushViewController(groupMemberViewController, animated: true)
 	}
+
+	func showGroupChatEdit(chat: MRChat) {
+		let editGroupViewController = EditGroupViewController(chat: chat)
+		let coordinator = EditGroupCoordinator(navigationController: navigationController)
+		childCoordinators.append(coordinator)
+		editGroupViewController.coordinator = coordinator
+		navigationController.pushViewController(editGroupViewController, animated: true)
+	}
 }
 
 class ChatViewCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	var childCoordinators: [Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showChatDetail(chatId: Int) {
 		let chat = MRChat(id: chatId)
 		switch chat.chatType {
@@ -357,13 +365,13 @@ class ChatViewCoordinator: Coordinator {
 			}
 		case .GROUP, .VERYFIEDGROUP:
 			let groupChatDetailViewController = GroupChatDetailViewController(chatId: chatId) // inherits from ChatDetailViewController
-			let coordinator = ChatDetailCoordinator(navigationController: navigationController)
+			let coordinator = GroupChatDetailCoordinator(navigationController: navigationController)
 			childCoordinators.append(coordinator)
 			groupChatDetailViewController.coordinator = coordinator
 			navigationController.pushViewController(groupChatDetailViewController, animated: true)
 		}
 	}
-	
+
 	func showContactDetail(of contactId: Int) {
 		let contactDetailController = ContactDetailViewController(contactId: contactId)
 		//let nav = UINavigationController(rootViewController: contactDetailController)
@@ -376,13 +384,13 @@ class ChatViewCoordinator: Coordinator {
 
 class NewGroupCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	private var childCoordinators: [Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showGroupNameController(contactIdsForGroup: Set<Int>) {
 		let groupNameController = GroupNameController(contactIdsForGroup: contactIdsForGroup)
 		let coordinator = GroupNameCoordinator(navigationController: navigationController)
@@ -394,13 +402,13 @@ class NewGroupCoordinator: Coordinator {
 
 class GroupNameCoordinator: Coordinator {
 	let navigationController: UINavigationController
-	
+
 	private var childCoordinators: [Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showGroupChat(chatId: Int) {
 		let chatViewController = ChatViewController(chatId: chatId)
 		let coordinator = ChatViewCoordinator(navigationController: navigationController)
@@ -413,13 +421,13 @@ class GroupNameCoordinator: Coordinator {
 
 class ContactDetailCoordinator: Coordinator, ContactDetailCoordinatorProtocol {
 	let navigationController: UINavigationController
-	
+
 	private var childCoordinators: [Coordinator] = []
-	
+
 	init(navigationController: UINavigationController) {
 		self.navigationController = navigationController
 	}
-	
+
 	func showChat(chatId: Int) {
 		let chatViewController = ChatViewController(chatId: chatId)
 		let coordinator = ChatViewCoordinator(navigationController: navigationController)
@@ -428,13 +436,25 @@ class ContactDetailCoordinator: Coordinator, ContactDetailCoordinatorProtocol {
 		navigationController.popToRootViewController(animated: false)
 		navigationController.pushViewController(chatViewController, animated: true)
 	}
-	
+
 	func showEditContact(contactId: Int) {
 		let newContactController = NewContactController(contactIdForUpdate: contactId)
 		navigationController.pushViewController(newContactController, animated: true)
 	}
 }
 
+class EditGroupCoordinator: Coordinator {
+	let navigationController: UINavigationController
+
+	init(navigationController: UINavigationController) {
+		self.navigationController = navigationController
+	}
+
+	func navigateBack() {
+		navigationController.popViewController(animated: true)
+	}
+}
+
 protocol ContactDetailCoordinatorProtocol: class {
 	func showEditContact(contactId: Int)
 	func showChat(chatId: Int)

+ 28 - 0
deltachat-ios/View/ContactDetailHeader.swift

@@ -0,0 +1,28 @@
+//
+//  ContactDetailHeader.swift
+//  deltachat-ios
+//
+//  Created by Bastian van de Wetering on 29.05.19.
+//  Copyright © 2019 Jonas Reinsch. All rights reserved.
+//
+
+import UIKit
+
+class ContactDetailHeader: ContactCell {
+	init() {
+		super.init(style: .default, reuseIdentifier: nil)
+		let bg = UIColor(red: 248 / 255, green: 248 / 255, blue: 255 / 255, alpha: 1.0)
+		backgroundColor = bg
+		darkMode = false
+		selectionStyle = .none
+	}
+
+	required init?(coder _: NSCoder) {
+		fatalError("init(coder:) has not been implemented")
+	}
+
+	func updateDetails(title: String?, subtitle: String?) {
+		nameLabel.text = title
+		emailLabel.text = subtitle
+	}
+}

+ 2 - 2
deltachat-ios/View/GroupNameCell.swift

@@ -11,7 +11,7 @@ import UIKit
 class GroupLabelCell: UITableViewCell {
   var groupBadgeSize: CGFloat = 54
 
-  var groupNameUpdated: ((String) -> Void)? // use this callback to update editButton in navigationController
+  var onTextChanged: ((String) -> Void)? // use this callback to update editButton in navigationController
 
   lazy var groupBadge: InitialsBadge = {
     let badge = InitialsBadge(frame: .zero)
@@ -62,7 +62,7 @@ class GroupLabelCell: UITableViewCell {
   @objc func nameFieldChanged() {
     let groupName = inputField.text ?? ""
     groupBadge.setText(groupName)
-    groupNameUpdated?(groupName)
+    onTextChanged?(groupName)
   }
 
   func getGroupName() -> String {