// // Copyright (c) 2020 Open Whisper Systems. All rights reserved. // import Foundation import PromiseKit @objc public protocol CameraFirstCaptureDelegate: AnyObject { func cameraFirstCaptureSendFlowDidComplete(_ cameraFirstCaptureSendFlow: CameraFirstCaptureSendFlow) func cameraFirstCaptureSendFlowDidCancel(_ cameraFirstCaptureSendFlow: CameraFirstCaptureSendFlow) } @objc public class CameraFirstCaptureSendFlow: NSObject { @objc public weak var delegate: CameraFirstCaptureDelegate? var approvedAttachments: [SignalAttachment]? var approvalMessageText: String? var selectedConversations: [ConversationItem] = [] } extension CameraFirstCaptureSendFlow: SendMediaNavDelegate { func sendMediaNavDidCancel(_ sendMediaNavigationController: SendMediaNavigationController) { delegate?.cameraFirstCaptureSendFlowDidCancel(self) } func sendMediaNav(_ sendMediaNavigationController: SendMediaNavigationController, didApproveAttachments attachments: [SignalAttachment], messageText: String?) { self.approvedAttachments = attachments self.approvalMessageText = messageText let pickerVC = ConversationPickerViewController() pickerVC.delegate = self sendMediaNavigationController.pushViewController(pickerVC, animated: true) } func sendMediaNavInitialMessageText(_ sendMediaNavigationController: SendMediaNavigationController) -> String? { return approvalMessageText } func sendMediaNav(_ sendMediaNavigationController: SendMediaNavigationController, didChangeMessageText newMessageText: String?) { self.approvalMessageText = newMessageText } var sendMediaNavApprovalButtonImageName: String { return "arrow-right-24" } var sendMediaNavCanSaveAttachments: Bool { return true } var sendMediaNavTextInputContextIdentifier: String? { return nil } var sendMediaNavRecipientNames: [String] { return selectedConversations.map { $0.title } } var sendMediaNavMentionableAddresses: [SignalServiceAddress] { guard FeatureFlags.mentionsSend else { return [] } guard selectedConversations.count == 1, case .group(let groupThread) = selectedConversations.first?.messageRecipient, groupThread.groupModel.groupsVersion == .V2 else { return [] } return groupThread.recipientAddresses } } extension CameraFirstCaptureSendFlow: ConversationPickerDelegate { var selectedConversationsForConversationPicker: [ConversationItem] { return selectedConversations } func conversationPicker(_ conversationPickerViewController: ConversationPickerViewController, didSelectConversation conversation: ConversationItem) { self.selectedConversations.append(conversation) } func conversationPicker(_ conversationPickerViewController: ConversationPickerViewController, didDeselectConversation conversation: ConversationItem) { self.selectedConversations = self.selectedConversations.filter { $0.messageRecipient != conversation.messageRecipient } } func conversationPickerDidCompleteSelection(_ conversationPickerViewController: ConversationPickerViewController) { guard let approvedAttachments = self.approvedAttachments else { owsFailDebug("approvedAttachments was unexpectedly nil") delegate?.cameraFirstCaptureSendFlowDidCancel(self) return } let conversations = selectedConversationsForConversationPicker firstly { AttachmentMultisend.sendApprovedMedia(conversations: conversations, approvalMessageText: self.approvalMessageText, approvedAttachments: approvedAttachments) }.done { _ in self.delegate?.cameraFirstCaptureSendFlowDidComplete(self) }.catch { error in owsFailDebug("Error: \(error)") } } func conversationPickerCanCancel(_ conversationPickerViewController: ConversationPickerViewController) -> Bool { return false } func conversationPickerDidCancel(_ conversationPickerViewController: ConversationPickerViewController) { owsFailDebug("Camera-first capture flow should never cancel conversation picker.") } func approvalMode(_ conversationPickerViewController: ConversationPickerViewController) -> ApprovalMode { return .send } }