Преглед изворни кода

Merge pull request #1251 from deltachat/fix_share_to_dc

Fix share to dc
cyBerta пре 4 година
родитељ
комит
391c7183c9

+ 2 - 1
DcShare/Controller/ShareViewController.swift

@@ -90,7 +90,7 @@ class ShareViewController: SLComposeServiceViewController {
                 if let chatId = selectedChatId {
                     selectedChat = dcContext.getChat(chatId: chatId)
                 }
-                DispatchQueue.global(qos: .background).async {
+                DispatchQueue.global(qos: .userInitiated).async {
                     self.shareAttachment = ShareAttachment(dcContext: self.dcContext, inputItems: self.extensionContext?.inputItems, delegate: self)
                 }
             }
@@ -203,6 +203,7 @@ extension ShareViewController: ShareAttachmentDelegate {
             } else {
                 self.textView.text = "\(url.absoluteString)"
             }
+            self.validateContent()
         }
     }
 

+ 2 - 2
DcShare/Helper/ShareAttachment.swift

@@ -102,9 +102,9 @@ class ShareAttachment {
             case let image as UIImage:
                 result = image
             case let data as Data:
-                result = SDAnimatedImage(data: data)
+                result = ImageFormat.loadImageFrom(data: data)
             case let url as URL:
-                result = SDAnimatedImage(contentsOfFile: url.path)
+                result = ImageFormat.loadImageFrom(url: url)
             default:
                 self.dcContext.logger?.debug("Unexpected data: \(type(of: data))")
                 result = nil

+ 6 - 0
deltachat-ios.xcodeproj/project.pbxproj

@@ -58,6 +58,8 @@
 		306011B622E5E7FB00C1CE6F /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 306011B422E5E7FB00C1CE6F /* Localizable.stringsdict */; };
 		30653081254358B10093E196 /* QuoteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30653080254358B10093E196 /* QuoteView.swift */; };
 		3067AA4C2666310E00525036 /* ChatInputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3067AA4B2666310E00525036 /* ChatInputTextView.swift */; };
+		3067AAC62667F3FE00525036 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3067AAC52667F3FE00525036 /* ImageFormat.swift */; };
+		3067AAC72667F3FE00525036 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3067AAC52667F3FE00525036 /* ImageFormat.swift */; };
 		306C32322445CDE9001D89F3 /* DcLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306C32312445CDE9001D89F3 /* DcLogger.swift */; };
 		30734326249A280B00BF9AD1 /* MediaQualityController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30734325249A280B00BF9AD1 /* MediaQualityController.swift */; };
 		307A82CC25B8D26700748B57 /* ChatEditingBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307A82CB25B8D26700748B57 /* ChatEditingBar.swift */; };
@@ -302,6 +304,7 @@
 		306011C922E5E83500C1CE6F /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
 		30653080254358B10093E196 /* QuoteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuoteView.swift; sourceTree = "<group>"; };
 		3067AA4B2666310E00525036 /* ChatInputTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInputTextView.swift; sourceTree = "<group>"; };
+		3067AAC52667F3FE00525036 /* ImageFormat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageFormat.swift; sourceTree = "<group>"; };
 		306C32312445CDE9001D89F3 /* DcLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DcLogger.swift; sourceTree = "<group>"; };
 		30734325249A280B00BF9AD1 /* MediaQualityController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaQualityController.swift; sourceTree = "<group>"; };
 		307A82CB25B8D26700748B57 /* ChatEditingBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatEditingBar.swift; sourceTree = "<group>"; };
@@ -814,6 +817,7 @@
 		AE851AC2227C695000ED86F0 /* Helper */ = {
 			isa = PBXGroup;
 			children = (
+				3067AAC52667F3FE00525036 /* ImageFormat.swift */,
 				305702A024C6453700D84EFC /* TypeAlias.swift */,
 				AEACE2E21FB32B5C00DCDD78 /* Constants.swift */,
 				AEACE2E41FB32E1900DCDD78 /* Utils.swift */,
@@ -1229,6 +1233,7 @@
 				30E8F2132447285600CE2C90 /* ShareViewController.swift in Sources */,
 				30152C9A25A5D92200377714 /* DetectorType.swift in Sources */,
 				30152CA025A5D97900377714 /* UIEdgeInsets+Extensions.swift in Sources */,
+				3067AAC72667F3FE00525036 /* ImageFormat.swift in Sources */,
 				30E8F253244DAD0E00CE2C90 /* SendingController.swift in Sources */,
 				3057028C24C5E7B600D84EFC /* ContactCellViewModel.swift in Sources */,
 				30152C9425A5D91400377714 /* PaddingTextView.swift in Sources */,
@@ -1301,6 +1306,7 @@
 				AEF53BD5248904BF00D309C1 /* GalleryTimeLabel.swift in Sources */,
 				AEE6EC482283045D00EDC689 /* EditSettingsController.swift in Sources */,
 				30653081254358B10093E196 /* QuoteView.swift in Sources */,
+				3067AAC62667F3FE00525036 /* ImageFormat.swift in Sources */,
 				30E348DF24F3F819005C93D1 /* ChatTableView.swift in Sources */,
 				30EF7308252F6A3300E2C54A /* PaddingTextView.swift in Sources */,
 				30E348E124F53772005C93D1 /* ImageTextCell.swift in Sources */,

+ 70 - 0
deltachat-ios/Helper/ImageFormat.swift

@@ -0,0 +1,70 @@
+import Foundation
+import UIKit
+import SDWebImage
+
+enum ImageFormat: String {
+    case png, jpg, gif, tiff, webp, heic, bmp, unknown
+}
+
+extension ImageFormat {
+
+    // magic bytes can be found here: https://en.wikipedia.org/wiki/List_of_file_signatures
+    static func get(from data: Data) -> ImageFormat {
+        switch data[0] {
+        case 0x89:
+            return .png
+        case 0xFF:
+            return .jpg
+        case 0x47:
+            return .gif
+        case 0x49, 0x4D:
+            return .tiff
+        case 0x52 where data.count >= 12:
+            let subdata = data[0...11]
+
+            if let dataString = String(data: subdata, encoding: .ascii),
+                dataString.hasPrefix("RIFF"),
+                dataString.hasSuffix("WEBP") {
+                return .webp
+            }
+
+        case 0x00 where data.count >= 12 :
+            let subdata = data[8...11]
+
+            if let dataString = String(data: subdata, encoding: .ascii),
+                Set(["heic", "heix", "hevc", "hevx"]).contains(dataString) {
+                return .heic
+            }
+
+        case 0x42 where data.count >= 2 :
+            if data[1] == 0x4D {
+                return .bmp
+            }
+
+        default:
+            break
+        }
+        return .unknown
+    }
+
+
+    // Theoretically, SDAnimatedImage should be able to read data of all kinds of images.
+    // In practive, JPG files haven't been read correctly, for now we're using SDAnimatedImage
+    // only for file formats that support animated content.
+    static func loadImageFrom(data: Data) -> UIImage? {
+        switch ImageFormat.get(from: data) {
+        case .gif, .png, .webp, .heic:
+            return SDAnimatedImage(data: data)
+        default:
+            return UIImage(data: data)
+        }
+    }
+
+    static func loadImageFrom(url: URL) -> UIImage? {
+        guard let imageData = try? Data(contentsOf: url) else {
+            return nil
+        }
+        return loadImageFrom(data: imageData)
+    }
+
+}

+ 4 - 22
deltachat-ios/Model/GalleryItem.swift

@@ -42,36 +42,18 @@ class GalleryItem: ContextMenuItem {
             return
         }
         switch viewtype {
-        case .image:
-            if url.pathExtension == "webp" {
-                loadAsyncSDImageThumbnail(from: url)
-            } else {
-                loadAsyncUIImageThumbnail(from: url)
-            }
+        case .image, .gif:
+            loadImageThumbnail(from: url)
         case .video:
             loadVideoThumbnail(from: url)
-        case .gif:
-            loadAsyncSDImageThumbnail(from: url)
         default:
             safe_fatalError("unsupported viewtype - viewtype \(viewtype) not supported.")
         }
     }
 
-    private func loadAsyncUIImageThumbnail(from url: URL) {
+    private func loadImageThumbnail(from url: URL) {
         DispatchQueue.global(qos: .userInteractive).async {
-            guard let imageData = try? Data(contentsOf: url) else {
-                return
-            }
-            let image = UIImage(data: imageData)
-            DispatchQueue.main.async { [weak self] in
-                    self?.thumbnailImage = image
-            }
-        }
-    }
-
-    private func loadAsyncSDImageThumbnail(from url: URL) {
-        DispatchQueue.global(qos: .userInteractive).async { [weak self] in
-            let image = SDAnimatedImage(contentsOfFile: url.path)
+            let image = ImageFormat.loadImageFrom(url: url)
             DispatchQueue.main.async { [weak self] in
                     self?.thumbnailImage = image
             }