final class MediaPlaceholderView : UIView { private let viewItem: ConversationViewItem private let textColor: UIColor // MARK: Settings private static let iconSize: CGFloat = 24 private static let iconImageViewSize: CGFloat = 40 // MARK: Lifecycle init(viewItem: ConversationViewItem, textColor: UIColor) { self.viewItem = viewItem self.textColor = textColor super.init(frame: CGRect.zero) setUpViewHierarchy() } override init(frame: CGRect) { preconditionFailure("Use init(viewItem:textColor:) instead.") } required init?(coder: NSCoder) { preconditionFailure("Use init(viewItem:textColor:) instead.") } private func setUpViewHierarchy() { let (iconName, attachmentDescription): (String, String) = { guard let message = viewItem.interaction as? TSIncomingMessage else { return ("actionsheet_document_black", "file") } // Should never occur var attachments: [TSAttachment] = [] Storage.read { transaction in attachments = message.attachments(with: transaction) } guard let contentType = attachments.first?.contentType else { return ("actionsheet_document_black", "file") } // Should never occur if MIMETypeUtil.isAudio(contentType) { return ("attachment_audio", "audio") } if MIMETypeUtil.isImage(contentType) || MIMETypeUtil.isVideo(contentType) { return ("actionsheet_camera_roll_black", "media") } return ("actionsheet_document_black", "file") }() // Image view let iconSize = MediaPlaceholderView.iconSize let icon = UIImage(named: iconName)?.withTint(textColor)?.resizedImage(to: CGSize(width: iconSize, height: iconSize)) let imageView = UIImageView(image: icon) imageView.contentMode = .center let iconImageViewSize = MediaPlaceholderView.iconImageViewSize imageView.set(.width, to: iconImageViewSize) imageView.set(.height, to: iconImageViewSize) // Body label let titleLabel = UILabel() titleLabel.lineBreakMode = .byTruncatingTail titleLabel.text = "Tap to download \(attachmentDescription)" titleLabel.textColor = textColor titleLabel.font = .systemFont(ofSize: Values.mediumFontSize) // Stack view let stackView = UIStackView(arrangedSubviews: [ imageView, titleLabel ]) stackView.axis = .horizontal stackView.alignment = .center stackView.isLayoutMarginsRelativeArrangement = true stackView.layoutMargins = UIEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 12) addSubview(stackView) stackView.pin(to: self, withInset: Values.smallSpacing) } }