diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 809d9f165..61ff20d9f 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -49,6 +49,16 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc } // MARK: Attachments + func didPasteImageFromPasteboard(_ image: UIImage) { + guard let imageData = image.jpegData(compressionQuality: 1.0) else { return } + let dataSource = DataSourceValue.dataSource(with: imageData, utiType: kUTTypeJPEG as String) + let attachment = SignalAttachment.attachment(dataSource: dataSource, dataUTI: kUTTypeJPEG as String, imageQuality: .medium) + + let approvalVC = AttachmentApprovalViewController.wrappedInNavController(attachments: [ attachment ], approvalDelegate: self) + approvalVC.modalPresentationStyle = .fullScreen + self.present(approvalVC, animated: true, completion: nil) + } + func sendMediaNavDidCancel(_ sendMediaNavigationController: SendMediaNavigationController) { dismiss(animated: true, completion: nil) } diff --git a/Session/Conversations/Input View/InputTextView.swift b/Session/Conversations/Input View/InputTextView.swift index 57546e407..69c61da67 100644 --- a/Session/Conversations/Input View/InputTextView.swift +++ b/Session/Conversations/Input View/InputTextView.swift @@ -37,6 +37,22 @@ public final class InputTextView : UITextView, UITextViewDelegate { public required init?(coder: NSCoder) { preconditionFailure("Use init(delegate:) instead.") } + + public override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { + if action == #selector(paste(_:)) { + if let _ = UIPasteboard.general.image { + return true + } + } + return super.canPerformAction(action, withSender: sender) + } + + public override func paste(_ sender: Any?) { + if let image = UIPasteboard.general.image { + snDelegate?.didPasteImageFromPasteboard(self, image: image) + } + super.paste(sender) + } private func setUpViewHierarchy() { showsHorizontalScrollIndicator = false @@ -80,4 +96,5 @@ protocol InputTextViewDelegate : AnyObject { func inputTextViewDidChangeSize(_ inputTextView: InputTextView) func inputTextViewDidChangeContent(_ inputTextView: InputTextView) + func didPasteImageFromPasteboard(_ inputTextView: InputTextView, image: UIImage) } diff --git a/Session/Conversations/Input View/InputView.swift b/Session/Conversations/Input View/InputView.swift index 599af7599..9b78dc9e6 100644 --- a/Session/Conversations/Input View/InputView.swift +++ b/Session/Conversations/Input View/InputView.swift @@ -143,6 +143,10 @@ final class InputView : UIView, InputViewButtonDelegate, InputTextViewDelegate, autoGenerateLinkPreviewIfPossible() delegate?.inputTextViewDidChangeContent(inputTextView) } + + func didPasteImageFromPasteboard(_ inputTextView: InputTextView, image: UIImage) { + delegate?.didPasteImageFromPasteboard(image) + } // We want to show either a link preview or a quote draft, but never both at the same time. When trying to // generate a link preview, wait until we're sure that we'll be able to build a link preview from the given @@ -351,4 +355,5 @@ protocol InputViewDelegate : AnyObject, ExpandingAttachmentsButtonDelegate, Voic func handleQuoteViewCancelButtonTapped() func inputTextViewDidChangeContent(_ inputTextView: InputTextView) func handleMentionSelected(_ mention: Mention, from view: MentionSelectionView) + func didPasteImageFromPasteboard(_ image: UIImage) } diff --git a/SignalUtilitiesKit/Media Viewing & Editing/Image Editing/ImageEditorCanvasView.swift b/SignalUtilitiesKit/Media Viewing & Editing/Image Editing/ImageEditorCanvasView.swift index 12fae43f5..92e4f93c1 100644 --- a/SignalUtilitiesKit/Media Viewing & Editing/Image Editing/ImageEditorCanvasView.swift +++ b/SignalUtilitiesKit/Media Viewing & Editing/Image Editing/ImageEditorCanvasView.swift @@ -166,7 +166,7 @@ public class ImageEditorCanvasView: UIView { // of code simplicity. We could modify the image layer's // transform to handle the normalization, which would // have perf benefits. - return srcImage + return srcImage.normalized() } // MARK: - Content