فهرست منبع

reintroduce file view

cyberta 4 سال پیش
والد
کامیت
d99e8cdbd8

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

@@ -110,6 +110,7 @@
 		30C0D49D237C4908008E2A0E /* CertificateCheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30C0D49C237C4908008E2A0E /* CertificateCheckController.swift */; };
 		30E348DF24F3F819005C93D1 /* ChatTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E348DE24F3F819005C93D1 /* ChatTableView.swift */; };
 		30E348E124F53772005C93D1 /* NewImageTextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E348E024F53772005C93D1 /* NewImageTextCell.swift */; };
+		30E348E524F6647D005C93D1 /* NewFileTextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E348E424F6647D005C93D1 /* NewFileTextCell.swift */; };
 		30E8F2132447285600CE2C90 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30E8F2122447285600CE2C90 /* ShareViewController.swift */; };
 		30E8F2162447285600CE2C90 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 30E8F2142447285600CE2C90 /* MainInterface.storyboard */; };
 		30E8F21A2447285600CE2C90 /* Delta Chat.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 30E8F2102447285600CE2C90 /* Delta Chat.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -400,6 +401,7 @@
 		30C0D49C237C4908008E2A0E /* CertificateCheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CertificateCheckController.swift; sourceTree = "<group>"; };
 		30E348DE24F3F819005C93D1 /* ChatTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatTableView.swift; sourceTree = "<group>"; };
 		30E348E024F53772005C93D1 /* NewImageTextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewImageTextCell.swift; sourceTree = "<group>"; };
+		30E348E424F6647D005C93D1 /* NewFileTextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewFileTextCell.swift; sourceTree = "<group>"; };
 		30E8F2102447285600CE2C90 /* Delta Chat.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Delta Chat.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
 		30E8F2122447285600CE2C90 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
 		30E8F2152447285600CE2C90 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
@@ -804,6 +806,7 @@
 				30FDB71E24D8170E0066C48D /* NewTextMessageCell.swift */,
 				30FDB72024D838240066C48D /* BaseMessageCell.swift */,
 				30E348E024F53772005C93D1 /* NewImageTextCell.swift */,
+				30E348E424F6647D005C93D1 /* NewFileTextCell.swift */,
 			);
 			path = Cells;
 			sourceTree = "<group>";
@@ -1474,6 +1477,7 @@
 				AEE6EC3F2282C59C00EDC689 /* GroupMembersViewController.swift in Sources */,
 				B26B3BC7236DC3DC008ED35A /* SwitchCell.swift in Sources */,
 				AEE700252438E0E500D6992E /* ProgressAlertHandler.swift in Sources */,
+				30E348E524F6647D005C93D1 /* NewFileTextCell.swift in Sources */,
 				306C32322445CDE9001D89F3 /* DcLogger.swift in Sources */,
 				78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */,
 				AE8519EA2272FDCA00ED86F0 /* DeviceContactsHandler.swift in Sources */,

+ 3 - 0
deltachat-ios/Chat/ChatViewControllerNew.swift

@@ -116,6 +116,7 @@ class ChatViewControllerNew: UITableViewController {
     override func viewDidLoad() {
         tableView.register(NewTextMessageCell.self, forCellReuseIdentifier: "text")
         tableView.register(NewImageTextCell.self, forCellReuseIdentifier: "image")
+        tableView.register(NewFileTextCell.self, forCellReuseIdentifier: "file")
         tableView.rowHeight = UITableView.automaticDimension
         tableView.separatorStyle = .none
         tableView.allowsSelection = false
@@ -309,6 +310,8 @@ class ChatViewControllerNew: UITableViewController {
         let cell: BaseMessageCell
         if message.type == DC_MSG_IMAGE || message.type == DC_MSG_GIF {
             cell = tableView.dequeueReusableCell(withIdentifier: "image", for: indexPath) as? NewImageTextCell ?? NewImageTextCell()
+        } else if message.type == DC_MSG_FILE {
+            cell = tableView.dequeueReusableCell(withIdentifier: "file", for: indexPath) as? NewFileTextCell ?? NewFileTextCell()
         } else {
             cell = tableView.dequeueReusableCell(withIdentifier: "text", for: indexPath) as? NewTextMessageCell ?? NewTextMessageCell()
         }

+ 1 - 0
deltachat-ios/Chat/Views/Cells/BaseMessageCell.swift

@@ -17,6 +17,7 @@ public class BaseMessageCell: UITableViewCell {
         view.setContentHuggingPriority(.defaultLow, for: .horizontal)
         view.alignment = .leading
         view.axis = .vertical
+        view.spacing = 6
         return view
     }()
 

+ 125 - 0
deltachat-ios/Chat/Views/Cells/NewFileTextCell.swift

@@ -0,0 +1,125 @@
+import Foundation
+import UIKit
+import DcCore
+import SDWebImage
+
+class NewFileTextCell: BaseMessageCell {
+
+    private lazy var defaultImage: UIImage = {
+        let image = UIImage(named: "ic_attach_file_36pt")
+        return image!
+    }()
+
+    private var imageWidthConstraint: NSLayoutConstraint?
+    private var imageHeightConstraint: NSLayoutConstraint?
+
+    private var horizontalLayout: Bool {
+        set {
+            if newValue {
+                fileStackView.axis = .horizontal
+                imageWidthConstraint?.isActive = true
+                imageHeightConstraint?.isActive = true
+            } else {
+                fileStackView.axis = .vertical
+                imageWidthConstraint?.isActive = false
+                imageHeightConstraint?.isActive = false
+            }
+        }
+        get {
+            return fileStackView.axis == .horizontal
+        }
+    }
+
+    private lazy var fileStackView: UIStackView = {
+        let stackView = UIStackView(arrangedSubviews: [fileImageView, fileMetadataStackView])
+        stackView.axis = .horizontal
+        stackView.spacing = 6
+        stackView.alignment = .center
+        return stackView
+    }()
+
+    private lazy var fileImageView: UIImageView = {
+        let imageView = UIImageView()
+        imageView.contentMode = .scaleAspectFit
+        return imageView
+    }()
+
+    private lazy var fileMetadataStackView: UIStackView = {
+        let stackView = UIStackView(arrangedSubviews: [fileTitle, fileSubtitle])
+        stackView.axis = .vertical
+        stackView.translatesAutoresizingMaskIntoConstraints = false
+        stackView.clipsToBounds = true
+        return stackView
+    }()
+
+    private lazy var fileTitle: UILabel = {
+        let title = UILabel()
+        title.font = UIFont.preferredItalicFont(for: .body)
+        title.translatesAutoresizingMaskIntoConstraints = false
+        title.numberOfLines = 3
+        title.lineBreakMode = .byCharWrapping
+        return title
+    }()
+
+    private lazy var fileSubtitle: UILabel = {
+        let subtitle = UILabel()
+        subtitle.font = UIFont.preferredItalicFont(for: .caption2)
+        subtitle.translatesAutoresizingMaskIntoConstraints = false
+        subtitle.numberOfLines = 1
+        return subtitle
+    }()
+
+
+    lazy var messageLabel: UILabel = {
+        let label = UILabel()
+        label.translatesAutoresizingMaskIntoConstraints = false
+        label.numberOfLines = 0
+        label.lineBreakMode = .byWordWrapping
+        label.setContentHuggingPriority(.defaultLow, for: .vertical)
+        return label
+    }()
+
+    override func setupSubviews() {
+        super.setupSubviews()
+        mainContentView.addArrangedSubview(fileStackView)
+        mainContentView.addArrangedSubview(messageLabel)
+        imageWidthConstraint = fileImageView.constraintWidthTo(50)
+        imageHeightConstraint = fileImageView.constraintHeightTo(50 * 1.3)
+        horizontalLayout = true
+    }
+
+    override func prepareForReuse() {
+        messageLabel.text = nil
+        messageLabel.attributedText = nil
+        fileImageView.image = nil
+    }
+
+    override func update(msg: DcMsg, messageStyle: UIRectCorner, isAvatarVisible: Bool) {
+        messageLabel.text = msg.text
+        if let url = msg.fileURL {
+            generateThumbnailFor(url: url, placeholder: defaultImage)
+        } else {
+            fileImageView.image = defaultImage
+            horizontalLayout = true
+        }
+        fileTitle.text = msg.filename
+        fileSubtitle.text = msg.getPrettyFileSize()
+        super.update(msg: msg, messageStyle: messageStyle, isAvatarVisible: isAvatarVisible)
+    }
+
+    private func generateThumbnailFor(url: URL, placeholder: UIImage?) {
+        if let thumbnail = ThumbnailCache.shared.restoreImage(key: url.absoluteString) {
+            fileImageView.image = thumbnail
+            horizontalLayout = false
+        } else if let pdfThumbnail = DcUtils.thumbnailFromPdf(withUrl: url) {
+            fileImageView.image = pdfThumbnail
+            horizontalLayout = false
+            ThumbnailCache.shared.storeImage(image: pdfThumbnail, key: url.absoluteString)
+        } else {
+            let controller = UIDocumentInteractionController(url: url)
+            fileImageView.image = controller.icons.first ?? placeholder
+            horizontalLayout = true
+        }
+    }
+    
+}

+ 8 - 0
deltachat-ios/Extensions/Extensions.swift

@@ -80,6 +80,14 @@ extension UIFont {
         let metrics = UIFontMetrics(forTextStyle: style)
         return metrics.scaledFont(for: font)
     }
+
+    static func preferredItalicFont(for style: TextStyle) -> UIFont {
+        let traits = UITraitCollection(preferredContentSizeCategory: .large)
+        let desc = UIFontDescriptor.preferredFontDescriptor(withTextStyle: style, compatibleWith: traits)
+        let font = UIFont.italicSystemFont(ofSize: desc.pointSize)
+        let metrics = UIFontMetrics(forTextStyle: style)
+        return metrics.scaledFont(for: font)
+    }
 }
 
 extension UINavigationController {