From b85c113da62b4f57ec8a28faa498abb579a94248 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Fri, 28 Jan 2022 16:24:18 +1100 Subject: [PATCH 1/4] 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 140cc978299b85c9e150ab40f5c52a9d690cbcc7 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Fri, 11 Feb 2022 13:05:10 +1100 Subject: [PATCH 2/4] Fixed a couple of bugs with the share extension Fixed a bug where sharing a text file was resulting in the entire contents being put into the message input field Fixed a bug where sharing from within the app where the app was in dark mode but the device was in light mode would result in buggy UI --- Session/Meta/AppDelegate.m | 12 +++------- Session/Meta/AppDelegate.swift | 16 -------------- .../Attachments/SignalAttachment.swift | 7 +++++- SessionShareExtension/ShareVC.swift | 9 -------- SessionShareExtension/ThreadPickerVC.swift | 5 +++++ SessionUIKit/Style Guide/AppMode.swift | 22 +++++++++++++++---- 6 files changed, 32 insertions(+), 39 deletions(-) diff --git a/Session/Meta/AppDelegate.m b/Session/Meta/AppDelegate.m index 000af7460..1f31d6604 100644 --- a/Session/Meta/AppDelegate.m +++ b/Session/Meta/AppDelegate.m @@ -194,7 +194,7 @@ static NSTimeInterval launchStartedAt; mainWindow.rootViewController = [LoadingViewController new]; [mainWindow makeKeyAndVisible]; - LKAppMode appMode = [self getCurrentAppMode]; + LKAppMode appMode = [LKAppModeManager getAppModeOrSystemDefault]; [self adaptAppMode:appMode]; if (@available(iOS 11, *)) { @@ -245,7 +245,7 @@ static NSTimeInterval launchStartedAt; [self ensureRootViewController]; - LKAppMode appMode = [self getCurrentAppMode]; + LKAppMode appMode = [LKAppModeManager getAppModeOrSystemDefault]; [self adaptAppMode:appMode]; [AppReadiness runNowOrWhenAppDidBecomeReady:^{ @@ -734,12 +734,6 @@ static NSTimeInterval launchStartedAt; [NSNotificationCenter.defaultCenter postNotificationName:NSNotification.appModeChanged object:nil]; } -- (LKAppMode)getCurrentAppMode -{ - LKAppMode appMode = [self getAppModeOrSystemDefault]; - return appMode; -} - - (void)setCurrentAppMode:(LKAppMode)appMode { [NSUserDefaults.standardUserDefaults setInteger:appMode forKey:@"appMode"]; @@ -749,7 +743,7 @@ static NSTimeInterval launchStartedAt; - (void)setAppModeToSystemDefault { [NSUserDefaults.standardUserDefaults removeObjectForKey:@"appMode"]; - LKAppMode appMode = [self getCurrentAppMode]; + LKAppMode appMode = [LKAppModeManager getAppModeOrSystemDefault]; [self adaptAppMode:appMode]; } diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index bb28b0b81..56e4100b2 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -40,20 +40,4 @@ extension AppDelegate { @objc func stopClosedGroupPoller() { ClosedGroupPoller.shared.stop() } - - @objc func getAppModeOrSystemDefault() -> AppMode { - let userDefaults = UserDefaults.standard - - guard userDefaults.dictionaryRepresentation().keys.contains("appMode") else { - if #available(iOS 13.0, *) { - return UITraitCollection.current.userInterfaceStyle == .dark ? .dark : .light - } else { - return .light - } - } - - let mode = userDefaults.integer(forKey: "appMode") - return AppMode(rawValue: mode) ?? .light - } - } diff --git a/SessionMessagingKit/Sending & Receiving/Attachments/SignalAttachment.swift b/SessionMessagingKit/Sending & Receiving/Attachments/SignalAttachment.swift index f65d8640c..0087c3663 100644 --- a/SessionMessagingKit/Sending & Receiving/Attachments/SignalAttachment.swift +++ b/SessionMessagingKit/Sending & Receiving/Attachments/SignalAttachment.swift @@ -462,7 +462,12 @@ public class SignalAttachment: NSObject { @objc public var isText: Bool { - return UTTypeConformsTo(dataUTI as CFString, kUTTypeText) || isOversizeText + return ( + isConvertibleToTextMessage && ( + UTTypeConformsTo(dataUTI as CFString, kUTTypeText) || + isOversizeText + ) + ) } @objc diff --git a/SessionShareExtension/ShareVC.swift b/SessionShareExtension/ShareVC.swift index 1492f8d80..34716c706 100644 --- a/SessionShareExtension/ShareVC.swift +++ b/SessionShareExtension/ShareVC.swift @@ -162,15 +162,6 @@ final class ShareVC : UINavigationController, ShareViewDelegate, AppModeManagerD } // MARK: - App Mode - - public func getCurrentAppMode() -> AppMode { - guard let window = self.view.window else { return .light } - - let userInterfaceStyle = window.traitCollection.userInterfaceStyle - let isLightMode = (userInterfaceStyle == .light || userInterfaceStyle == .unspecified) - - return (isLightMode ? .light : .dark) - } public func setCurrentAppMode(to appMode: AppMode) { return // Not applicable to share extensions diff --git a/SessionShareExtension/ThreadPickerVC.swift b/SessionShareExtension/ThreadPickerVC.swift index 6e4df133a..3e975d51d 100644 --- a/SessionShareExtension/ThreadPickerVC.swift +++ b/SessionShareExtension/ThreadPickerVC.swift @@ -95,6 +95,11 @@ final class ThreadPickerVC: UIViewController, UITableViewDataSource, UITableView } } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + view.setGradient(Gradients.defaultBackground) + fadeView.setGradient(Gradients.homeVCFade) + } + // MARK: Layout private func setupLayout() { diff --git a/SessionUIKit/Style Guide/AppMode.swift b/SessionUIKit/Style Guide/AppMode.swift index 01db04682..e2ad9e75a 100644 --- a/SessionUIKit/Style Guide/AppMode.swift +++ b/SessionUIKit/Style Guide/AppMode.swift @@ -1,11 +1,11 @@ -import Foundation +import UIKit @objc(LKAppModeManager) public final class AppModeManager : NSObject { private let delegate: AppModeManagerDelegate public var currentAppMode: AppMode { - return delegate.getCurrentAppMode() + return AppModeManager.getAppModeOrSystemDefault() } public static var shared: AppModeManager! @@ -29,19 +29,33 @@ public final class AppModeManager : NSObject { public func setAppModeToSystemDefault() { delegate.setAppModeToSystemDefault() } + + @objc public static func getAppModeOrSystemDefault() -> AppMode { + let userDefaults = UserDefaults.standard + + guard userDefaults.dictionaryRepresentation().keys.contains("appMode") else { + if #available(iOS 13.0, *) { + return UITraitCollection.current.userInterfaceStyle == .dark ? .dark : .light + } + + return .light + } + + let mode = userDefaults.integer(forKey: "appMode") + return AppMode(rawValue: mode) ?? .light + } } @objc(LKAppModeManagerDelegate) public protocol AppModeManagerDelegate { - func getCurrentAppMode() -> AppMode @objc(setCurrentAppMode:) func setCurrentAppMode(to appMode: AppMode) func setAppModeToSystemDefault() } @objc(LKAppMode) -public enum AppMode : Int { +public enum AppMode: Int { case light, dark } From 161a90ad286591a514162fae2d79828e29948057 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Mon, 14 Feb 2022 09:54:17 +1100 Subject: [PATCH 3/4] 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 4/4] 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]) {