Przeglądaj źródła

Merge pull request #1491 from deltachat/webxdc_drafts

Webxdc drafts
cyBerta 3 lat temu
rodzic
commit
ae57fb87b0

+ 0 - 3
DcCore/DcCore/DC/Wrapper.swift

@@ -1033,9 +1033,6 @@ public class DcMsg {
             return DcMsg(pointer: msgpointer)
         }
         set {
-            if newValue == nil {
-                fatalError("Quote message cannot be set to null!")
-            }
             dc_msg_set_quote(messagePointer, newValue?.messagePointer)
         }
     }

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

@@ -40,7 +40,6 @@
 		303492CB257A814200A523D0 /* DraftArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 303492CA257A814200A523D0 /* DraftArea.swift */; };
 		304219D3243F588500516852 /* DcCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 304219D1243F588500516852 /* DcCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		304219D92440734A00516852 /* DcMsg+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304219D82440734A00516852 /* DcMsg+Extension.swift */; };
-		304A92C127AAE10B00588A15 /* WebxdcPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304A92C027AAE10B00588A15 /* WebxdcPreview.swift */; };
 		304F5E44244F571C00462538 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A9FB14A1FB061E2001FEA36 /* Assets.xcassets */; };
 		304F769525DD237B0094B5E2 /* WebViewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304F769425DD237B0094B5E2 /* WebViewViewController.swift */; };
 		304F769925DD23D70094B5E2 /* FullMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304F769825DD23D70094B5E2 /* FullMessageViewController.swift */; };
@@ -283,7 +282,6 @@
 		303492CA257A814200A523D0 /* DraftArea.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftArea.swift; sourceTree = "<group>"; };
 		304219D1243F588500516852 /* DcCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = DcCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		304219D82440734A00516852 /* DcMsg+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DcMsg+Extension.swift"; sourceTree = "<group>"; };
-		304A92C027AAE10B00588A15 /* WebxdcPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebxdcPreview.swift; sourceTree = "<group>"; };
 		304F769425DD237B0094B5E2 /* WebViewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewViewController.swift; sourceTree = "<group>"; };
 		304F769825DD23D70094B5E2 /* FullMessageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullMessageViewController.swift; sourceTree = "<group>"; };
 		3052C609253F082E007D13EA /* MessageLabelDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageLabelDelegate.swift; sourceTree = "<group>"; };
@@ -740,7 +738,6 @@
 				303492AC2577CAC300A523D0 /* FileView.swift */,
 				303492B22577E40700A523D0 /* DocumentPreview.swift */,
 				303492CA257A814200A523D0 /* DraftArea.swift */,
-				304A92C027AAE10B00588A15 /* WebxdcPreview.swift */,
 			);
 			path = Views;
 			sourceTree = "<group>";
@@ -1411,7 +1408,6 @@
 				304219D92440734A00516852 /* DcMsg+Extension.swift in Sources */,
 				AE52EA19229EB53C00C586C9 /* ContactDetailHeader.swift in Sources */,
 				78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */,
-				304A92C127AAE10B00588A15 /* WebxdcPreview.swift in Sources */,
 				3080A022277DE09900E74565 /* InputTextView.swift in Sources */,
 				30734326249A280B00BF9AD1 /* MediaQualityController.swift in Sources */,
 				3080A01C277DDB8A00E74565 /* InputBarAccessoryViewDelegate.swift in Sources */,

+ 25 - 14
deltachat-ios/Chat/ChatViewController.swift

@@ -7,7 +7,6 @@ import SDWebImage
 
 class ChatViewController: UITableViewController {
     var dcContext: DcContext
-    private var draftMessage: DcMsg?
     let outgoingAvatarOverlap: CGFloat = 17.5
     let loadCount = 30
     let chatId: Int
@@ -1449,6 +1448,11 @@ class ChatViewController: UITableViewController {
                     messageIds.remove(at: newMsgMarkerIndex)
                 }
                 insertMessage(msg)
+            } else if msg.type == DC_MSG_WEBXDC,
+                      msg.chatId == chatId {
+                // webxdc draft got updated
+                draft.draftMsg = msg
+                configureDraftArea(draft: draft, animated: false)
             }
         }
     }
@@ -1478,14 +1482,15 @@ class ChatViewController: UITableViewController {
 
     private func stageDocument(url: NSURL) {
         keepKeyboard = true
-        self.draft.setAttachment(viewType: DC_MSG_FILE, path: url.relativePath)
+        self.draft.setAttachment(viewType: url.pathExtension == "xdc" ? DC_MSG_WEBXDC : DC_MSG_FILE, path: url.relativePath)
         self.configureDraftArea(draft: self.draft)
         self.messageInputBar.inputTextView.becomeFirstResponder()
     }
 
     private func stageVideo(url: NSURL) {
         keepKeyboard = true
-        DispatchQueue.main.async {
+        DispatchQueue.main.async { [weak self] in
+            guard let self = self else { return }
             self.draft.setAttachment(viewType: DC_MSG_VIDEO, path: url.relativePath)
             self.configureDraftArea(draft: self.draft)
             self.messageInputBar.inputTextView.becomeFirstResponder()
@@ -1502,7 +1507,8 @@ class ChatViewController: UITableViewController {
     }
 
     private func stageImage(_ image: UIImage) {
-        DispatchQueue.global().async {
+        DispatchQueue.global().async { [weak self] in
+            guard let self = self else { return }
             if let pathInDocDir = ImageFormat.saveImage(image: image) {
                 DispatchQueue.main.async {
                     if pathInDocDir.suffix(4).contains(".gif") {
@@ -1534,7 +1540,7 @@ class ChatViewController: UITableViewController {
     }
 
     private func sendAttachmentMessage(viewType: Int32, filePath: String, message: String? = nil, quoteMessage: DcMsg? = nil) {
-        let msg = dcContext.newMessage(viewType: viewType)
+        let msg = draft.draftMsg ?? dcContext.newMessage(viewType: viewType)
         msg.setFile(filepath: filePath)
         msg.text = (message ?? "").isEmpty ? nil : message
         if quoteMessage != nil {
@@ -1837,7 +1843,7 @@ extension ChatViewController: InputBarAccessoryViewDelegate {
             .trimmingCharacters(in: .whitespacesAndNewlines)
         if let filePath = draft.attachment, let viewType = draft.viewType {
             switch viewType {
-            case DC_MSG_GIF, DC_MSG_IMAGE, DC_MSG_FILE, DC_MSG_VIDEO:
+            case DC_MSG_GIF, DC_MSG_IMAGE, DC_MSG_FILE, DC_MSG_VIDEO, DC_MSG_WEBXDC:
                 self.sendAttachmentMessage(viewType: viewType, filePath: filePath, message: trimmedText, quoteMessage: draft.quoteMessage)
             default:
                 logger.warning("Unsupported viewType for drafted messages.")
@@ -1850,6 +1856,7 @@ extension ChatViewController: InputBarAccessoryViewDelegate {
         }
         inputBar.inputTextView.text = String()
         inputBar.inputTextView.attributedText = nil
+        draft.clear()
         draftArea.cancel()
     }
 
@@ -1869,7 +1876,7 @@ extension ChatViewController: DraftPreviewDelegate {
 
     func onCancelAttachment() {
         keepKeyboard = true
-        draft.setAttachment(viewType: nil, path: nil, mimetype: nil)
+        draft.clearAttachment()
         configureDraftArea(draft: draft)
         evaluateInputBar(draft: draft)
     }
@@ -1881,14 +1888,18 @@ extension ChatViewController: DraftPreviewDelegate {
     func onAttachmentTapped() {
         if let attachmentPath = draft.attachment {
             let attachmentURL = URL(fileURLWithPath: attachmentPath, isDirectory: false)
-            let previewController = PreviewController(dcContext: dcContext, type: .single(attachmentURL))
-            if #available(iOS 13.0, *), draft.viewType == DC_MSG_IMAGE || draft.viewType == DC_MSG_VIDEO {
-                previewController.setEditing(true, animated: true)
-                previewController.delegate = self
+            if draft.viewType == DC_MSG_WEBXDC, let draftMessage = draft.draftMsg {
+                showWebxdcViewFor(message: draftMessage)
+            } else {
+                let previewController = PreviewController(dcContext: dcContext, type: .single(attachmentURL))
+                if #available(iOS 13.0, *), draft.viewType == DC_MSG_IMAGE || draft.viewType == DC_MSG_VIDEO {
+                    previewController.setEditing(true, animated: true)
+                    previewController.delegate = self
+                }
+                let nav = UINavigationController(rootViewController: previewController)
+                nav.modalPresentationStyle = .fullScreen
+                navigationController?.present(nav, animated: true)
             }
-            let nav = UINavigationController(rootViewController: previewController)
-            nav.modalPresentationStyle = .fullScreen
-            navigationController?.present(nav, animated: true)
         }
     }
 }

+ 53 - 34
deltachat-ios/Chat/DraftModel.swift

@@ -3,15 +3,29 @@ import UIKit
 import DcCore
 
 public class DraftModel {
-    var quoteMessage: DcMsg?
+    var draftMsg: DcMsg?
     var dcContext: DcContext
-    var quoteText: String?
     var text: String?
-    var attachment: String?
-    var attachmentMimeType: String?
-    var viewType: Int32?
     let chatId: Int
     var isEditing: Bool = false
+    var quoteMessage: DcMsg? {
+        return draftMsg?.quoteMessage
+    }
+    var quoteText: String? {
+        return draftMsg?.quoteText
+    }
+    var attachment: String? {
+        return draftMsg?.fileURL?.relativePath
+    }
+    var attachmentMimeType: String? {
+        return draftMsg?.filemime
+    }
+    var viewType: Int32? {
+        if let viewType = draftMsg?.type {
+            return Int32(viewType)
+        }
+        return nil
+    }
 
     public init(dcContext: DcContext, chatId: Int) {
         self.chatId = chatId
@@ -19,53 +33,58 @@ public class DraftModel {
     }
 
     public func parse(draftMsg: DcMsg?) {
+        self.draftMsg = draftMsg
         text = draftMsg?.text
-        quoteText = draftMsg?.quoteText
-        quoteMessage = draftMsg?.quoteMessage
-        attachment = draftMsg?.fileURL?.relativePath
-        if let viewType = draftMsg?.type {
-            self.viewType = Int32(viewType)
-        }
-        attachmentMimeType = draftMsg?.filemime
     }
 
     public func setQuote(quotedMsg: DcMsg?) {
-        if let quotedMsg = quotedMsg {
-            // create a temporary draft to get the correct quoteText
-            let draftMessage = dcContext.newMessage(viewType: DC_MSG_TEXT)
-            draftMessage.quoteMessage = quotedMsg
-            self.quoteText = draftMessage.quoteText
-            self.quoteMessage = quotedMsg
-        } else {
-            self.quoteText = nil
-            self.quoteMessage = nil
+        if draftMsg == nil {
+            draftMsg = dcContext.newMessage(viewType: DC_MSG_TEXT)
         }
+        draftMsg?.quoteMessage = quotedMsg
     }
 
     public func setAttachment(viewType: Int32?, path: String?, mimetype: String? = nil) {
-        attachment = path
-        self.viewType = viewType
-        attachmentMimeType = mimetype
+        let quoteMsg = draftMsg?.quoteMessage
+        draftMsg = dcContext.newMessage(viewType: viewType ?? DC_MSG_TEXT)
+        draftMsg?.quoteMessage = quoteMsg
+        draftMsg?.setFile(filepath: path, mimeType: mimetype)
+        save(context: dcContext)
+    }
+
+    public func clearAttachment() {
+        let quoteMsg = draftMsg?.quoteMessage
+        if text != nil || quoteMsg != nil {
+            draftMsg = dcContext.newMessage(viewType: DC_MSG_TEXT)
+            draftMsg?.quoteMessage = quoteMsg
+            save(context: dcContext)
+        } else {
+            draftMsg = nil
+            dcContext.setDraft(chatId: chatId, message: nil)
+        }
     }
 
     public func save(context: DcContext) {
-        if (text?.isEmpty ?? true) && quoteMessage == nil {
-            context.setDraft(chatId: chatId, message: nil)
+        if (text?.isEmpty ?? true) &&
+            (draftMsg == nil || quoteMessage == nil && attachment == nil) {
+            self.clear()
             return
         }
 
-        let draftMessage = dcContext.newMessage(viewType: viewType ?? DC_MSG_TEXT)
-        draftMessage.text = text
-        if quoteMessage != nil {
-            draftMessage.quoteMessage = quoteMessage
-        }
-        if attachment != nil {
-            draftMessage.setFile(filepath: attachment, mimeType: attachmentMimeType)
+        if draftMsg == nil {
+            draftMsg = dcContext.newMessage(viewType: DC_MSG_TEXT)
         }
-        context.setDraft(chatId: chatId, message: draftMessage)
+        draftMsg?.text = text
+        context.setDraft(chatId: chatId, message: draftMsg)
     }
 
     public func canSend() -> Bool {
         return !(text?.isEmpty ?? true) || attachment != nil
     }
+
+    public func clear() {
+        text = nil
+        draftMsg = nil
+        dcContext.setDraft(chatId: chatId, message: nil)
+    }
 }

+ 10 - 8
deltachat-ios/Chat/Views/Cells/FileTextCell.swift

@@ -3,11 +3,12 @@ import UIKit
 import DcCore
 import SDWebImage
 
-class FileTextCell: BaseMessageCell {
+public class FileTextCell: BaseMessageCell {
 
-    private var spacer: NSLayoutConstraint?
+    private var spacerHeight: NSLayoutConstraint?
+    var spacerWidth: NSLayoutConstraint?
 
-    private lazy var fileView: FileView = {
+    lazy var fileView: FileView = {
         let view = FileView()
         return view
     }()
@@ -15,8 +16,9 @@ class FileTextCell: BaseMessageCell {
     override func setupSubviews() {
         super.setupSubviews()
         let spacerView = UIView()
-        spacer = spacerView.constraintHeightTo(8, priority: .defaultHigh)
-        spacer?.isActive = true
+        spacerHeight = spacerView.constraintHeightTo(8, priority: .defaultHigh)
+        spacerHeight?.isActive = true
+        spacerWidth = spacerView.constraintWidthTo(280, priority: UILayoutPriority(rawValue: 400))
         mainContentView.addArrangedSubview(fileView)
         mainContentView.addArrangedSubview(spacerView)
         mainContentView.addArrangedSubview(messageLabel)
@@ -24,7 +26,7 @@ class FileTextCell: BaseMessageCell {
         mainContentViewHorizontalPadding = 12
     }
 
-    override func prepareForReuse() {
+    public override func prepareForReuse() {
         super.prepareForReuse()
         fileView.prepareForReuse()
     }
@@ -32,9 +34,9 @@ class FileTextCell: BaseMessageCell {
     override func update(dcContext: DcContext, msg: DcMsg, messageStyle: UIRectCorner, showAvatar: Bool, showName: Bool, searchText: String? = nil, highlight: Bool) {
         if let text = msg.text, !text.isEmpty {
             messageLabel.text = text
-            spacer?.isActive = true
+            spacerHeight?.isActive = true
         } else {
-            spacer?.isActive = false
+            spacerHeight?.isActive = false
         }
         
         fileView.configure(message: msg)

+ 6 - 32
deltachat-ios/Chat/Views/Cells/WebxdcCell.swift

@@ -1,28 +1,15 @@
 import UIKit
 import DcCore
 
-public class WebxdcCell: BaseMessageCell {
-    
-    private var spacer: NSLayoutConstraint?
-    
-    private lazy var webxdcView: WebxdcPreview = {
-        let view = WebxdcPreview()
-        return view
-    }()
-    
+public class WebxdcCell: FileTextCell {
 
     override func setupSubviews() {
         super.setupSubviews()
-        let spacerView = UIView()
-        spacer = spacerView.constraintHeightTo(8, priority: .defaultHigh)
-        spacer?.isActive = true
-        spacerView.constraintWidthTo(300, priority: UILayoutPriority(rawValue: 400)).isActive = true
-        mainContentView.addArrangedSubview(webxdcView)
-        mainContentView.addArrangedSubview(spacerView)
-        mainContentView.addArrangedSubview(messageLabel)
-        mainContentViewHorizontalPadding = 12
+        fileView.fileImageView.isUserInteractionEnabled = true
         let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(onImageTapped))
-        webxdcView.imagePreview.addGestureRecognizer(gestureRecognizer)
+        fileView.fileImageView.addGestureRecognizer(gestureRecognizer)
+        fileView.horizontalLayout = false
+        spacerWidth?.isActive = true
     }
 
     @objc func onImageTapped() {
@@ -31,21 +18,7 @@ public class WebxdcCell: BaseMessageCell {
         }
     }
 
-    public override func prepareForReuse() {
-        super.prepareForReuse()
-        webxdcView.prepareForReuse()
-    }
-
     override func update(dcContext: DcContext, msg: DcMsg, messageStyle: UIRectCorner, showAvatar: Bool, showName: Bool, searchText: String? = nil, highlight: Bool) {
-        if let text = msg.text, !text.isEmpty {
-            messageLabel.text = text
-            spacer?.isActive = true
-        } else {
-            spacer?.isActive = false
-        }
-        
-        webxdcView.configure(message: msg)
-        accessibilityLabel = "\(webxdcView.configureAccessibilityLabel())"
         super.update(dcContext: dcContext,
                      msg: msg,
                      messageStyle: messageStyle,
@@ -53,5 +26,6 @@ public class WebxdcCell: BaseMessageCell {
                      showName: showName,
                      searchText: searchText,
                      highlight: highlight)
+        accessibilityLabel = fileView.configureAccessibilityLabel()
     }
 }

+ 11 - 4
deltachat-ios/Chat/Views/DocumentPreview.swift

@@ -36,12 +36,19 @@ public class DocumentPreview: DraftPreview {
 
     override public func configure(draft: DraftModel) {
         if !draft.isEditing,
-           draft.viewType == DC_MSG_FILE,
+           let viewType = draft.viewType,
+           viewType == DC_MSG_FILE || viewType == DC_MSG_WEBXDC,
            let path = draft.attachment {
-            let tmpMsg = draft.dcContext.newMessage(viewType: DC_MSG_FILE)
-            tmpMsg.setFile(filepath: path)
-            tmpMsg.text = draft.text
+            var tmpMsg: DcMsg
+            if let draftMsg = draft.draftMsg {
+                tmpMsg = draftMsg
+            } else {
+                tmpMsg = draft.dcContext.newMessage(viewType: viewType)
+                tmpMsg.setFile(filepath: path)
+                tmpMsg.text = draft.text
+            }
             fileView.configure(message: tmpMsg)
+            fileView.fileTitle.numberOfLines = 2
             self.delegate?.onAttachmentAdded()
             accessibilityLabel = "\(String.localized("attachment")), \(fileView.configureAccessibilityLabel())"
             isHidden = false

+ 38 - 5
deltachat-ios/Chat/Views/FileView.swift

@@ -41,9 +41,10 @@ public class FileView: UIView {
         return stackView
     }()
 
-    private lazy var fileImageView: UIImageView = {
+    lazy var fileImageView: UIImageView = {
         let imageView = UIImageView()
         imageView.contentMode = .scaleAspectFit
+        imageView.clipsToBounds = true
         isAccessibilityElement = false
         return imageView
     }()
@@ -58,17 +59,13 @@ public class FileView: UIView {
 
     lazy var fileTitle: UILabel = {
         let title = UILabel()
-        title.font = UIFont.preferredItalicFont(for: .body)
         title.translatesAutoresizingMaskIntoConstraints = false
-        title.numberOfLines = 3
-        title.lineBreakMode = .byCharWrapping
         isAccessibilityElement = false
         return title
     }()
 
     private lazy var fileSubtitle: UILabel = {
         let subtitle = UILabel()
-        subtitle.font = UIFont.preferredItalicFont(for: .caption2)
         subtitle.translatesAutoresizingMaskIntoConstraints = false
         subtitle.numberOfLines = 1
         isAccessibilityElement = false
@@ -99,12 +96,48 @@ public class FileView: UIView {
     }
 
     public func configure(message: DcMsg) {
+        if message.type == DC_MSG_WEBXDC {
+           configureWebxdc(message: message)
+        } else if message.type == DC_MSG_FILE {
+            configureFile(message: message)
+        } else {
+            logger.error("Configuring message failed")
+        }
+    }
+
+    private func configureWebxdc(message: DcMsg) {
+        fileImageView.layer.cornerRadius = 8
+        let dict = message.getWebxdcInfoDict()
+        if let iconfilePath = dict["icon"] as? String {
+            let blob = message.getWebxdcBlob(filename: iconfilePath)
+            if !blob.isEmpty {
+                fileImageView.image = UIImage(data: blob)?.sd_resizedImage(with: CGSize(width: 175, height: 175), scaleMode: .aspectFill)
+            }
+        }
+        fileTitle.numberOfLines = 1
+        fileTitle.lineBreakMode = .byTruncatingTail
+        fileTitle.font = UIFont.preferredBoldFont(for: .body)
+        fileSubtitle.font = UIFont.preferredFont(forTextStyle: .body)
+        fileTitle.text = dict["name"] as? String
+        guard let summary = dict["summary"] as? String, !summary.isEmpty else {
+            fileSubtitle.text = "Webxdc"
+            return
+        }
+        fileSubtitle.text = summary
+    }
+
+    private func configureFile(message: DcMsg) {
+        fileImageView.layer.cornerRadius = 0
         if let url = message.fileURL {
             generateThumbnailFor(url: url, placeholder: defaultImage)
         } else {
             fileImageView.image = defaultImage
             horizontalLayout = true
         }
+        fileTitle.numberOfLines = 3
+        fileTitle.lineBreakMode = .byCharWrapping
+        fileTitle.font = UIFont.preferredItalicFont(for: .body)
+        fileSubtitle.font = UIFont.preferredItalicFont(for: .caption2)
         fileTitle.text = message.filename
         fileSubtitle.text = message.getPrettyFileSize()
     }

+ 0 - 97
deltachat-ios/Chat/Views/WebxdcPreview.swift

@@ -1,97 +0,0 @@
-import UIKit
-import DcCore
-
-public class WebxdcPreview: UIView {
-    
-    lazy var imagePreview: UIImageView = {
-        let view = UIImageView()
-        view.contentMode = .left
-        view.translatesAutoresizingMaskIntoConstraints = false
-        view.layer.cornerRadius = 8
-        view.clipsToBounds = true
-        view.isUserInteractionEnabled = true
-        return view
-    }()
-    
-    lazy var titleView: UILabel = {
-        let view = UILabel()
-        view.font = UIFont.preferredBoldFont(for: .body)
-        view.translatesAutoresizingMaskIntoConstraints = false
-        view.numberOfLines = 1
-        view.lineBreakMode = .byTruncatingTail
-        isAccessibilityElement = false
-        return view
-    }()
-    
-    lazy var subtitleView: UILabel = {
-        let view = UILabel()
-        view.font = UIFont.preferredFont(forTextStyle: .body)
-        view.translatesAutoresizingMaskIntoConstraints = false
-        view.numberOfLines = 1
-        view.lineBreakMode = .byTruncatingTail
-        isAccessibilityElement = false
-        return view
-    }()
-    
-    lazy var containerStackView: UIStackView = {
-        let view = UIStackView(arrangedSubviews: [imagePreview, titleView, subtitleView])
-        view.axis = .vertical
-        view.alignment = .leading
-        view.spacing = 6
-        view.translatesAutoresizingMaskIntoConstraints = false
-        return view
-    }()
-    
-    convenience init() {
-        self.init(frame: .zero)
-
-    }
-    
-    required init?(coder: NSCoder) {
-        fatalError("init(coder:) has not been implemented")
-    }
-
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        self.setupSubviews()
-    }
-    
-    private func setupSubviews() {
-        addSubview(containerStackView)
-        containerStackView.fillSuperview()
-    }
-    
-    public func configure(message: DcMsg) {
-        let dict = message.getWebxdcInfoDict()
-        if let iconfilePath = dict["icon"] as? String {
-            let blob = message.getWebxdcBlob(filename: iconfilePath)
-            if !blob.isEmpty {
-                imagePreview.image = UIImage(data: blob)?.sd_resizedImage(with: CGSize(width: 175, height: 175), scaleMode: .aspectFill)
-            }
-        }
-        titleView.text = dict["name"] as? String
-        guard let summary = dict["summary"] as? String, !summary.isEmpty else {
-            subtitleView.text = "Webxdc"
-            return
-        }
-        subtitleView.text = summary
-    }
-
-    public func configureAccessibilityLabel() -> String {
-        var accessibilityTitle = ""
-        var accessiblitySubtitle = ""
-        if let titleText = titleView.text {
-            accessibilityTitle = titleText
-        }
-        if let subtitleText = subtitleView.text {
-            accessiblitySubtitle = subtitleText
-        }
-        
-        return "\(accessibilityTitle), \(accessiblitySubtitle)"
-    }
-
-    public func prepareForReuse() {
-        imagePreview.image = nil
-    }
-    
-}

+ 2 - 1
deltachat-ios/Helper/MediaPicker.swift

@@ -72,7 +72,8 @@ class MediaPicker: NSObject, UINavigationControllerDelegate, AudioRecorderContro
     }
 
     func showDocumentLibrary() {
-        let types = [kUTTypePDF, kUTTypeText, kUTTypeRTF, kUTTypeSpreadsheet, kUTTypeVCard, kUTTypeZipArchive, kUTTypeImage]
+        // TODO: instead of adding kUTTypeData, we probably should implement a Document provider for webxdc's https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/FileProvider.html#//apple_ref/doc/uid/TP40014214-CH18
+        let types = [kUTTypePDF, kUTTypeText, kUTTypeRTF, kUTTypeSpreadsheet, kUTTypeVCard, kUTTypeZipArchive, kUTTypeImage, kUTTypeData]
         let documentPicker = UIDocumentPickerViewController(documentTypes: types as [String], in: .import)
         documentPicker.delegate = self
         documentPicker.allowsMultipleSelection = false