From 6a80db784492f9d12620448670c8aadaac4fa1ec Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 10 Jan 2018 16:40:08 -0500 Subject: [PATCH] Enable support for sharing urls in SAE. --- .../attachments/MediaMessageView.swift | 39 +++++++++++++++++++ .../attachments/SignalAttachment.swift | 11 ++++-- .../ShareViewController.swift | 33 ++++++++++++++-- 3 files changed, 76 insertions(+), 7 deletions(-) diff --git a/SignalMessaging/attachments/MediaMessageView.swift b/SignalMessaging/attachments/MediaMessageView.swift index c7750252e..0a55bee89 100644 --- a/SignalMessaging/attachments/MediaMessageView.swift +++ b/SignalMessaging/attachments/MediaMessageView.swift @@ -110,6 +110,8 @@ public class MediaMessageView: UIView, OWSAudioAttachmentPlayerDelegate { createVideoPreview() } else if attachment.isAudio { createAudioPreview() + } else if attachment.isOversizeText { + createTextPreview() } else { createGenericPreview() } @@ -286,6 +288,43 @@ public class MediaMessageView: UIView, OWSAudioAttachmentPlayerDelegate { } } + private func createTextPreview() { + + let data = attachment.data + guard let messageText = String(data: data, encoding: String.Encoding.utf8) else { + createGenericPreview() + return + } + + let messageTextView = UITextView() + messageTextView.font = UIFont.ows_dynamicTypeBody() +// messageTextView.backgroundColor = UIColor.clear + messageTextView.backgroundColor = UIColor.white + messageTextView.isOpaque = false + messageTextView.isEditable = false + messageTextView.isSelectable = true + messageTextView.textContainerInset = UIEdgeInsets.zero + messageTextView.contentInset = UIEdgeInsets.zero + messageTextView.isScrollEnabled = true + messageTextView.showsHorizontalScrollIndicator = false + messageTextView.showsVerticalScrollIndicator = false + messageTextView.isUserInteractionEnabled = false +// messageTextView.textColor = isIncoming ? UIColor.black : UIColor.white + messageTextView.textColor = UIColor.black + messageTextView.text = messageText + + self.addSubview(messageTextView) + messageTextView.autoPinWidthToSuperview() + messageTextView.autoVCenterInSuperview() + + // TODO: How should text messages be displayed in this view? + NSLayoutConstraint.autoSetPriority(UILayoutPriorityDefaultLow) { + messageTextView.autoPinHeightToSuperview() + } + messageTextView.autoPinEdge(toSuperviewEdge: .top, withInset: 0, relation: .greaterThanOrEqual) + messageTextView.autoPinEdge(toSuperviewEdge: .bottom, withInset: 0, relation: .greaterThanOrEqual) + } + private func createGenericPreview() { var subviews = [UIView]() diff --git a/SignalMessaging/attachments/SignalAttachment.swift b/SignalMessaging/attachments/SignalAttachment.swift index cbc700046..53a2942be 100644 --- a/SignalMessaging/attachments/SignalAttachment.swift +++ b/SignalMessaging/attachments/SignalAttachment.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // import Foundation @@ -290,7 +290,7 @@ public class SignalAttachment: NSObject { } } } - if dataUTI == kOversizeTextAttachmentUTI { + if isOversizeText { return OWSMimeTypeOversizeTextMessage } if dataUTI == kUnknownTestAttachmentUTI { @@ -334,7 +334,7 @@ public class SignalAttachment: NSObject { return fileExtension } } - if dataUTI == kOversizeTextAttachmentUTI { + if isOversizeText { return kOversizeTextAttachmentFileExtension } if dataUTI == kUnknownTestAttachmentUTI { @@ -414,6 +414,11 @@ public class SignalAttachment: NSObject { return SignalAttachment.audioUTISet.contains(dataUTI) } + @objc + public var isOversizeText: Bool { + return dataUTI == kOversizeTextAttachmentUTI + } + @objc public class func pasteboardHasPossibleAttachment() -> Bool { return UIPasteboard.general.numberOfItems > 0 diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index c7490a867..bf432bf9b 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -506,14 +506,26 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE Logger.debug("\(self.logTag) building DataSource with url: \(url)") - guard let dataSource = DataSourcePath.dataSource(with: url) else { + var rawDataSource: DataSource? + if utiType == (kUTTypeURL as String) { + let urlString = url.absoluteString + rawDataSource = DataSourceValue.dataSource(withOversizeText:urlString) + } else { + rawDataSource = DataSourcePath.dataSource(with: url) + } + guard let dataSource = rawDataSource else { throw ShareViewControllerError.assertionError(description: "Unable to read attachment data") } - dataSource.sourceFilename = url.lastPathComponent + if utiType != (kUTTypeURL as String) { + dataSource.sourceFilename = url.lastPathComponent + } // start with base utiType, but it might be something generic like "image" var specificUTIType = utiType - if url.pathExtension.count > 0 { + if utiType == (kUTTypeURL as String) { + Logger.debug("\(self.logTag) using text UTI type for URL.") + specificUTIType = kOversizeTextAttachmentUTI as String + } else if url.pathExtension.count > 0 { // Determine a more specific utiType based on file extension if let typeExtension = MIMETypeUtil.utiType(forFileExtension: url.pathExtension) { Logger.debug("\(self.logTag) utiType based on extension: \(typeExtension)") @@ -571,7 +583,20 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE // Perhaps the AVFoundation APIs require some extra file system permssion we don't have in the // passed through URL. private func isVideoNeedingRelocation(itemProvider: NSItemProvider, itemUrl: URL) -> Bool { - guard MIMETypeUtil.utiType(forFileExtension: itemUrl.pathExtension) == kUTTypeMPEG4 as String else { + if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) { + return false + } + + let pathExtension = itemUrl.pathExtension + guard pathExtension.count > 0 else { + Logger.verbose("\(self.logTag) in \(#function): item URL has no file extension: \(itemUrl).") + return false + } + guard let utiTypeForURL = MIMETypeUtil.utiType(forFileExtension: pathExtension) else { + Logger.verbose("\(self.logTag) in \(#function): item has unknown UTI type: \(itemUrl).") + return false + } + guard utiTypeForURL == kUTTypeMPEG4 as String else { // Either it's not a video or it was a video which was not auto-converted to mp4. // Not affected by the issue. return false