diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index d2cd2687e..5aa5b0bd3 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -2,6 +2,7 @@ import UIKit import CoreServices import Photos import PhotosUI +import SessionUtilitiesKit import SignalUtilitiesKit extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuActionDelegate, ScrollToBottomButtonDelegate, @@ -487,7 +488,18 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc let thread = self.thread as? TSContactThread, Storage.shared.getContact(with: thread.contactSessionID())?.isTrusted != true { confirmDownload() - } else { + } + else if ( + viewItem.attachmentStream?.isText == true || + viewItem.attachmentStream?.isMicrosoftDoc == true || + viewItem.attachmentStream?.contentType == OWSMimeTypeApplicationPdf + ), let filePathString: String = viewItem.attachmentStream?.originalFilePath { + let fileUrl: URL = URL(fileURLWithPath: filePathString) + let interactionController: UIDocumentInteractionController = UIDocumentInteractionController(url: fileUrl) + interactionController.delegate = self + interactionController.presentPreview(animated: true) + } + else { // Open the document if possible guard let url = viewItem.attachmentStream?.originalMediaURL else { return } let shareVC = UIActivityViewController(activityItems: [ url ], applicationActivities: nil) @@ -1008,3 +1020,11 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc } } } + +// MARK: - UIDocumentInteractionControllerDelegate + +extension ConversationVC: UIDocumentInteractionControllerDelegate { + func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController { + return self + } +} diff --git a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h index 89f3b4aae..d8f0d8936 100644 --- a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h +++ b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h @@ -84,6 +84,8 @@ typedef NS_ENUM(NSUInteger, TSAttachmentType) { @property (nonatomic, readonly) BOOL isAudio; @property (nonatomic, readonly) BOOL isVoiceMessage; @property (nonatomic, readonly) BOOL isVisualMedia; +@property (nonatomic, readonly) BOOL isText; +@property (nonatomic, readonly) BOOL isMicrosoftDoc; @property (nonatomic, readonly) BOOL isOversizeText; + (NSString *)emojiForMimeType:(NSString *)contentType; diff --git a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.m b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.m index e32418bdf..f3722bd80 100644 --- a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.m +++ b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.m @@ -3,6 +3,14 @@ #import "TSAttachmentPointer.h" #import +#if TARGET_OS_IPHONE +#import + +#else +#import + +#endif + NS_ASSUME_NONNULL_BEGIN NSUInteger const TSAttachmentSchemaVersion = 4; @@ -229,6 +237,14 @@ NSUInteger const TSAttachmentSchemaVersion = 4; return [MIMETypeUtil isVisualMedia:self.contentType]; } +- (BOOL)isText { + return [MIMETypeUtil isText:self.contentType]; +} + +- (BOOL)isMicrosoftDoc { + return [MIMETypeUtil isMicrosoftDoc:self.contentType]; +} + - (BOOL)isOversizeText { return [self.contentType isEqualToString:OWSMimeTypeOversizeTextMessage]; diff --git a/SessionUtilitiesKit/Media/MIMETypeUtil.h b/SessionUtilitiesKit/Media/MIMETypeUtil.h index 1c12bc7fa..6b09c6437 100644 --- a/SessionUtilitiesKit/Media/MIMETypeUtil.h +++ b/SessionUtilitiesKit/Media/MIMETypeUtil.h @@ -4,6 +4,7 @@ NS_ASSUME_NONNULL_BEGIN extern NSString *const OWSMimeTypeApplicationOctetStream; extern NSString *const OWSMimeTypeApplicationZip; +extern NSString *const OWSMimeTypeApplicationPdf; extern NSString *const OWSMimeTypeImagePng; extern NSString *const OWSMimeTypeImageJpeg; extern NSString *const OWSMimeTypeImageGif; @@ -40,6 +41,8 @@ extern NSString *const kSyncMessageFileExtension; + (BOOL)isImage:(NSString *)contentType; + (BOOL)isVideo:(NSString *)contentType; + (BOOL)isAudio:(NSString *)contentType; ++ (BOOL)isText:(NSString *)contentType; ++ (BOOL)isMicrosoftDoc:(NSString *)contentType; + (BOOL)isVisualMedia:(NSString *)contentType; // filename is optional and should not be trusted. diff --git a/SessionUtilitiesKit/Media/MIMETypeUtil.m b/SessionUtilitiesKit/Media/MIMETypeUtil.m index d2024d6ad..d1aa2ce6c 100644 --- a/SessionUtilitiesKit/Media/MIMETypeUtil.m +++ b/SessionUtilitiesKit/Media/MIMETypeUtil.m @@ -22,6 +22,7 @@ NSString *const OWSMimeTypeImageBmp2 = @"image/x-windows-bmp"; NSString *const OWSMimeTypeOversizeTextMessage = @"text/x-signal-plain"; NSString *const OWSMimeTypeUnknownForTests = @"unknown/mimetype"; NSString *const OWSMimeTypeApplicationZip = @"application/zip"; +NSString *const OWSMimeTypeApplicationPdf = @"application/pdf"; NSString *const kOversizeTextAttachmentUTI = @"org.whispersystems.oversize-text-attachment"; NSString *const kOversizeTextAttachmentFileExtension = @"txt"; @@ -278,6 +279,53 @@ NSString *const kSyncMessageFileExtension = @"bin"; return [MIMETypeUtil isSupportedAudioMIMEType:contentType]; } ++ (BOOL)isText:(NSString *)contentType { + return [ + @[ + @"text/plain", + @"text/csv", + @"text/tab-separated-values" + ] + containsObject:contentType + ]; +} + ++ (BOOL)isMicrosoftDoc:(NSString *)contentType { + return [ + @[ + // Word files + @"application/msword", + + @"application/vnd.openxmlformats-officedocument.wordprocessingml.document", + @"application/vnd.openxmlformats-officedocument.wordprocessingml.template", + @"application/vnd.ms-word.document.macroEnabled.12", + @"application/vnd.ms-word.template.macroEnabled.12", + + // Excel files + @"application/vnd.ms-excel", + + @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + @"application/vnd.openxmlformats-officedocument.spreadsheetml.template", + @"application/vnd.ms-excel.sheet.macroEnabled.12", + @"application/vnd.ms-excel.template.macroEnabled.12", + @"application/vnd.ms-excel.addin.macroEnabled.12", + @"application/vnd.ms-excel.sheet.binary.macroEnabled.12", + + // Powerpoint files + @"application/vnd.ms-powerpoint", + + @"application/vnd.openxmlformats-officedocument.presentationml.presentation", + @"application/vnd.openxmlformats-officedocument.presentationml.template", + @"application/vnd.openxmlformats-officedocument.presentationml.slideshow", + @"application/vnd.ms-powerpoint.addin.macroEnabled.12", + @"application/vnd.ms-powerpoint.presentation.macroEnabled.12", + @"application/vnd.ms-powerpoint.template.macroEnabled.12", + @"application/vnd.ms-powerpoint.slideshow.macroEnabled.12" + ] + containsObject:contentType + ]; +} + + (BOOL)isVisualMedia:(NSString *)contentType { if ([self isImage:contentType]) {