ソースを参照

implement media galleries for contact profiles

cyberta 5 年 前
コミット
e4a95c4056

+ 44 - 4
deltachat-ios/Controller/ContactDetailViewController.swift

@@ -49,6 +49,23 @@ class ContactDetailViewController: UITableViewController {
         return cell
     }()
 
+    private lazy var galleryCell: ActionCell = {
+        let cell = ActionCell()
+        cell.actionTitle = String.localized("gallery")
+        cell.actionColor = SystemColor.blue.uiColor
+        cell.selectionStyle = .none
+        return cell
+    }()
+
+    private lazy var documentsCell: ActionCell = {
+        let cell = ActionCell()
+        cell.actionTitle = String.localized("documents")
+        cell.actionColor = SystemColor.blue.uiColor
+        cell.selectionStyle = .none
+        return cell
+    }()
+
+
     init(viewModel: ContactDetailViewModelProtocol) {
         self.viewModel = viewModel
         super.init(style: .grouped)
@@ -95,8 +112,15 @@ class ContactDetailViewController: UITableViewController {
         let row = indexPath.row
         let cellType = viewModel.typeFor(section: indexPath.section)
         switch cellType {
+        case .attachments:
+            switch viewModel.attachmentActionFor(row: row) {
+            case .documents:
+                return documentsCell
+            case .gallery:
+                return galleryCell
+            }
         case .chatActions:
-            switch viewModel.actionFor(row: row) {
+            switch viewModel.chatActionFor(row: row) {
             case .archiveChat:
                 return archiveChatCell
             case .blockChat:
@@ -118,6 +142,8 @@ class ContactDetailViewController: UITableViewController {
     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
         let type = viewModel.typeFor(section: indexPath.section)
         switch type {
+        case .attachments:
+            handleAttachmentAction(for: indexPath.row)
         case .chatActions:
             handleCellAction(for: indexPath.row)
         case .startChat:
@@ -132,8 +158,8 @@ class ContactDetailViewController: UITableViewController {
     override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
         let type = viewModel.typeFor(section: indexPath.section)
         switch type {
-        case .chatActions, .startChat:
-            return 44
+        case .chatActions, .startChat, .attachments:
+            return Constants.defaultCellHeight
         case .sharedChats:
             return ContactCell.cellHeight
         }
@@ -143,10 +169,14 @@ class ContactDetailViewController: UITableViewController {
         return viewModel.titleFor(section: section)
     }
 
+    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
+        return Constants.defaultHeaderHeight
+    }
+
     // MARK: - actions
 
     private func handleCellAction(for index: Int) {
-        let action = viewModel.actionFor(row: index)
+        let action = viewModel.chatActionFor(row: index)
         switch action {
         case .archiveChat:
             toggleArchiveChat()
@@ -157,6 +187,16 @@ class ContactDetailViewController: UITableViewController {
         }
     }
 
+    private func handleAttachmentAction(for index: Int) {
+        let action = viewModel.attachmentActionFor(row: index)
+        switch action {
+        case .documents:
+            coordinator?.showDocuments()
+        case .gallery:
+            coordinator?.showGallery()
+        }
+    }
+
     private func toggleArchiveChat() {
         let archived = viewModel.toggleArchiveChat()
         if archived {

+ 32 - 1
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -620,9 +620,9 @@ class NewGroupCoordinator: Coordinator {
 }
 
 class ContactDetailCoordinator: Coordinator, ContactDetailCoordinatorProtocol {
-
     var dcContext: DcContext
     let navigationController: UINavigationController
+    var previewController: PreviewController?
     let chatId: Int?
 
     private var childCoordinators: [Coordinator] = []
@@ -650,6 +650,31 @@ class ContactDetailCoordinator: Coordinator, ContactDetailCoordinatorProtocol {
         navigationController.pushViewController(editContactController, animated: true)
     }
 
+    func showDocuments() {
+        presentPreview(for: DC_MSG_FILE, messageType2: DC_MSG_AUDIO, messageType3: 0)
+    }
+
+    func showGallery() {
+        presentPreview(for: DC_MSG_IMAGE, messageType2: DC_MSG_GIF, messageType3: DC_MSG_VIDEO)
+    }
+
+    private func presentPreview(for messageType: Int32, messageType2: Int32, messageType3: Int32) {
+        guard let chatId = self.chatId else { return }
+        let messageIds = dcContext.getChatMedia(chatId: chatId, messageType: messageType, messageType2: messageType2, messageType3: messageType3)
+        var mediaUrls: [URL] = []
+        for messageId in messageIds {
+            let message = DcMsg.init(id: messageId)
+            if let url = message.fileURL {
+                mediaUrls.insert(url, at: 0)
+            }
+        }
+        previewController = PreviewController(currentIndex: 0, urls: mediaUrls)
+        if let previewController = previewController {
+            navigationController.pushViewController(previewController.qlController, animated: true)
+        }
+    }
+
+
     func deleteChat() {
         guard let chatId = chatId else {
             return
@@ -736,10 +761,16 @@ class EditContactCoordinator: Coordinator, EditContactCoordinatorProtocol {
     }
 }
 
+
+/*
+ boilerplate - I tend to remove that interface (cyberta)
+ */
 protocol ContactDetailCoordinatorProtocol: class {
     func showEditContact(contactId: Int)
     func showChat(chatId: Int)
     func deleteChat()
+    func showDocuments()
+    func showGallery()
 }
 
 protocol EditContactCoordinatorProtocol: class {

+ 1 - 0
deltachat-ios/Helper/Constants.swift

@@ -17,4 +17,5 @@ struct Constants {
     static let notificationIdentifier = "deltachat-ios-local-notifications"
 
     static let defaultCellHeight: CGFloat = 48
+    static let defaultHeaderHeight: CGFloat = 20
 }

+ 23 - 7
deltachat-ios/ViewModel/ContactDetailViewModel.swift

@@ -7,7 +7,8 @@ protocol ContactDetailViewModelProtocol {
     var chatIsArchived: Bool { get }
     func numberOfRowsInSection(_ : Int) -> Int
     func typeFor(section: Int) -> ContactDetailViewModel.ProfileSections
-    func actionFor(row: Int) -> ContactDetailViewModel.ChatAction
+    func chatActionFor(row: Int) -> ContactDetailViewModel.ChatAction
+    func attachmentActionFor(row: Int) -> ContactDetailViewModel.AttachmentAction
     func update(sharedChatCell: ContactCell, row index: Int)
     func getSharedChatIdAt(indexPath: IndexPath) -> Int
     func titleFor(section: Int) -> String?
@@ -19,6 +20,7 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
     let context: DcContext
     enum ProfileSections {
         case startChat
+        case attachments
         case sharedChats
         case chatActions //  archive chat, block chat, delete chats
     }
@@ -29,13 +31,19 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
         case deleteChat
     }
 
+    enum AttachmentAction {
+        case gallery
+        case documents
+    }
+
     var contactId: Int
 
     var contact: DcContact
     private let chatId: Int?
     private let sharedChats: DcChatlist
     private var sections: [ProfileSections] = []
-    private var actions: [ChatAction] = [] // chatDetail: archive, block, delete - else: block
+    private var chatActions: [ChatAction] = [] // chatDetail: archive, block, delete - else: block
+    private var attachmentActions: [AttachmentAction] = [.gallery, .documents]
 
     /// if chatId is nil this is a contact detail with 'start chat'-option
     init(contactId: Int, chatId: Int?, context: DcContext) {
@@ -46,15 +54,16 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
         self.sharedChats = context.getChatlist(flags: 0, queryString: nil, queryId: contactId)
 
         sections.append(.startChat)
+        sections.append(.attachments)
         if sharedChats.length > 0 {
             sections.append(.sharedChats)
         }
         sections.append(.chatActions)
 
         if chatId != nil {
-            actions = [.archiveChat, .blockChat, .deleteChat]
+            chatActions = [.archiveChat, .blockChat, .deleteChat]
         } else {
-            actions = [.blockChat]
+            chatActions = [.blockChat]
         }
     }
 
@@ -62,8 +71,12 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
         return sections[section]
     }
 
-    func actionFor(row: Int) -> ContactDetailViewModel.ChatAction {
-        return actions[row]
+    func chatActionFor(row: Int) -> ContactDetailViewModel.ChatAction {
+        return chatActions[row]
+    }
+
+    func attachmentActionFor(row: Int) -> ContactDetailViewModel.AttachmentAction {
+        return attachmentActions[row]
     }
 
     var chatIsArchived: Bool {
@@ -80,9 +93,10 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
 
     func numberOfRowsInSection(_ section: Int) -> Int {
         switch sections[section] {
+        case .attachments: return 2
         case .sharedChats: return sharedChats.length
         case .startChat: return 1
-        case .chatActions: return actions.count
+        case .chatActions: return chatActions.count
         }
     }
 
@@ -105,6 +119,8 @@ class ContactDetailViewModel: ContactDetailViewModelProtocol {
     func titleFor(section: Int) -> String? {
         if sections[section] == .sharedChats {
             return String.localized("profile_shared_chats")
+        } else if sections[section] == .attachments {
+            return String.localized("media")
         }
         return nil
     }