Message forwarding.
This commit is contained in:
parent
9e3aa77ce2
commit
66c239bbbb
@ -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 */,
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
// }
|
||||
//}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user