From b85c113da62b4f57ec8a28faa498abb579a94248 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Fri, 28 Jan 2022 16:24:18 +1100 Subject: [PATCH 1/3] Added code to preview PDF attachments --- Podfile.lock | 8 ++++---- .../ConversationVC+Interaction.swift | 18 +++++++++++++++++- SessionUtilitiesKit/Media/MIMETypeUtil.h | 1 + SessionUtilitiesKit/Media/MIMETypeUtil.m | 1 + 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index 24d6abeed..d8af51feb 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -132,7 +132,7 @@ DEPENDENCIES: - SignalCoreKit (from `https://github.com/oxen-io/session-ios-core-kit`, branch `session-version`) - Sodium (~> 0.9.1) - SwiftProtobuf (~> 1.5.0) - - YapDatabase/SQLCipher (from `https://github.com/loki-project/session-ios-yap-database.git`, branch `signal-release`) + - YapDatabase/SQLCipher (from `https://github.com/oxen-io/session-ios-yap-database.git`, branch `signal-release`) - YYImage (from `https://github.com/signalapp/YYImage`) - ZXingObjC @@ -163,7 +163,7 @@ EXTERNAL SOURCES: :git: https://github.com/oxen-io/session-ios-core-kit YapDatabase: :branch: signal-release - :git: https://github.com/loki-project/session-ios-yap-database.git + :git: https://github.com/oxen-io/session-ios-yap-database.git YYImage: :git: https://github.com/signalapp/YYImage @@ -179,7 +179,7 @@ CHECKOUT OPTIONS: :git: https://github.com/oxen-io/session-ios-core-kit YapDatabase: :commit: d84069e25e12a16ab4422e5258127a04b70489ad - :git: https://github.com/loki-project/session-ios-yap-database.git + :git: https://github.com/oxen-io/session-ios-yap-database.git YYImage: :commit: 62a4cede20bcf31da73d18163408e46a92f171c6 :git: https://github.com/signalapp/YYImage @@ -204,6 +204,6 @@ SPEC CHECKSUMS: YYImage: f1ddd15ac032a58b78bbed1e012b50302d318331 ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb -PODFILE CHECKSUM: 7722d8a03a0ebc6ecd0070d02b199bd748992f12 +PODFILE CHECKSUM: 7f961dc4934dd213f5a3277af57d54caef7a4442 COCOAPODS: 1.11.2 diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 61ff20d9f..d397dc668 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -1,6 +1,7 @@ import CoreServices import Photos import PhotosUI +import SessionUtilitiesKit extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuActionDelegate, ScrollToBottomButtonDelegate, SendMediaNavDelegate, UIDocumentPickerDelegate, AttachmentApprovalViewControllerDelegate, GifPickerViewControllerDelegate, @@ -463,7 +464,14 @@ 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?.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) @@ -981,3 +989,11 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc OWSAlerts.showAlert(title: title, message: message) } } + +// MARK: - UIDocumentInteractionControllerDelegate + +extension ConversationVC: UIDocumentInteractionControllerDelegate { + func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController { + return self + } +} diff --git a/SessionUtilitiesKit/Media/MIMETypeUtil.h b/SessionUtilitiesKit/Media/MIMETypeUtil.h index 1c12bc7fa..cad42aef8 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; diff --git a/SessionUtilitiesKit/Media/MIMETypeUtil.m b/SessionUtilitiesKit/Media/MIMETypeUtil.m index d2024d6ad..c17e98c3a 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"; From 161a90ad286591a514162fae2d79828e29948057 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 14 Feb 2022 09:54:17 +1100 Subject: [PATCH 2/3] Updated the code to show the document interaction controller for text files as well --- .../Conversations/ConversationVC+Interaction.swift | 2 +- .../Sending & Receiving/Attachments/TSAttachment.h | 1 + .../Sending & Receiving/Attachments/TSAttachment.m | 12 ++++++++++++ SessionUtilitiesKit/Media/MIMETypeUtil.h | 1 + SessionUtilitiesKit/Media/MIMETypeUtil.m | 11 +++++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 00430c187..823423680 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -472,7 +472,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc Storage.shared.getContact(with: thread.contactSessionID())?.isTrusted != true { confirmDownload() } - else if viewItem.attachmentStream?.contentType == OWSMimeTypeApplicationPdf, let filePathString: String = viewItem.attachmentStream?.originalFilePath { + else if (viewItem.attachmentStream?.isText == 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 diff --git a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h index 89f3b4aae..b9ab550f4 100644 --- a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h +++ b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h @@ -84,6 +84,7 @@ 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 isOversizeText; + (NSString *)emojiForMimeType:(NSString *)contentType; diff --git a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.m b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.m index e32418bdf..601eec0f9 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,10 @@ NSUInteger const TSAttachmentSchemaVersion = 4; return [MIMETypeUtil isVisualMedia:self.contentType]; } +- (BOOL)isText { + return [MIMETypeUtil isText:self.contentType]; +} + - (BOOL)isOversizeText { return [self.contentType isEqualToString:OWSMimeTypeOversizeTextMessage]; diff --git a/SessionUtilitiesKit/Media/MIMETypeUtil.h b/SessionUtilitiesKit/Media/MIMETypeUtil.h index cad42aef8..2093b5bf3 100644 --- a/SessionUtilitiesKit/Media/MIMETypeUtil.h +++ b/SessionUtilitiesKit/Media/MIMETypeUtil.h @@ -41,6 +41,7 @@ extern NSString *const kSyncMessageFileExtension; + (BOOL)isImage:(NSString *)contentType; + (BOOL)isVideo:(NSString *)contentType; + (BOOL)isAudio:(NSString *)contentType; ++ (BOOL)isText:(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 c17e98c3a..fb4d15df4 100644 --- a/SessionUtilitiesKit/Media/MIMETypeUtil.m +++ b/SessionUtilitiesKit/Media/MIMETypeUtil.m @@ -279,6 +279,17 @@ NSString *const kSyncMessageFileExtension = @"bin"; return [MIMETypeUtil isSupportedAudioMIMEType:contentType]; } ++ (BOOL)isText:(NSString *)contentType { + return [ + @[ + @"text/plain", + @"text/csv", + @"text/tab-separated-values" + ] + containsObject:contentType + ]; +} + + (BOOL)isVisualMedia:(NSString *)contentType { if ([self isImage:contentType]) { From 1b820c48c645200b8a3cb39c4527ce579d17be2b Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 14 Feb 2022 10:02:33 +1100 Subject: [PATCH 3/3] Added support for Microsoft Word, Excel & Powerpoint previews --- .../ConversationVC+Interaction.swift | 6 +++- .../Attachments/TSAttachment.h | 1 + .../Attachments/TSAttachment.m | 4 +++ SessionUtilitiesKit/Media/MIMETypeUtil.h | 1 + SessionUtilitiesKit/Media/MIMETypeUtil.m | 36 +++++++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 823423680..a802e285b 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -472,7 +472,11 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc Storage.shared.getContact(with: thread.contactSessionID())?.isTrusted != true { confirmDownload() } - else if (viewItem.attachmentStream?.isText == true || viewItem.attachmentStream?.contentType == OWSMimeTypeApplicationPdf), let filePathString: String = viewItem.attachmentStream?.originalFilePath { + 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 diff --git a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h index b9ab550f4..d8f0d8936 100644 --- a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h +++ b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.h @@ -85,6 +85,7 @@ typedef NS_ENUM(NSUInteger, TSAttachmentType) { @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 601eec0f9..f3722bd80 100644 --- a/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.m +++ b/SessionMessagingKit/Sending & Receiving/Attachments/TSAttachment.m @@ -241,6 +241,10 @@ NSUInteger const TSAttachmentSchemaVersion = 4; 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 2093b5bf3..6b09c6437 100644 --- a/SessionUtilitiesKit/Media/MIMETypeUtil.h +++ b/SessionUtilitiesKit/Media/MIMETypeUtil.h @@ -42,6 +42,7 @@ extern NSString *const kSyncMessageFileExtension; + (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 fb4d15df4..d1aa2ce6c 100644 --- a/SessionUtilitiesKit/Media/MIMETypeUtil.m +++ b/SessionUtilitiesKit/Media/MIMETypeUtil.m @@ -290,6 +290,42 @@ NSString *const kSyncMessageFileExtension = @"bin"; ]; } ++ (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]) {