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

Merge pull request #642 from deltachat/qr_login_avatar_name_2

name and profile after qr login
bjoern 5 лет назад
Родитель
Сommit
66473a05f1

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

@@ -144,6 +144,7 @@
 		AE851AD0227DF50900ED86F0 /* GroupChatDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE851ACF227DF50900ED86F0 /* GroupChatDetailViewController.swift */; };
 		AE9DAF0D22C1215D004C9591 /* EditContactController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE9DAF0C22C1215D004C9591 /* EditContactController.swift */; };
 		AE9DAF0F22C278C6004C9591 /* ChatTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE9DAF0E22C278C6004C9591 /* ChatTitleView.swift */; };
+		AEA0F6A124474146009F887B /* ProfileInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA0F6A024474146009F887B /* ProfileInfoViewController.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 */; };
@@ -394,6 +395,7 @@
 		AE851ACF227DF50900ED86F0 /* GroupChatDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupChatDetailViewController.swift; sourceTree = "<group>"; };
 		AE9DAF0C22C1215D004C9591 /* EditContactController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditContactController.swift; sourceTree = "<group>"; };
 		AE9DAF0E22C278C6004C9591 /* ChatTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTitleView.swift; sourceTree = "<group>"; };
+		AEA0F6A024474146009F887B /* ProfileInfoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileInfoViewController.swift; 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>"; };
 		AEACE2E21FB32B5C00DCDD78 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
@@ -791,6 +793,7 @@
 				7A0052C71FBE6CB40048C3BF /* NewContactController.swift */,
 				7070FB9A2101ECBB000DC258 /* NewGroupController.swift */,
 				AE4AEE3422B1030D000AA495 /* PreviewController.swift */,
+				AEA0F6A024474146009F887B /* ProfileInfoViewController.swift */,
 				789E879521D6CB58003ED1C5 /* QrCodeReaderController.swift */,
 				30A4D9AD2332672600544344 /* QrInviteViewController.swift */,
 				30149D9222F21129003C12B5 /* QrViewController.swift */,
@@ -1237,6 +1240,7 @@
 				305961FF2346125100C80F33 /* AvatarView.swift in Sources */,
 				3059620C2346125100C80F33 /* MessageSizeCalculator.swift in Sources */,
 				305962042346125100C80F33 /* MessagesCollectionViewLayoutAttributes.swift in Sources */,
+				AEA0F6A124474146009F887B /* ProfileInfoViewController.swift in Sources */,
 				305961D02346125100C80F33 /* NSAttributedString+Extensions.swift in Sources */,
 				302B84C72396770B001C261F /* RelayHelper.swift in Sources */,
 				305961CF2346125100C80F33 /* UIColor+Extensions.swift in Sources */,

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

@@ -68,7 +68,7 @@ class EditGroupViewController: UITableViewController, MediaPickerDelegate {
 
     override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
         if indexPath.row == rowAvatar {
-            return AvatarSelectionCell.cellSize
+            return AvatarSelectionCell.cellHeight
         }
         return Constants.defaultCellHeight
     }

+ 3 - 3
deltachat-ios/Controller/EditSettingsController.swift

@@ -8,8 +8,6 @@ class EditSettingsController: UITableViewController, MediaPickerDelegate {
     private var displayNameBackup: String?
     private var statusCellBackup: String?
 
-    private let groupBadgeSize: CGFloat = 72
-
     private let section1 = 0
     private let section1Name = 0
     private let section1Avatar = 1
@@ -106,7 +104,7 @@ class EditSettingsController: UITableViewController, MediaPickerDelegate {
         if indexPath.section == section1 {
             switch indexPath.row {
             case section1Avatar:
-                return AvatarSelectionCell.cellSize
+                return AvatarSelectionCell.cellHeight
             case section1Status:
                 return MultilineTextFieldCell.cellHeight
             default:
@@ -189,3 +187,5 @@ class EditSettingsController: UITableViewController, MediaPickerDelegate {
     }
 
 }
+
+

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

@@ -207,7 +207,7 @@ class NewGroupController: UITableViewController, MediaPickerDelegate {
         switch section {
         case sectionGroupDetails:
             if row == sectionGroupDetailsRowAvatar {
-                return AvatarSelectionCell.cellSize
+                return AvatarSelectionCell.cellHeight
             } else {
                 return Constants.defaultCellHeight
             }

+ 150 - 0
deltachat-ios/Controller/ProfileInfoViewController.swift

@@ -0,0 +1,150 @@
+import UIKit
+import DcCore
+
+class ProfileInfoViewController: UITableViewController {
+
+    weak var coordinator: EditSettingsCoordinator?
+    private let dcContext: DcContext
+
+    private var displayName: String?
+
+    private lazy var doneButtonItem: UIBarButtonItem = {
+        return UIBarButtonItem(
+            title: String.localized("done"),
+            style: .done,
+            target: self,
+            action: #selector(doneButtonPressed(_:))
+        )
+    }()
+
+    private lazy var emailCell: TextFieldCell = {
+        let cell = TextFieldCell(description: "Meine Email Adresse", placeholder: "Meine Email")
+        cell.setText(text: dcContext.addr)
+        return cell
+    }()
+
+    private lazy var avatarCell: AvatarSelectionCell = {
+        let cell = AvatarSelectionCell(context: self.dcContext)
+        cell.onAvatarTapped = avatarTapped
+        return cell
+    }()
+
+    private lazy var nameCell: TextFieldCell = {
+        let cell =  TextFieldCell.makeNameCell()
+        cell.placeholder = String.localized("pref_your_name")
+        cell.setText(text: dcContext.displayname)
+        cell.onTextFieldChange = {[unowned self] textField in
+            self.displayName = textField.text
+        }
+        return cell
+    }()
+
+    private lazy var cells = [nameCell, avatarCell]
+
+    init(context: DcContext) {
+        self.dcContext = context
+        super.init(style: .grouped)
+        tableView.estimatedRowHeight = Constants.defaultCellHeight
+    }
+
+    required init?(coder: NSCoder) {
+        fatalError("init(coder:) has not been implemented")
+    }
+
+    // MARK: - lifecycle
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        title = String.localized("pref_profile_info_headline")
+        navigationItem.rightBarButtonItem = doneButtonItem
+    }
+
+    // MARK: - tableviewDelegate
+    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+        return cells.count
+    }
+
+    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+        return cells[indexPath.row]
+    }
+
+    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+
+        let cell = cells[indexPath.row]
+        if cell is AvatarSelectionCell {
+            return AvatarSelectionCell.cellHeight
+        }
+        return Constants.defaultCellHeight
+    }
+
+    override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
+        let email = dcContext.addr ?? ""
+        let footerTitle = String.localizedStringWithFormat(
+            NSLocalizedString("qraccount_success_enter_name",comment: ""), email
+        )
+        return footerTitle
+    }
+
+    // MARK: - updates
+    private func updateAvatarCell() {
+        if let avatarImage = dcContext.getSelfAvatarImage() {
+            avatarCell.updateAvatar(image: avatarImage)
+        }
+        self.tableView.beginUpdates()
+        let indexPath = IndexPath(row: 1, section: 0)
+        self.tableView.reloadRows(at: [indexPath], with: UITableView.RowAnimation.none)
+        self.tableView.endUpdates()
+    }
+
+    // MARK: - actions
+    private func avatarTapped() {
+        let sender = avatarCell.badge
+        let alert = UIAlertController(
+            title: String.localized("pref_profile_photo"),
+            message: nil,
+            preferredStyle: .actionSheet
+        )
+        let photoAction = PhotoPickerAlertAction(
+            title: String.localized("gallery"),
+            style: .default,
+            handler: galleryButtonPressed(_:)
+        )
+        let videoAction = PhotoPickerAlertAction(
+            title: String.localized("camera"),
+            style: .default,
+            handler: cameraButtonPressed(_:)
+        )
+        alert.addAction(photoAction)
+        alert.addAction(videoAction)
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil))
+        if let popoverController = alert.popoverPresentationController {
+            popoverController.sourceView = self.avatarCell
+            popoverController.sourceRect = CGRect(
+                x: sender.frame.minX - 10,
+                y: sender.frame.minY,
+                width: sender.frame.width,
+                height: sender.frame.height
+            )
+         }
+        self.present(alert, animated: true, completion: nil)
+    }
+
+    @objc private func doneButtonPressed(_ sender: UIBarButtonItem) {
+        dcContext.displayname = displayName
+        self.dismiss(animated: true, completion: nil)
+    }
+
+    private func galleryButtonPressed(_ action: UIAlertAction) {
+        coordinator?.showPhotoPicker(delegate: self)
+    }
+
+    private func cameraButtonPressed(_ action: UIAlertAction) {
+        coordinator?.showCamera(delegate: self)
+    }
+}
+
+extension ProfileInfoViewController: MediaPickerDelegate {
+    func onImageSelected(image: UIImage) {
+        AvatarHelper.saveSelfAvatarImage(dcContext: dcContext, image: image)
+        updateAvatarCell()
+    }
+}

+ 14 - 2
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -83,6 +83,8 @@ class AppCoordinator: NSObject, Coordinator {
         return nav
     }()
 
+    private var profileInfoNavigationController: UINavigationController?
+
     init(window: UIWindow, dcContext: DcContext) {
         self.window = window
         self.dcContext = dcContext
@@ -170,7 +172,6 @@ extension AppCoordinator: WelcomeCoordinator {
         loginController.modalPresentationStyle = .fullScreen
         welcomeController.present(loginController, animated: true, completion: nil)
     }
-    
 
     func handleLoginSuccess() {
         DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
@@ -182,6 +183,18 @@ extension AppCoordinator: WelcomeCoordinator {
 
     func handleQRAccountCreationSuccess() {
         self.presentTabBarController()
+        showTab(index: 1)
+        presentProfileInfoController()
+    }
+
+    private func presentProfileInfoController() {
+        let profileInfoController = ProfileInfoViewController(context: dcContext)
+        let profileInfoNav = UINavigationController(rootViewController: profileInfoController)
+        profileInfoNav.modalPresentationStyle = .fullScreen
+        let coordinator = EditSettingsCoordinator(dcContext: dcContext, navigationController: profileInfoNav)
+        profileInfoController.coordinator = coordinator
+        childCoordinators.append(coordinator)
+        tabBarController.present(profileInfoNav, animated: false, completion: nil)
     }
 
     @objc private func cancelButtonPressed(_ sender: UIBarButtonItem) {
@@ -429,7 +442,6 @@ class NewChatCoordinator: Coordinator {
         navigationController.viewControllers.remove(at: 1)
     }
 
-
     func showContactDetail(contactId: Int) {
         let viewModel = ContactDetailViewModel(contactId: contactId, chatId: nil, context: dcContext)
         let contactDetailController = ContactDetailViewController(viewModel: viewModel)

+ 1 - 1
deltachat-ios/Helper/TypeAlias.swift

@@ -1,3 +1,3 @@
-import Foundation
+import UIKit
 
 typealias VoidFunction = () -> Void

+ 7 - 1
deltachat-ios/View/AvatarSelectionCell.swift

@@ -3,7 +3,7 @@ import DcCore
 
 class AvatarSelectionCell: UITableViewCell {
     let badgeSize: CGFloat = 72
-    static let cellSize: CGFloat = 98
+    static let cellHeight: CGFloat = 98
 
     var onAvatarTapped: (() -> Void)?
 
@@ -87,6 +87,7 @@ class AvatarSelectionCell: UITableViewCell {
         }
     }
 
+    // I think this is no good, we should rather update badge than overwriting it.
     func setAvatar(for chat: DcChat) {
         if let image = chat.profileImage {
             badge = InitialsBadge(image: image, size: badgeSize)
@@ -96,6 +97,7 @@ class AvatarSelectionCell: UITableViewCell {
         badge.setVerified(chat.isVerified)
     }
 
+    // I think this is no good, we should rather update badge than overwriting it.
     func setAvatar(image: UIImage?, with defaultImage: UIImage?) {
         if let image = image {
             badge = InitialsBadge(image: image, size: badgeSize)
@@ -104,4 +106,8 @@ class AvatarSelectionCell: UITableViewCell {
             badge.backgroundColor = DcColors.grayTextColor
         }
     }
+
+    func updateAvatar(image: UIImage) {
+        badge.setImage(image)
+    }
 }

+ 10 - 3
deltachat-ios/View/TextFieldCell.swift

@@ -1,7 +1,15 @@
 import UIKit
 
 class TextFieldCell: UITableViewCell {
-    private let placeholder: String
+
+    var placeholder: String? {
+        set {
+            textField.placeholder = newValue
+        }
+        get {
+            return textField.placeholder
+        }
+    }
 
     var onTextFieldChange:((_:UITextField) -> Void)?	// set this from outside to get notified about textfield changes
 
@@ -9,13 +17,11 @@ class TextFieldCell: UITableViewCell {
         let textField = UITextField()
         textField.textAlignment = .right
         // textField.enablesReturnKeyAutomatically = true
-        textField.placeholder = self.placeholder
         textField.addTarget(self, action: #selector(textFieldChanged), for: .editingChanged)
         return textField
     }()
 
     init(description: String, placeholder: String, delegate: UITextFieldDelegate? = nil) {
-        self.placeholder = placeholder
         super.init(style: .value1, reuseIdentifier: nil)
         textLabel?.text = "\(description):"
 
@@ -25,6 +31,7 @@ class TextFieldCell: UITableViewCell {
         selectionStyle = .none
         setupViews()
         textField.delegate = delegate
+        textField.placeholder = placeholder
     }
 
     convenience init(descriptionID: String, placeholder: String, delegate: UITextFieldDelegate? = nil) {