From e9af6ec5412e1c1619484b655e50847a8a4ece4a Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Sat, 6 May 2023 13:52:57 +0300 Subject: [PATCH] Improve media uploading content type selection. Fix pasting in screenshots not working --- .../Other/Extensions/NSItemProvider.swift | 26 ++++++++++++++++--- .../PhotoLibraryPicker.swift | 2 +- .../RoomScreen/RoomScreenViewModel.swift | 6 ++--- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/ElementX/Sources/Other/Extensions/NSItemProvider.swift b/ElementX/Sources/Other/Extensions/NSItemProvider.swift index 3de31a1cd..469c4e8b0 100644 --- a/ElementX/Sources/Other/Extensions/NSItemProvider.swift +++ b/ElementX/Sources/Other/Extensions/NSItemProvider.swift @@ -15,12 +15,30 @@ // import Foundation +import UniformTypeIdentifiers extension NSItemProvider { var isSupportedForPasteOrDrop: Bool { - !registeredContentTypes - .compactMap(\.preferredMIMEType) - .filter { $0.hasPrefix("image/") || $0.hasPrefix("video/") || $0.hasPrefix("application/") } - .isEmpty + preferredContentType != nil + } + + var preferredContentType: UTType? { + let supportedContentTypes = registeredContentTypes + .filter { isMimeTypeSupported($0.preferredMIMEType) } + + // Have .jpeg take priority over .heic + if supportedContentTypes.contains(.jpeg) { + return .jpeg + } + + return supportedContentTypes.first + } + + private func isMimeTypeSupported(_ mimeType: String?) -> Bool { + guard let mimeType else { + return false + } + + return mimeType.hasPrefix("image/") || mimeType.hasPrefix("video/") || mimeType.hasPrefix("application/") } } diff --git a/ElementX/Sources/Screens/MediaPickerScreen/PhotoLibraryPicker.swift b/ElementX/Sources/Screens/MediaPickerScreen/PhotoLibraryPicker.swift index 5e0a92c4f..38c4a5a87 100644 --- a/ElementX/Sources/Screens/MediaPickerScreen/PhotoLibraryPicker.swift +++ b/ElementX/Sources/Screens/MediaPickerScreen/PhotoLibraryPicker.swift @@ -62,7 +62,7 @@ struct PhotoLibraryPicker: UIViewControllerRepresentable { func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { guard let provider = results.first?.itemProvider, - let contentType = provider.registeredContentTypes.filter({ $0.conforms(to: .image) || $0.conforms(to: .movie) || $0.conforms(to: .video) }).first else { + let contentType = provider.preferredContentType else { photoLibraryPicker.callback(.cancel) return } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index 427246233..2e720b0aa 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -335,8 +335,8 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol // Pasting and dropping private func handlePasteOrDrop(_ provider: NSItemProvider) { - guard let type = provider.registeredContentTypes.first, - let preferredExtension = type.preferredFilenameExtension else { + guard let contentType = provider.preferredContentType, + let preferredExtension = contentType.preferredFilenameExtension else { MXLog.error("Invalid NSItemProvider: \(provider)") displayError(.toast(L10n.screenRoomErrorFailedProcessingMedia)) return @@ -345,7 +345,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol let providerSuggestedName = provider.suggestedName let providerDescription = provider.description - _ = provider.loadDataRepresentation(for: type) { data, error in + _ = provider.loadDataRepresentation(for: contentType) { data, error in Task { @MainActor in let loadingIndicatorIdentifier = UUID().uuidString ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: loadingIndicatorIdentifier, type: .modal, title: L10n.commonLoading, persistent: true))