|  |  |  | // | 
					
						
							|  |  |  | //  Copyright (c) 2018 Open Whisper Systems. All rights reserved. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import Foundation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @objc | 
					
						
							|  |  |  | protocol QuotedReplyPreviewDelegate: class { | 
					
						
							|  |  |  |     func quotedReplyPreviewDidPressCancel(_ preview: QuotedReplyPreview) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @objc | 
					
						
							|  |  |  | class QuotedReplyPreview: UIView { | 
					
						
							|  |  |  |     public weak var delegate: QuotedReplyPreviewDelegate? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private class func iconView(message: TSQuotedMessage) -> UIView? { | 
					
						
							|  |  |  |         guard let contentType = message.contentType else { | 
					
						
							|  |  |  |             return nil | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let iconText = TSAttachmentStream.emoji(forMimeType: contentType) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let label = UILabel() | 
					
						
							|  |  |  |         label.setContentHuggingHigh() | 
					
						
							|  |  |  |         label.text = iconText | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return label | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     required init?(coder aDecoder: NSCoder) { | 
					
						
							|  |  |  |         fatalError("init(coder:) has not been implemented") | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     init(quotedMessage: TSQuotedMessage) { | 
					
						
							|  |  |  |         super.init(frame: .zero) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let isQuotingSelf = quotedMessage.authorId == TSAccountManager.localNumber() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // used for stripe and author | 
					
						
							|  |  |  |         // FIXME actual colors TBD | 
					
						
							|  |  |  |         let authorColor: UIColor = isQuotingSelf ? .ows_materialBlue : .black | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // used for text and cancel | 
					
						
							|  |  |  |         let foregroundColor: UIColor = .darkGray | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let authorLabel: UILabel = UILabel() | 
					
						
							|  |  |  |         authorLabel.textColor = authorColor | 
					
						
							|  |  |  |         if isQuotingSelf { | 
					
						
							|  |  |  |             authorLabel.text = NSLocalizedString("MEDIA_GALLERY_SENDER_NAME_YOU", comment: "") | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             authorLabel.text = Environment.current().contactsManager.displayName(forPhoneIdentifier: quotedMessage.authorId) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         authorLabel.font = .ows_dynamicTypeHeadline | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let bodyLabel: UILabel = UILabel() | 
					
						
							|  |  |  |         bodyLabel.textColor = foregroundColor | 
					
						
							|  |  |  |         bodyLabel.font = .ows_footnote | 
					
						
							|  |  |  |         bodyLabel.text = quotedMessage.body | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let iconView: UIView? = QuotedReplyPreview.iconView(message: quotedMessage) | 
					
						
							|  |  |  |         let thumbnailView: UIView? = { | 
					
						
							|  |  |  |             if let image = quotedMessage.thumbnailImage() { | 
					
						
							|  |  |  |                 let imageView = UIImageView(image: image) | 
					
						
							|  |  |  |                 imageView.contentMode = .scaleAspectFill | 
					
						
							|  |  |  |                 imageView.autoPinToSquareAspectRatio() | 
					
						
							|  |  |  |                 imageView.layer.cornerRadius = 3.0 | 
					
						
							|  |  |  |                 imageView.clipsToBounds = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 return imageView | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return nil | 
					
						
							|  |  |  |         }() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let cancelButton: UIButton = UIButton(type: .custom) | 
					
						
							|  |  |  |         // FIXME proper image asset/size | 
					
						
							|  |  |  |         let buttonImage: UIImage = #imageLiteral(resourceName: "quoted-message-cancel").withRenderingMode(.alwaysTemplate) | 
					
						
							|  |  |  |         cancelButton.setImage(buttonImage, for: .normal) | 
					
						
							|  |  |  |         cancelButton.imageView?.tintColor = foregroundColor | 
					
						
							|  |  |  |         cancelButton.addTarget(self, action: #selector(didTapCancel), for: .touchUpInside) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let quoteStripe: UIView = UIView() | 
					
						
							|  |  |  |         quoteStripe.backgroundColor = authorColor | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let bodyContentViews: [UIView] = iconView == nil ? [bodyLabel] : [iconView!, bodyLabel] | 
					
						
							|  |  |  |         let bodyContentView: UIStackView = UIStackView(arrangedSubviews: bodyContentViews) | 
					
						
							|  |  |  |         bodyContentView.axis = .horizontal | 
					
						
							|  |  |  |         bodyContentView.spacing = 4.0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let textColumn = UIView.container() | 
					
						
							|  |  |  |         textColumn.addSubview(authorLabel) | 
					
						
							|  |  |  |         textColumn.addSubview(bodyContentView) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         authorLabel.setCompressionResistanceHigh() | 
					
						
							|  |  |  |         authorLabel.autoPinEdges(toSuperviewMarginsExcludingEdge: .bottom) | 
					
						
							|  |  |  |         authorLabel.autoPinEdge(.bottom, to: .top, of: bodyContentView) | 
					
						
							|  |  |  |         bodyContentView.setCompressionResistanceHigh() | 
					
						
							|  |  |  |         bodyContentView.autoPinEdges(toSuperviewMarginsExcludingEdge: .top) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let contentViews: [UIView] = [textColumn, thumbnailView, cancelButton].flatMap { return $0 } | 
					
						
							|  |  |  |         let contentRow = UIStackView(arrangedSubviews: contentViews) | 
					
						
							|  |  |  |         contentRow.axis = .horizontal | 
					
						
							|  |  |  |         self.addSubview(contentRow) | 
					
						
							|  |  |  |         self.addSubview(quoteStripe) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Layout | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let kQuoteStripeWidth: CGFloat = 4 | 
					
						
							|  |  |  |         self.layoutMargins = UIEdgeInsets(top: 6, | 
					
						
							|  |  |  |                                           left: kQuoteStripeWidth + 8, | 
					
						
							|  |  |  |                                           bottom: 2, | 
					
						
							|  |  |  |                                           right: 4) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         quoteStripe.autoPinEdge(toSuperviewEdge: .leading) | 
					
						
							|  |  |  |         quoteStripe.autoPinHeightToSuperview() | 
					
						
							|  |  |  |         quoteStripe.autoSetDimension(.width, toSize: kQuoteStripeWidth) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         contentRow.autoPinEdgesToSuperviewMargins() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cancelButton.autoSetDimensions(to: CGSize(width: 40, height: 40)) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // MARK: UIViewOverrides | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Used by stack view to determin size. | 
					
						
							|  |  |  |     override var intrinsicContentSize: CGSize { | 
					
						
							|  |  |  |         return CGSize(width: 0, height: 30) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // MARK: Actions | 
					
						
							|  |  |  |     @objc | 
					
						
							|  |  |  |     func didTapCancel(_ sender: Any) { | 
					
						
							|  |  |  |         self.delegate?.quotedReplyPreviewDidPressCancel(self) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |