Message forwarding.

This commit is contained in:
Matthew Chen 2019-10-23 11:51:29 -03:00
parent 9e3aa77ce2
commit 66c239bbbb
6 changed files with 427 additions and 102 deletions

View File

@ -33,6 +33,7 @@
340CCB722305962B005243B3 /* YDBToGRDBMigrationModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340CCB702305962B005243B3 /* YDBToGRDBMigrationModelTest.swift */; };
340E9AC0235F876800FA362C /* ForwardMessageNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340E9ABF235F876800FA362C /* ForwardMessageNavigationController.swift */; };
340E9AC2235F878900FA362C /* TextApprovalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340E9AC1235F878800FA362C /* TextApprovalViewController.swift */; };
340E9AC4236095CD00FA362C /* SendMediaNavigationController+Multisend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 340E9AC3236095CC00FA362C /* SendMediaNavigationController+Multisend.swift */; };
340FC8A9204DAC8D007AEB0F /* NotificationSettingsOptionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */; };
340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */; };
340FC8AB204DAC8D007AEB0F /* DomainFrontingCountryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340FC87D204DAC8C007AEB0F /* DomainFrontingCountryViewController.m */; };
@ -755,6 +756,7 @@
340CCB702305962B005243B3 /* YDBToGRDBMigrationModelTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = YDBToGRDBMigrationModelTest.swift; sourceTree = "<group>"; };
340E9ABF235F876800FA362C /* ForwardMessageNavigationController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForwardMessageNavigationController.swift; sourceTree = "<group>"; };
340E9AC1235F878800FA362C /* TextApprovalViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextApprovalViewController.swift; sourceTree = "<group>"; };
340E9AC3236095CC00FA362C /* SendMediaNavigationController+Multisend.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SendMediaNavigationController+Multisend.swift"; sourceTree = "<group>"; };
340FC87B204DAC8C007AEB0F /* NotificationSettingsOptionsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsOptionsViewController.m; sourceTree = "<group>"; };
340FC87C204DAC8C007AEB0F /* NotificationSettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NotificationSettingsViewController.m; sourceTree = "<group>"; };
340FC87D204DAC8C007AEB0F /* DomainFrontingCountryViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DomainFrontingCountryViewController.m; sourceTree = "<group>"; };
@ -2030,13 +2032,14 @@
34969558219B605E00DCFE74 /* Photos */ = {
isa = PBXGroup;
children = (
4C4AE69F224AF21900D4AF6F /* SendMediaNavigationController.swift */,
34969559219B605E00DCFE74 /* ImagePickerController.swift */,
4C21D5D7223AC60F00EF8A77 /* PhotoCapture.swift */,
4CA485BA2232339F004B9E7D /* PhotoCaptureViewController.swift */,
3496955A219B605E00DCFE74 /* PhotoCollectionPickerController.swift */,
3496955B219B605E00DCFE74 /* PhotoLibrary.swift */,
4CA485BA2232339F004B9E7D /* PhotoCaptureViewController.swift */,
4C21D5D7223AC60F00EF8A77 /* PhotoCapture.swift */,
4C4F5EBB22711EEB00F3DD01 /* SendMediaBottomButton.swift */,
4C4AE69F224AF21900D4AF6F /* SendMediaNavigationController.swift */,
340E9AC3236095CC00FA362C /* SendMediaNavigationController+Multisend.swift */,
);
path = Photos;
sourceTree = "<group>";
@ -4044,6 +4047,7 @@
340CCB6A23032762005243B3 /* YDBLegacyMigration.m in Sources */,
3496955D219B605E00DCFE74 /* PhotoCollectionPickerController.swift in Sources */,
8835DDFD230CEE8900DC6B66 /* RecipientPickerDelegate.swift in Sources */,
340E9AC4236095CD00FA362C /* SendMediaNavigationController+Multisend.swift in Sources */,
34CE88E71F2FB9A10098030F /* ProfileViewController.m in Sources */,
3403B95D20EA9527001A1F44 /* OWSContactShareButtonsView.m in Sources */,
34B0796D1FCF46B100E248C2 /* MainAppContext.m in Sources */,

View File

@ -20,16 +20,6 @@ public class CameraFirstCaptureSendFlow: NSObject {
var approvalMessageText: String?
var selectedConversations: [ConversationItem] = []
// MARK: Dependencies
var databaseStorage: SDSDatabaseStorage {
return SSKEnvironment.shared.databaseStorage
}
var broadcastMediaMessageJobQueue: BroadcastMediaMessageJobQueue {
return AppEnvironment.shared.broadcastMediaMessageJobQueue
}
}
extension CameraFirstCaptureSendFlow: SendMediaNavDelegate {
@ -92,64 +82,11 @@ extension CameraFirstCaptureSendFlow: ConversationPickerDelegate {
}
let conversations = selectedConversationsForConversationPicker
DispatchQueue.global().async(.promise) {
// Duplicate attachments per conversation
let conversationAttachments: [(ConversationItem, [SignalAttachment])] =
try conversations.map { conversation in
return (conversation, try approvedAttachments.map { try $0.cloneAttachment() })
}
// We only upload one set of attachments, and then copy the upload details into
// each conversation before sending.
let attachmentsToUpload: [OutgoingAttachmentInfo] = approvedAttachments.map { attachment in
return OutgoingAttachmentInfo(dataSource: attachment.dataSource,
contentType: attachment.mimeType,
sourceFilename: attachment.filenameOrDefault,
caption: attachment.captionText,
albumMessageId: nil)
}
self.databaseStorage.write { transaction in
var messages: [TSOutgoingMessage] = []
for (conversation, attachments) in conversationAttachments {
let thread: TSThread
switch conversation.messageRecipient {
case .contact(let address):
thread = TSContactThread.getOrCreateThread(withContactAddress: address,
transaction: transaction)
case .group(let groupThread):
thread = groupThread
}
let message = try! ThreadUtil.createUnsentMessage(withText: self.approvalMessageText,
mediaAttachments: attachments,
in: thread,
quotedReplyModel: nil,
linkPreviewDraft: nil,
transaction: transaction)
messages.append(message)
}
// map of attachments we'll upload to their copies in each recipient thread
var attachmentIdMap: [String: [String]] = [:]
let correspondingAttachmentIds = transpose(messages.map { $0.attachmentIds })
for (index, attachmentInfo) in attachmentsToUpload.enumerated() {
do {
let attachmentToUpload = try attachmentInfo.asStreamConsumingDataSource(withIsVoiceMessage: false)
attachmentToUpload.anyInsert(transaction: transaction)
attachmentIdMap[attachmentToUpload.uniqueId] = correspondingAttachmentIds[index]
} catch {
owsFailDebug("error: \(error)")
}
}
self.broadcastMediaMessageJobQueue.add(attachmentIdMap: attachmentIdMap,
transaction: transaction)
}
}.done { _ in
self.delegate?.cameraFirstCaptureSendFlowDidComplete(self)
}.retainUntilComplete()
SendMediaNavigationController.sendApprovedMedia(conversations: conversations,
approvalMessageText: self.approvalMessageText,
approvedAttachments: approvedAttachments)
.done { _ in
self.delegate?.cameraFirstCaptureSendFlowDidComplete(self)
}.retainUntilComplete()
}
}

View File

@ -2052,11 +2052,18 @@ typedef enum : NSUInteger {
{
OWSAssertDebug(conversationViewItem);
// if (conversationViewItem.messageCellType == OWSMessageCellType_MediaMessage) {
ForwardMessageNavigationController *modal =
[[ForwardMessageNavigationController alloc] initWithConversationViewItem:conversationViewItem];
modal.forwardMessageDelegate = self;
[self presentFullScreenViewController:modal animated:YES completion:nil];
// } else {
// NSMutableArray<SignalAttachment *> *attachments = [NSMutableArray new];
// ForwardMediaNavigationController *modal = [ForwardMediaNavigationController
// forwardMediaModalWithAttachments:<#(NSArray<SignalAttachment *> * _Nonnull)#>];
// modal.forwardMediaSendFlow.delegate = self;
// [self presentFullScreenViewController:modal animated:YES completion:nil];
// }
}
#pragma mark - MessageDetailViewDelegate

View File

@ -35,7 +35,7 @@ extension ForwardMessageNavigationController {
let approvalView = TextApprovalViewController(messageText: body)
approvalView.delegate = self
self.pushViewController(approvalView, animated: true)
pushViewController(approvalView, animated: true)
case .contactShare:
guard let oldContactShare = conversationViewItem.contactShare else {
throw OWSAssertionError("Missing contactShareViewModel.")
@ -43,14 +43,67 @@ extension ForwardMessageNavigationController {
let newContactShare = oldContactShare.copyForResending()
let approvalView = ContactShareApprovalViewController(contactShare: newContactShare)
approvalView.delegate = self
self.pushViewController(approvalView, animated: true)
pushViewController(approvalView, animated: true)
case .audio,
.genericAttachment,
.stickerMessage:
// Skip approval for these message types.
send()
case .mediaMessage:
throw OWSAssertionError("Invalid message type.")
// fileprivate func pushApprovalViewController(
// attachmentApprovalItems: [AttachmentApprovalItem],
// options: AttachmentApprovalViewControllerOptions = .canAddMore,
// animated: Bool
// ) {
// guard let sendMediaNavDelegate = self.sendMediaNavDelegate else {
// owsFailDebug("sendMediaNavDelegate was unexpectedly nil")
// return
// }
// public static let canAddMore = AttachmentApprovalViewControllerOptions(rawValue: 1 << 0)
// public static let hasCancel = AttachmentApprovalViewControllerOptions(rawValue: 1 << 1)
// public static let canToggleViewOnce = AttachmentApprovalViewControllerOptions(rawValue: 1 << 2)
let options: AttachmentApprovalViewControllerOptions = .hasCancel
let sendButtonImageName = "send-solid-24"
var attachmentApprovalItems = [AttachmentApprovalItem]()
guard let mediaAlbumItems = conversationViewItem.mediaAlbumItems else {
throw OWSAssertionError("Missing mediaAlbumItems.")
}
for mediaAlbumItem in mediaAlbumItems {
guard let attachmentStream = mediaAlbumItem.attachmentStream else {
continue
}
let signalAttachment = try attachmentStream.asSignalAttachmentForSending()
// @interface ConversationMediaAlbumItem : NSObject
//
// @property (nonatomic, readonly) TSAttachment *attachment;
//
// // This property will only be set if the attachment is downloaded.
// @property (nonatomic, readonly, nullable) TSAttachmentStream *attachmentStream;
//
// // This property will be non-zero if the attachment is valid.
// @property (nonatomic, readonly) CGSize mediaSize;
//
// @property (nonatomic, readonly, nullable) NSString *caption;
//
// @property (nonatomic, readonly) BOOL isFailedDownload;
// for attachment in attachments {
let attachmentApprovalItem = AttachmentApprovalItem(attachment: signalAttachment, canSave: false)
attachmentApprovalItems.append(attachmentApprovalItem)
// let cameraCaptureAttachment = CameraCaptureAttachment(signalAttachment: attachment, canSave: false)
// navController.attachmentDraftCollection.append(.camera(attachment: cameraCaptureAttachment))
// attachmentApprovalItems.append(cameraCaptureAttachment.attachmentApprovalItem)
}
// let approvalItem = Attachmen
let approvalViewController = AttachmentApprovalViewController(options: options,
sendButtonImageName: sendButtonImageName,
attachmentApprovalItems: attachmentApprovalItems)
approvalViewController.approvalDelegate = self
approvalViewController.messageText = approvalMessageText
pushViewController(approvalViewController, animated: true)
case .unknown,
.oversizeTextDownloading,
.viewOnce:
@ -107,29 +160,21 @@ extension ForwardMessageNavigationController {
}
send { (thread, transaction) in
guard let sourceUrl = attachmentStream.originalMediaURL else {
throw OWSAssertionError("Missing originalMediaURL.")
}
guard let dataUTI = MIMETypeUtil.utiType(forMIMEType: attachmentStream.contentType) else {
throw OWSAssertionError("Missing dataUTI.")
}
let newUrl = OWSFileSystem.temporaryFileUrl(fileExtension: sourceUrl.pathExtension)
try FileManager.default.copyItem(at: sourceUrl, to: newUrl)
let clonedDataSource = try DataSourcePath.dataSource(with: newUrl,
shouldDeleteOnDeallocation: true)
clonedDataSource.sourceFilename = attachmentStream.sourceFilename
var attachment: SignalAttachment
if attachmentStream.isVoiceMessage {
attachment = SignalAttachment.voiceMessageAttachment(dataSource: clonedDataSource, dataUTI: dataUTI)
} else {
attachment = SignalAttachment.attachment(dataSource: clonedDataSource, dataUTI: dataUTI, imageQuality: .original)
}
let attachment = try attachmentStream.asSignalAttachmentForSending()
self.send(body: "", attachment: attachment, thread: thread, transaction: transaction)
}
case .mediaMessage:
throw OWSAssertionError("Invalid message type.")
guard let approvedAttachments = approvedAttachments else {
throw OWSAssertionError("Missing approvedAttachments.")
}
let conversations = selectedConversationsForConversationPicker
SendMediaNavigationController.sendApprovedMedia(conversations: conversations,
approvalMessageText: self.approvalMessageText,
approvedAttachments: approvedAttachments)
.done { threads in
self.forwardMessageDelegate?.forwardMessageFlowDidComplete(threads: threads)
}.retainUntilComplete()
case .unknown,
.oversizeTextDownloading,
.viewOnce:
@ -211,10 +256,6 @@ class ForwardMessageNavigationController: OWSNavigationController {
return SSKEnvironment.shared.databaseStorage
}
var broadcastMediaMessageJobQueue: BroadcastMediaMessageJobQueue {
return AppEnvironment.shared.broadcastMediaMessageJobQueue
}
var messageSenderJobQueue: MessageSenderJobQueue {
return SSKEnvironment.shared.messageSenderJobQueue
}
@ -310,3 +351,182 @@ extension ForwardMessageNavigationController: ContactShareApprovalViewController
forwardMessageDelegate?.forwardMessageFlowDidCancel()
}
}
// MARK: -
extension ForwardMessageNavigationController: AttachmentApprovalViewControllerDelegate {
func attachmentApprovalDidAppear(_ attachmentApproval: AttachmentApprovalViewController) {
// TODO:
// updateViewState(topViewController: attachmentApproval)
}
func attachmentApproval(_ attachmentApproval: AttachmentApprovalViewController, didChangeMessageText newMessageText: String?) {
self.approvalMessageText = newMessageText
// sendMediaNavDelegate?.sendMediaNav(self, didChangeMessageText: newMessageText)
}
func attachmentApproval(_ attachmentApproval: AttachmentApprovalViewController, didRemoveAttachment attachment: SignalAttachment) {
// guard let removedDraft = attachmentDraftCollection.attachmentDraft(forAttachment: attachment) else {
// owsFailDebug("removedDraft was unexpectedly nil")
// return
// }
//
// attachmentDraftCollection.remove(removedDraft)
}
func attachmentApproval(_ attachmentApproval: AttachmentApprovalViewController, didApproveAttachments attachments: [SignalAttachment], messageText: String?) {
self.approvedAttachments = attachments
self.approvalMessageText = messageText
send()
}
func attachmentApprovalDidCancel(_ attachmentApproval: AttachmentApprovalViewController) {
forwardMessageDelegate?.forwardMessageFlowDidCancel()
}
func attachmentApprovalDidTapAddMore(_ attachmentApproval: AttachmentApprovalViewController) {
owsFailDebug("Cannot add more to message forwards.")
}
var attachmentApprovalTextInputContextIdentifier: String? {
return nil
}
}
//extension ForwardMediaNavigationController: SendMediaNavDelegate {
// func approveContactShare(_ approveContactShare: ContactShareApprovalViewController,
// didApproveContactShare contactShare: ContactShareViewModel) {
// approvedContactShare = contactShare
//
// send()
// }
//
// func approveContactShare(_ approveContactShare: ContactShareApprovalViewController,
// didCancelContactShare contactShare: ContactShareViewModel) {
// forwardMessageDelegate?.forwardMessageFlowDidCancel()
// }
//}
//@objc
//public protocol CameraFirstCaptureDelegate: AnyObject {
// func cameraFirstCaptureSendFlowDidComplete(_ cameraFirstCaptureSendFlow: CameraFirstCaptureSendFlow)
// func cameraFirstCaptureSendFlowDidCancel(_ cameraFirstCaptureSendFlow: CameraFirstCaptureSendFlow)
//}
//@objc
//public class ForwardMediaSendFlow: NSObject {
// @objc
// public weak var delegate: ForwardMessageDelegate?
//
// var approvedAttachments: [SignalAttachment]?
// var approvalMessageText: String?
//
// var selectedConversations: [ConversationItem] = []
//
// // MARK: Dependencies
//
// var databaseStorage: SDSDatabaseStorage {
// return SSKEnvironment.shared.databaseStorage
// }
//}
////func forwardMessageFlowDidComplete(threads: [TSThread])
////func forwardMessageFlowDidCancel()
//
//extension ForwardMediaSendFlow: SendMediaNavDelegate {
// func sendMediaNavDidCancel(_ sendMediaNavigationController: SendMediaNavigationController) {
// delegate?.forwardMessageFlowDidCancel()
// }
//
// 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
// }
//}
//
//extension ForwardMediaSendFlow: 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?.forwardMessageFlowDidCancel()
// return
// }
//
// let conversations = selectedConversationsForConversationPicker
// SendMediaNavigationController.sendApprovedMedia(conversations: conversations,
// approvalMessageText: self.approvalMessageText,
// approvedAttachments: approvedAttachments)
// .done { threads in
// self.delegate?.forwardMessageFlowDidComplete(threads: threads)
// }.retainUntilComplete()
// }
//}
// MARK: -
extension TSAttachmentStream {
func asSignalAttachmentForSending() throws -> SignalAttachment {
guard let sourceUrl = originalMediaURL else {
throw OWSAssertionError("Missing originalMediaURL.")
}
guard let dataUTI = MIMETypeUtil.utiType(forMIMEType: contentType) else {
throw OWSAssertionError("Missing dataUTI.")
}
let newUrl = OWSFileSystem.temporaryFileUrl(fileExtension: sourceUrl.pathExtension)
try FileManager.default.copyItem(at: sourceUrl, to: newUrl)
let clonedDataSource = try DataSourcePath.dataSource(with: newUrl,
shouldDeleteOnDeallocation: true)
clonedDataSource.sourceFilename = sourceFilename
var signalAttachment: SignalAttachment
if isVoiceMessage {
signalAttachment = SignalAttachment.voiceMessageAttachment(dataSource: clonedDataSource, dataUTI: dataUTI)
} else {
signalAttachment = SignalAttachment.attachment(dataSource: clonedDataSource, dataUTI: dataUTI, imageQuality: .original)
}
signalAttachment.captionText = caption
return signalAttachment
}
}

View File

@ -0,0 +1,86 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
import Foundation
import PromiseKit
extension SendMediaNavigationController {
// MARK: Dependencies
class var databaseStorage: SDSDatabaseStorage {
return SSKEnvironment.shared.databaseStorage
}
class var broadcastMediaMessageJobQueue: BroadcastMediaMessageJobQueue {
return AppEnvironment.shared.broadcastMediaMessageJobQueue
}
// MARK: -
class func sendApprovedMedia(conversations: [ConversationItem],
approvalMessageText: String?,
approvedAttachments: [SignalAttachment]) -> Promise<[TSThread]> {
return DispatchQueue.global().async(.promise) {
// Duplicate attachments per conversation
let conversationAttachments: [(ConversationItem, [SignalAttachment])] =
try conversations.map { conversation in
return (conversation, try approvedAttachments.map { try $0.cloneAttachment() })
}
// We only upload one set of attachments, and then copy the upload details into
// each conversation before sending.
let attachmentsToUpload: [OutgoingAttachmentInfo] = approvedAttachments.map { attachment in
return OutgoingAttachmentInfo(dataSource: attachment.dataSource,
contentType: attachment.mimeType,
sourceFilename: attachment.filenameOrDefault,
caption: attachment.captionText,
albumMessageId: nil)
}
var threads: [TSThread] = []
self.databaseStorage.write { transaction in
var messages: [TSOutgoingMessage] = []
for (conversation, attachments) in conversationAttachments {
let thread: TSThread
switch conversation.messageRecipient {
case .contact(let address):
thread = TSContactThread.getOrCreateThread(withContactAddress: address,
transaction: transaction)
case .group(let groupThread):
thread = groupThread
}
let message = try! ThreadUtil.createUnsentMessage(withText: approvalMessageText,
mediaAttachments: attachments,
in: thread,
quotedReplyModel: nil,
linkPreviewDraft: nil,
transaction: transaction)
messages.append(message)
threads.append(thread)
}
// map of attachments we'll upload to their copies in each recipient thread
var attachmentIdMap: [String: [String]] = [:]
let correspondingAttachmentIds = transpose(messages.map { $0.attachmentIds })
for (index, attachmentInfo) in attachmentsToUpload.enumerated() {
do {
let attachmentToUpload = try attachmentInfo.asStreamConsumingDataSource(withIsVoiceMessage: false)
attachmentToUpload.anyInsert(transaction: transaction)
attachmentIdMap[attachmentToUpload.uniqueId] = correspondingAttachmentIds[index]
} catch {
owsFailDebug("error: \(error)")
}
}
self.broadcastMediaMessageJobQueue.add(attachmentIdMap: attachmentIdMap,
transaction: transaction)
}
return threads
}
}
}

View File

@ -18,6 +18,8 @@ protocol SendMediaNavDelegate: AnyObject {
var sendMediaNavTextInputContextIdentifier: String? { get }
}
// MARK: -
@objc
class SendMediaNavigationController: OWSNavigationController {
@ -289,7 +291,7 @@ class SendMediaNavigationController: OWSNavigationController {
// MARK: State
private var attachmentDraftCollection: AttachmentDraftCollection = .empty
fileprivate var attachmentDraftCollection: AttachmentDraftCollection = .empty
private var attachmentApprovalItemPromises: [Promise<AttachmentApprovalItem>] {
return attachmentDraftCollection.attachmentApprovalItemPromises
@ -311,7 +313,7 @@ class SendMediaNavigationController: OWSNavigationController {
return vc
}()
private func pushApprovalViewController(
fileprivate func pushApprovalViewController(
attachmentApprovalItems: [AttachmentApprovalItem],
options: AttachmentApprovalViewControllerOptions = .canAddMore,
animated: Bool
@ -586,6 +588,7 @@ extension SendMediaNavigationController: AttachmentApprovalViewControllerDelegat
private enum AttachmentDraft {
case camera(attachment: CameraCaptureAttachment)
case picker(attachment: MediaLibraryAttachment)
// case forward(attachment: MediaForwardAttachment)
}
private extension AttachmentDraft {
@ -708,6 +711,26 @@ private struct MediaLibraryAttachment: Hashable, Equatable {
}
}
//private struct MediaForwardAttachment: Hashable, Equatable {
// let signalAttachment: SignalAttachment
// let attachmentApprovalItem: AttachmentApprovalItem
// let attachmentApprovalItemPromise: Promise<AttachmentApprovalItem>
//
// init(signalAttachment: SignalAttachment, canSave: Bool) {
// self.signalAttachment = signalAttachment
// self.attachmentApprovalItem = AttachmentApprovalItem(attachment: signalAttachment, canSave: canSave)
// self.attachmentApprovalItemPromise = Promise.value(attachmentApprovalItem)
// }
//
// func hash(into hasher: inout Hasher) {
// hasher.combine(signalAttachment)
// }
//
// static func ==(lhs: MediaForwardAttachment, rhs: MediaForwardAttachment) -> Bool {
// return lhs.signalAttachment == rhs.signalAttachment
// }
//}
extension SendMediaNavigationController: DoneButtonDelegate {
var doneButtonCount: Int {
return attachmentCount
@ -830,3 +853,51 @@ class CaptureFirstCaptureNavigationController: SendMediaNavigationController {
return navController
}
}
// MARK: -
//@objc
//class ForwardMediaNavigationController: SendMediaNavigationController {
//// delegate: SendMediaNavDelegate
//// @objc
//// private(set) var cameraFirstCaptureSendFlow: CameraFirstCaptureSendFlow!
// @objc
// public let forwardMediaSendFlow = ForwardMediaSendFlow()
//
// @objc
// public class func forwardMediaModal(attachments: [SignalAttachment]) -> ForwardMediaNavigationController {
// let navController = ForwardMediaNavigationController()
//
// navController.sendMediaNavDelegate = navController.forwardMediaSendFlow
//
// var attachmentApprovalItems = [AttachmentApprovalItem]()
// for attachment in attachments {
// let cameraCaptureAttachment = CameraCaptureAttachment(signalAttachment: attachment, canSave: false)
// navController.attachmentDraftCollection.append(.camera(attachment: cameraCaptureAttachment))
// attachmentApprovalItems.append(cameraCaptureAttachment.attachmentApprovalItem)
// }
//// let approvalItem = AttachmentApprovalItem(attachment: attachment, canSave: false)
//// let libraryMedia = MediaLibraryAttachment(asset: asset,
//// attachmentApprovalItemPromise: .value(approvalItem))
//// navController.attachmentDraftCollection.append(.picker(attachment: libraryMedia))
//
//// navController.setViewControllers([navController.mediaLibraryViewController], animated: false)
//
// // Since we're starting on the approval view, include cancel to allow the user to immediately dismiss.
// // If they choose to add more, `hasCancel` will go away and they'll enter the normal gallery flow.
// navController.pushApprovalViewController(
// attachmentApprovalItems: attachmentApprovalItems,
// options: [.canAddMore, .hasCancel],
// animated: false
// )
//
//
//// navController.setViewControllers([navController.captureViewController], animated: false)
//
//// let cameraFirstCaptureSendFlow = CameraFirstCaptureSendFlow()
//// navController.cameraFirstCaptureSendFlow = cameraFirstCaptureSendFlow
//// navController.sendMediaNavDelegate = cameraFirstCaptureSendFlow
//
// return navController
// }
//}