From 52ea54ae6468622b2ade4896388089583fe4e76a Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 3 Apr 2018 23:24:09 -0400 Subject: [PATCH] Add thumbnail when available MVP - [x] populate from menu - [x] send quoted message TODO - [x] thumbnail - [] paperclip icon showing for text message - [] cancel button asset - [] fonts - [] colors - [] adjust content inset/offset when showing quote edit NICE TO HAVE - [] animate presentation - [] animate dismiss - [] non-paperclip icon for generic attachments // FREEBIE --- Signal/src/views/QuotedReplyPreview.swift | 64 +++++++++++-------- .../Messages/Interactions/TSQuotedMessage.h | 2 + .../Messages/Interactions/TSQuotedMessage.m | 11 ++++ 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/Signal/src/views/QuotedReplyPreview.swift b/Signal/src/views/QuotedReplyPreview.swift index 409eec731..453ece642 100644 --- a/Signal/src/views/QuotedReplyPreview.swift +++ b/Signal/src/views/QuotedReplyPreview.swift @@ -43,7 +43,7 @@ class QuotedReplyPreview: UIView { // used for text and cancel let foregroundColor: UIColor = .darkGray - let authorLabel: UILabel = UILabel() + let authorLabel: UILabel = UILabel() authorLabel.textColor = authorColor authorLabel.text = Environment.current().contactsManager.displayName(forPhoneIdentifier: quotedMessage.authorId) authorLabel.font = .ows_dynamicTypeHeadline @@ -54,6 +54,18 @@ class QuotedReplyPreview: UIView { 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 @@ -65,44 +77,40 @@ class QuotedReplyPreview: UIView { let quoteStripe: UIView = UIView() quoteStripe.backgroundColor = authorColor - let contentViews: [UIView] = iconView == nil ? [bodyLabel] : [iconView!, bodyLabel] - let contentContainer: UIStackView = UIStackView(arrangedSubviews: contentViews) - contentContainer.axis = .horizontal - contentContainer.spacing = 4.0 + 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) - self.addSubview(authorLabel) - self.addSubview(contentContainer) - self.addSubview(cancelButton) + 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 kCancelButtonMargin: CGFloat = 4 let kQuoteStripeWidth: CGFloat = 4 - let leadingMargin: CGFloat = kQuoteStripeWidth + 8 - let vMargin: CGFloat = 6 - let trailingMargin: CGFloat = 8 - - self.layoutMargins = UIEdgeInsets(top: vMargin, left: leadingMargin, bottom: vMargin, right: trailingMargin) + self.layoutMargins = UIEdgeInsets(top: 6, + left: kQuoteStripeWidth + 8, + bottom: 2, + right: 4) quoteStripe.autoPinEdge(toSuperviewEdge: .leading) quoteStripe.autoPinHeightToSuperview() quoteStripe.autoSetDimension(.width, toSize: kQuoteStripeWidth) - authorLabel.autoPinTopToSuperviewMargin() - authorLabel.autoPinLeadingToSuperviewMargin() - - authorLabel.autoPinEdge(.trailing, to: .leading, of: cancelButton, withOffset: -kCancelButtonMargin) - authorLabel.setCompressionResistanceHigh() - - contentContainer.autoPinLeadingToSuperviewMargin() - contentContainer.autoPinBottomToSuperviewMargin() - contentContainer.autoPinEdge(.top, to: .bottom, of: authorLabel) - contentContainer.autoPinEdge(.trailing, to: .leading, of: cancelButton, withOffset: -kCancelButtonMargin) - - cancelButton.autoPinTrailingToSuperviewMargin() - cancelButton.autoVCenterInSuperview() - cancelButton.setContentHuggingHigh() + contentRow.autoPinEdgesToSuperviewMargins() cancelButton.autoSetDimensions(to: CGSize(width: 40, height: 40)) } diff --git a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.h b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.h index 51acde44f..a971c81be 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.h @@ -33,6 +33,8 @@ NS_ASSUME_NONNULL_BEGIN thumbnailData:(NSData *_Nullable)thumbnailData contentType:(NSString *_Nullable)contentType; +- (nullable UIImage *)thumbnailImage; + @end #pragma mark - diff --git a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m index d6160b3a0..1d99d58aa 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSQuotedMessage.m @@ -33,6 +33,17 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (nullable UIImage *)thumbnailImage +{ + if (self.thumbnailData.length == 0) { + return nil; + } + + // PERF TODO cache + return [UIImage imageWithData:self.thumbnailData]; +} + + @end NS_ASSUME_NONNULL_END