Sfoglia il codice sorgente

draft Webxdc message cell

cyberta 3 anni fa
parent
commit
cc2ce2f4fe

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

@@ -40,6 +40,7 @@
 		303492CB257A814200A523D0 /* DraftArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = 303492CA257A814200A523D0 /* DraftArea.swift */; };
 		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, ); }; };
 		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 */; };
 		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 */; };
 		304F5E44244F571C00462538 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A9FB14A1FB061E2001FEA36 /* Assets.xcassets */; };
 		304F769525DD237B0094B5E2 /* WebViewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304F769425DD237B0094B5E2 /* WebViewViewController.swift */; };
 		304F769525DD237B0094B5E2 /* WebViewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304F769425DD237B0094B5E2 /* WebViewViewController.swift */; };
 		304F769925DD23D70094B5E2 /* FullMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304F769825DD23D70094B5E2 /* FullMessageViewController.swift */; };
 		304F769925DD23D70094B5E2 /* FullMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 304F769825DD23D70094B5E2 /* FullMessageViewController.swift */; };
@@ -67,6 +68,7 @@
 		3067AAC62667F3FE00525036 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3067AAC52667F3FE00525036 /* ImageFormat.swift */; };
 		3067AAC62667F3FE00525036 /* ImageFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3067AAC52667F3FE00525036 /* ImageFormat.swift */; };
 		3067AAC72667F3FE00525036 /* 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 */; };
 		306C32322445CDE9001D89F3 /* DcLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306C32312445CDE9001D89F3 /* DcLogger.swift */; };
+		30703B6D27AA80FF00BDADE6 /* WebxdcCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30703B6C27AA80FF00BDADE6 /* WebxdcCell.swift */; };
 		30734326249A280B00BF9AD1 /* MediaQualityController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30734325249A280B00BF9AD1 /* MediaQualityController.swift */; };
 		30734326249A280B00BF9AD1 /* MediaQualityController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30734325249A280B00BF9AD1 /* MediaQualityController.swift */; };
 		307A82CC25B8D26700748B57 /* ChatEditingBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307A82CB25B8D26700748B57 /* ChatEditingBar.swift */; };
 		307A82CC25B8D26700748B57 /* ChatEditingBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307A82CB25B8D26700748B57 /* ChatEditingBar.swift */; };
 		307D822E241669C7006D2490 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307D822D241669C7006D2490 /* LocationManager.swift */; };
 		307D822E241669C7006D2490 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 307D822D241669C7006D2490 /* LocationManager.swift */; };
@@ -281,6 +283,7 @@
 		303492CA257A814200A523D0 /* DraftArea.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftArea.swift; sourceTree = "<group>"; };
 		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; };
 		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>"; };
 		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>"; };
 		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>"; };
 		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>"; };
 		3052C609253F082E007D13EA /* MessageLabelDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageLabelDelegate.swift; sourceTree = "<group>"; };
@@ -341,6 +344,7 @@
 		3067AA4B2666310E00525036 /* ChatInputTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatInputTextView.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>"; };
 		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>"; };
 		306C32312445CDE9001D89F3 /* DcLogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DcLogger.swift; sourceTree = "<group>"; };
+		30703B6C27AA80FF00BDADE6 /* WebxdcCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebxdcCell.swift; sourceTree = "<group>"; };
 		30734325249A280B00BF9AD1 /* MediaQualityController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaQualityController.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>"; };
 		307A82CB25B8D26700748B57 /* ChatEditingBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatEditingBar.swift; sourceTree = "<group>"; };
 		307D822D241669C7006D2490 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; };
 		307D822D241669C7006D2490 /* LocationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = "<group>"; };
@@ -736,6 +740,7 @@
 				303492AC2577CAC300A523D0 /* FileView.swift */,
 				303492AC2577CAC300A523D0 /* FileView.swift */,
 				303492B22577E40700A523D0 /* DocumentPreview.swift */,
 				303492B22577E40700A523D0 /* DocumentPreview.swift */,
 				303492CA257A814200A523D0 /* DraftArea.swift */,
 				303492CA257A814200A523D0 /* DraftArea.swift */,
+				304A92C027AAE10B00588A15 /* WebxdcPreview.swift */,
 			);
 			);
 			path = Views;
 			path = Views;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -751,6 +756,7 @@
 				3008CB7124F93EB900E6A617 /* AudioMessageCell.swift */,
 				3008CB7124F93EB900E6A617 /* AudioMessageCell.swift */,
 				3010968826838A040032CBA0 /* VideoInviteCell.swift */,
 				3010968826838A040032CBA0 /* VideoInviteCell.swift */,
 				30AAD71A2762869600DE3DC1 /* SelectableCell.swift */,
 				30AAD71A2762869600DE3DC1 /* SelectableCell.swift */,
+				30703B6C27AA80FF00BDADE6 /* WebxdcCell.swift */,
 			);
 			);
 			path = Cells;
 			path = Cells;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -1405,6 +1411,7 @@
 				304219D92440734A00516852 /* DcMsg+Extension.swift in Sources */,
 				304219D92440734A00516852 /* DcMsg+Extension.swift in Sources */,
 				AE52EA19229EB53C00C586C9 /* ContactDetailHeader.swift in Sources */,
 				AE52EA19229EB53C00C586C9 /* ContactDetailHeader.swift in Sources */,
 				78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */,
 				78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */,
+				304A92C127AAE10B00588A15 /* WebxdcPreview.swift in Sources */,
 				3080A022277DE09900E74565 /* InputTextView.swift in Sources */,
 				3080A022277DE09900E74565 /* InputTextView.swift in Sources */,
 				30734326249A280B00BF9AD1 /* MediaQualityController.swift in Sources */,
 				30734326249A280B00BF9AD1 /* MediaQualityController.swift in Sources */,
 				3080A01C277DDB8A00E74565 /* InputBarAccessoryViewDelegate.swift in Sources */,
 				3080A01C277DDB8A00E74565 /* InputBarAccessoryViewDelegate.swift in Sources */,
@@ -1442,6 +1449,7 @@
 				306C32322445CDE9001D89F3 /* DcLogger.swift in Sources */,
 				306C32322445CDE9001D89F3 /* DcLogger.swift in Sources */,
 				3080A036277DE30100E74565 /* NSMutableAttributedString+Extensions.swift in Sources */,
 				3080A036277DE30100E74565 /* NSMutableAttributedString+Extensions.swift in Sources */,
 				307A82CC25B8D26700748B57 /* ChatEditingBar.swift in Sources */,
 				307A82CC25B8D26700748B57 /* ChatEditingBar.swift in Sources */,
+				30703B6D27AA80FF00BDADE6 /* WebxdcCell.swift in Sources */,
 				303492952565AABC00A523D0 /* DraftModel.swift in Sources */,
 				303492952565AABC00A523D0 /* DraftModel.swift in Sources */,
 				78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */,
 				78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */,
 				3080A021277DE09900E74565 /* InputStackView.swift in Sources */,
 				3080A021277DE09900E74565 /* InputStackView.swift in Sources */,

+ 4 - 3
deltachat-ios/Chat/ChatViewController.swift

@@ -297,6 +297,7 @@ class ChatViewController: UITableViewController {
         tableView.register(InfoMessageCell.self, forCellReuseIdentifier: "info")
         tableView.register(InfoMessageCell.self, forCellReuseIdentifier: "info")
         tableView.register(AudioMessageCell.self, forCellReuseIdentifier: "audio")
         tableView.register(AudioMessageCell.self, forCellReuseIdentifier: "audio")
         tableView.register(VideoInviteCell.self, forCellReuseIdentifier: "video_invite")
         tableView.register(VideoInviteCell.self, forCellReuseIdentifier: "video_invite")
+        tableView.register(WebxdcCell.self, forCellReuseIdentifier: "webxdc")
         tableView.rowHeight = UITableView.automaticDimension
         tableView.rowHeight = UITableView.automaticDimension
         tableView.separatorStyle = .none
         tableView.separatorStyle = .none
         tableView.keyboardDismissMode = .interactive
         tableView.keyboardDismissMode = .interactive
@@ -710,7 +711,7 @@ class ChatViewController: UITableViewController {
                 cell = tableView.dequeueReusableCell(withIdentifier: "file", for: indexPath) as? FileTextCell ?? FileTextCell()
                 cell = tableView.dequeueReusableCell(withIdentifier: "file", for: indexPath) as? FileTextCell ?? FileTextCell()
             }
             }
         case DC_MSG_WEBXDC:
         case DC_MSG_WEBXDC:
-                cell = tableView.dequeueReusableCell(withIdentifier: "file", for: indexPath) as? FileTextCell ?? FileTextCell()
+                cell = tableView.dequeueReusableCell(withIdentifier: "webxdc", for: indexPath) as? WebxdcCell ?? WebxdcCell()
         case DC_MSG_AUDIO, DC_MSG_VOICE:
         case DC_MSG_AUDIO, DC_MSG_VOICE:
             let audioMessageCell: AudioMessageCell = tableView.dequeueReusableCell(withIdentifier: "audio",
             let audioMessageCell: AudioMessageCell = tableView.dequeueReusableCell(withIdentifier: "audio",
                                                                                       for: indexPath) as? AudioMessageCell ?? AudioMessageCell()
                                                                                       for: indexPath) as? AudioMessageCell ?? AudioMessageCell()
@@ -880,8 +881,6 @@ class ChatViewController: UITableViewController {
             if let url = NSURL(string: message.getVideoChatUrl()) {
             if let url = NSURL(string: message.getVideoChatUrl()) {
                 UIApplication.shared.open(url as URL)
                 UIApplication.shared.open(url as URL)
             }
             }
-        } else if message.type == DC_MSG_WEBXDC {
-            showWebxdcViewFor(message: message)
         }
         }
         _ = handleUIMenu()
         _ = handleUIMenu()
     }
     }
@@ -1716,6 +1715,8 @@ extension ChatViewController: BaseMessageCellDelegate {
         let msg = dcContext.getMessage(id: messageIds[indexPath.row])
         let msg = dcContext.getMessage(id: messageIds[indexPath.row])
         if msg.downloadState != DC_DOWNLOAD_DONE {
         if msg.downloadState != DC_DOWNLOAD_DONE {
             dcContext.downloadFullMessage(id: msg.id)
             dcContext.downloadFullMessage(id: msg.id)
+        } else if msg.type == DC_MSG_WEBXDC {
+            showWebxdcViewFor(message: msg)
         } else {
         } else {
             let fullMessageViewController = FullMessageViewController(dcContext: dcContext, messageId: msg.id)
             let fullMessageViewController = FullMessageViewController(dcContext: dcContext, messageId: msg.id)
             navigationController?.pushViewController(fullMessageViewController, animated: true)
             navigationController?.pushViewController(fullMessageViewController, animated: true)

+ 7 - 6
deltachat-ios/Chat/Views/Cells/BaseMessageCell.swift

@@ -354,7 +354,8 @@ public class BaseMessageCell: UITableViewCell {
 
 
         let downloadState = msg.downloadState
         let downloadState = msg.downloadState
         let hasHtml = msg.hasHtml
         let hasHtml = msg.hasHtml
-        isActionButtonHidden = !hasHtml && downloadState == DC_DOWNLOAD_DONE
+        let hasWebxdc =  msg.type == DC_MSG_WEBXDC
+        isActionButtonHidden = !hasWebxdc && !hasHtml && downloadState == DC_DOWNLOAD_DONE
         
         
         switch downloadState {
         switch downloadState {
         case DC_DOWNLOAD_FAILURE, DC_DOWNLOAD_AVAILABLE:
         case DC_DOWNLOAD_FAILURE, DC_DOWNLOAD_AVAILABLE:
@@ -363,11 +364,11 @@ public class BaseMessageCell: UITableViewCell {
             actionButton.isEnabled = false
             actionButton.isEnabled = false
             actionButton.setTitle(String.localized("downloading"), for: .normal)
             actionButton.setTitle(String.localized("downloading"), for: .normal)
         default:
         default:
-            break
-        }
-        
-        if hasHtml {
-            actionButton.setTitle(String.localized("show_full_message"), for: .normal)
+            if hasHtml {
+                actionButton.setTitle(String.localized("show_full_message"), for: .normal)
+            } else if hasWebxdc {
+                actionButton.setTitle(String.localized("start_app"), for: .normal)
+            }
         }
         }
 
 
         messageBackgroundContainer.update(rectCorners: messageStyle,
         messageBackgroundContainer.update(rectCorners: messageStyle,

+ 48 - 0
deltachat-ios/Chat/Views/Cells/WebxdcCell.swift

@@ -0,0 +1,48 @@
+import UIKit
+import DcCore
+
+public class WebxdcCell: BaseMessageCell {
+    
+    private var spacer: NSLayoutConstraint?
+    
+    private lazy var webxdcView: WebxdcPreview = {
+        let view = WebxdcPreview()
+        return view
+    }()
+    
+
+    override func setupSubviews() {
+        super.setupSubviews()
+        let spacerView = UIView()
+        spacer = spacerView.constraintHeightTo(8, priority: .defaultHigh)
+        spacer?.isActive = true
+        mainContentView.addArrangedSubview(webxdcView)
+        mainContentView.addArrangedSubview(spacerView)
+        mainContentView.addArrangedSubview(messageLabel)
+        mainContentViewHorizontalPadding = 12
+    }
+
+    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,
+                     showAvatar: showAvatar,
+                     showName: showName,
+                     searchText: searchText,
+                     highlight: highlight)
+    }
+}

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

@@ -0,0 +1,86 @@
+import UIKit
+import DcCore
+
+public class WebxdcPreview: UIView {
+    
+    private var imageWidthConstraint: NSLayoutConstraint?
+    private var imageHeightConstraint: NSLayoutConstraint?
+    
+    lazy var imagePreview: UIImageView = {
+        let view = UIImageView()
+        view.translatesAutoresizingMaskIntoConstraints = false
+        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.preferredItalicFont(for: .caption2)
+        view.translatesAutoresizingMaskIntoConstraints = false
+        view.numberOfLines = 3
+        isAccessibilityElement = false
+        return view
+    }()
+    
+    lazy var containerStackView: UIStackView = {
+        let view = UIStackView(arrangedSubviews: [imagePreview, titleView, subtitleView])
+        view.axis = .vertical
+        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()
+        imageWidthConstraint = imagePreview.constraintWidthTo(80)
+        imageHeightConstraint = imagePreview.constraintHeightTo(80, priority: .defaultLow)
+    }
+    
+    public func configure(message: DcMsg) {
+        imagePreview.image = message.getWebxdcIcon()
+        titleView.text = message.getWebxdcName()
+        subtitleView.text = message.getWebxdcSummary()
+    }
+
+    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
+    }
+    
+}