diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index e88e458b4..54f4d1901 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -71,6 +71,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/Session/Conversations/Settings/OWSConversationSettingsViewController.m b/Session/Conversations/Settings/OWSConversationSettingsViewController.m index b703a58ff..345a09bc5 100644 --- a/Session/Conversations/Settings/OWSConversationSettingsViewController.m +++ b/Session/Conversations/Settings/OWSConversationSettingsViewController.m @@ -1025,8 +1025,11 @@ CGFloat kIconViewLength = 24; - (void)saveName { if (![self.thread isKindOfClass:TSContactThread.class]) { return; } - SNContact *contact = [LKStorage.shared getContactWithSessionID:((TSContactThread *)self.thread).contactSessionID]; - if (contact == nil) { return; } + NSString *sessionID = ((TSContactThread *)self.thread).contactSessionID; + SNContact *contact = [LKStorage.shared getContactWithSessionID:sessionID]; + if (contact == nil) { + contact = [[SNContact alloc] initWithSessionID:sessionID]; + } NSString *text = [self.displayNameTextField.text stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet]; contact.nickname = text.length > 0 ? text : nil; [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { diff --git a/Session/Media Viewing & Editing/MediaDetailViewController.m b/Session/Media Viewing & Editing/MediaDetailViewController.m index 1e19acaf4..446000b80 100644 --- a/Session/Media Viewing & Editing/MediaDetailViewController.m +++ b/Session/Media Viewing & Editing/MediaDetailViewController.m @@ -257,7 +257,7 @@ NS_ASSUME_NONNULL_BEGIN self.videoProgressBar = videoProgressBar; [self.view addSubview:videoProgressBar]; [videoProgressBar autoPinWidthToSuperview]; - [videoProgressBar autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:self.view withOffset:0.0f]; + [videoProgressBar autoPinEdgeToSuperviewSafeArea:ALEdgeTop]; CGFloat kVideoProgressBarHeight = 44; [videoProgressBar autoSetDimension:ALDimensionHeight toSize:kVideoProgressBarHeight]; 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