Bladeren bron

implement avatar picker for group creation

cyberta 5 jaren geleden
bovenliggende
commit
4381ea79c5

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

@@ -1,6 +1,7 @@
 import UIKit
 
-class GroupNameController: UITableViewController {
+class GroupNameController: UITableViewController, MediaPickerDelegate {
+
     weak var coordinator: GroupNameCoordinator?
 
     var groupName: String = ""
@@ -8,6 +9,7 @@ class GroupNameController: UITableViewController {
     var doneButton: UIBarButtonItem!
     let contactIdsForGroup: Set<Int> // TODO: check if array is sufficient
     let groupContactIds: [Int]
+    var groupImage: UIImage?
 
     private let sectionGroupDetails = 0
     private let sectionGroupDetailsRowAvatar = 0
@@ -23,6 +25,7 @@ class GroupNameController: UITableViewController {
     lazy var avatarSelectionCell: AvatarSelectionCell = {
         let cell = AvatarSelectionCell(context: nil)
         cell.hintLabel.text = String.localized("group_avatar")
+        cell.onAvatarTapped = onAvatarTapped
         return cell
     }()    
 
@@ -50,6 +53,11 @@ class GroupNameController: UITableViewController {
         let groupChatId = dc_create_group_chat(mailboxPointer, 0, groupName)
         for contactId in contactIdsForGroup {
             let success = dc_add_contact_to_chat(mailboxPointer, groupChatId, UInt32(contactId))
+
+            if let groupImage = groupImage, let dcContext = coordinator?.dcContext {
+                    AvatarHelper.saveChatAvatar(dcContext: dcContext, image: groupImage, for: Int(groupChatId))
+            }
+
             if success == 1 {
                 logger.info("successfully added \(contactId) to group \(groupName)")
             } else {
@@ -128,4 +136,40 @@ class GroupNameController: UITableViewController {
         groupName = name
         doneButton.isEnabled = name.containsCharacters()
     }
+
+    private func onAvatarTapped() {
+        let alert = UIAlertController(title: nil, 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))
+        self.present(alert, animated: true, completion: nil)
+    }
+
+    private func galleryButtonPressed(_ action: UIAlertAction) {
+        coordinator?.showPhotoPicker(delegate: self)
+    }
+
+    private func cameraButtonPressed(_ action: UIAlertAction) {
+        coordinator?.showCamera(delegate: self)
+    }
+
+    func onImageSelected(image: UIImage) {
+        groupImage = image
+
+        avatarSelectionCell = AvatarSelectionCell(context: nil, with: groupImage)
+        avatarSelectionCell.hintLabel.text = String.localized("group_avatar")
+        avatarSelectionCell.onAvatarTapped = onAvatarTapped
+
+        self.tableView.beginUpdates()
+        let indexPath = IndexPath(row: sectionGroupDetailsRowAvatar, section: sectionGroupDetails)
+        self.tableView.reloadRows(at: [indexPath], with: UITableView.RowAnimation.none)
+        self.tableView.endUpdates()
+    }
+
+    func onDismiss() {
+        
+    }
+
 }

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

@@ -368,6 +368,9 @@ class GroupChatDetailCoordinator: Coordinator {
         contactDetailController.coordinator = coordinator
         navigationController.pushViewController(contactDetailController, animated: true)
     }
+
+
+
 }
 
 class ChatViewCoordinator: NSObject, Coordinator {
@@ -567,12 +570,15 @@ class AddGroupMembersCoordinator: Coordinator {
 class GroupNameCoordinator: Coordinator {
     var dcContext: DcContext
     let navigationController: UINavigationController
+    let mediaPicker: MediaPicker
+
 
     private var childCoordinators: [Coordinator] = []
 
     init(dcContext: DcContext, navigationController: UINavigationController) {
         self.dcContext = dcContext
         self.navigationController = navigationController
+        self.mediaPicker = MediaPicker(navigationController: self.navigationController)
     }
 
     func showGroupChat(chatId: Int) {
@@ -583,6 +589,15 @@ class GroupNameCoordinator: Coordinator {
         navigationController.popToRootViewController(animated: false)
         navigationController.pushViewController(chatViewController, animated: true)
     }
+
+    func showPhotoPicker(delegate: MediaPickerDelegate) {
+          mediaPicker.showImageCropper(delegate: delegate)
+      }
+
+      func showCamera(delegate: MediaPickerDelegate) {
+          mediaPicker.showCamera(delegate: delegate)
+      }
+
 }
 
 class ContactDetailCoordinator: Coordinator, ContactDetailCoordinatorProtocol {

+ 4 - 0
deltachat-ios/DC/Wrapper.swift

@@ -153,6 +153,10 @@ class DcContext {
        }
        return nil
     }
+
+    func saveChatAvatarImage(chatId: Int, path: String) {
+        dc_set_chat_profile_image(contextPointer, UInt32(chatId), path)
+    }
 }
 
 class DcConfig {

+ 44 - 11
deltachat-ios/Helper/AvatarHelper.swift

@@ -3,35 +3,68 @@ import UIKit
 
 class AvatarHelper {
 
+    static let groupTemplate: NSString = "group_chat_avatar_%1$@.jpg"
     static let selfAvatarFile = "contact_avatar_self.jpg"
     private static let avatarPath = "avatars"
 
+    enum FileError: Error {
+        case runtimeError(String)
+    }
+
     static func saveSelfAvatarImage(image: UIImage) {
+        do {
+            let avatarFile = try saveAvatarImageToFile(image: image, fileName: selfAvatarFile)
+            DcConfig.selfavatar = avatarFile.path
+            //deleteAvatarFile(avatarFile)
+        } catch let error {
+            logger.error("Error saving Image: \(error.localizedDescription)")
+        }
+    }
+
+    static func saveChatAvatar(dcContext: DcContext, image: UIImage, for chatId: Int) {
+        let formattedGroupFileName = NSString.init(format: groupTemplate, "\(chatId)")
+        do {
+            let groupFileName = try saveAvatarImageToFile(image: image, fileName: formattedGroupFileName as String)
+            dcContext.saveChatAvatarImage(chatId: chatId, path: groupFileName.path)
+            //deleteAvatarFile(groupFileName)
+        } catch let error {
+            logger.error("Error saving Image: \(error.localizedDescription)")
+        }
+    }
+
+
+    private static func saveAvatarImageToFile(image: UIImage, fileName: String) throws -> URL {
         if let data = image.jpegData(compressionQuality: 1.0) {
             let filemanager = FileManager.default
             let docDir = filemanager.urls(for: .documentDirectory, in: .userDomainMask)[0]
             let avatarDir = docDir.appendingPathComponent(avatarPath)
             let avatarFile = avatarDir.appendingPathComponent(selfAvatarFile)
-            do {
-                try filemanager.createDirectory(atPath: avatarDir.path,
-                                                withIntermediateDirectories: false)
-            } catch let error as NSError {
-                logger.info("directory not created: \(error.localizedDescription)")
+
+            if !filemanager.fileExists(atPath: avatarDir.path) {
+                try filemanager.createDirectory(atPath: avatarDir.path, withIntermediateDirectories: false)
             }
 
             if !filemanager.changeCurrentDirectoryPath(avatarDir.path) {
-                logger.warning("Could not change into avatar directory")
-                return
+                throw FileError.runtimeError("Could not change to Avatar directory")
             }
+            
+            try data.write(to: avatarFile)
+            return avatarFile
+        } else {
+            throw FileError.runtimeError("Could not convert UIImage to jpegData")
+        }
+    }
 
+    private static func deleteAvatarFile(_ url: URL) {
+        let filemanager = FileManager.default
+        if filemanager.fileExists(atPath: url.path) {
             do {
-                try data.write(to: avatarFile)
+                try filemanager.removeItem(atPath: url.path)
             } catch let error {
                 logger.warning("Error: \(error.localizedDescription)")
-                return
             }
-
-            DcConfig.selfavatar = avatarFile.path
         }
     }
+
+
 }

+ 4 - 2
deltachat-ios/View/AvatarSelectionCell.swift

@@ -36,9 +36,11 @@ class AvatarSelectionCell: UITableViewCell {
         setupSubviews()
     }
 
-    init(context: DcContext?) {
+    init(context: DcContext?, with defaultImage: UIImage? = nil) {
         super.init(style: .default, reuseIdentifier: nil)
-        setAvatar(image: context?.getSelfAvatarImage(), with: self.defaultImage, downscale: downscaleDefaultImage)
+        setAvatar(image: context?.getSelfAvatarImage(),
+                  with: defaultImage ?? self.defaultImage,
+                  downscale: (defaultImage != nil) ? 1 : downscaleDefaultImage)
         setupSubviews()
     }