Refine appearance of quoted reply message cells.

pull/1/head
Matthew Chen 8 years ago
parent 8a843f70e3
commit 71c5c3a4b7

@ -1144,13 +1144,24 @@ NS_ASSUME_NONNULL_BEGIN
const CGFloat maxMediaWidth = maxMessageWidth; const CGFloat maxMediaWidth = maxMessageWidth;
const CGFloat maxMediaHeight = maxMessageWidth; const CGFloat maxMediaHeight = maxMessageWidth;
CGFloat mediaWidth = (CGFloat)round(maxMediaHeight * contentAspectRatio); CGFloat mediaWidth = maxMediaHeight * contentAspectRatio;
CGFloat mediaHeight = (CGFloat)round(maxMediaHeight); CGFloat mediaHeight = maxMediaHeight;
if (mediaWidth > maxMediaWidth) { if (mediaWidth > maxMediaWidth) {
mediaWidth = (CGFloat)round(maxMediaWidth); mediaWidth = maxMediaWidth;
mediaHeight = (CGFloat)round(maxMediaWidth / contentAspectRatio); mediaHeight = maxMediaWidth / contentAspectRatio;
} }
return CGSizeMake(mediaWidth, mediaHeight);
// We don't want to blow up small images unnecessarily.
const CGFloat kMinimumSize = 150.f;
CGFloat shortSrcDimension = MIN(self.mediaSize.width, self.mediaSize.height);
CGFloat shortDstDimension = MIN(mediaWidth, mediaHeight);
if (shortDstDimension > kMinimumSize && shortDstDimension > shortSrcDimension) {
CGFloat factor = kMinimumSize / shortDstDimension;
mediaWidth *= factor;
mediaHeight *= factor;
}
return CGSizeRound(CGSizeMake(mediaWidth, mediaHeight));
} }
case OWSMessageCellType_Audio: case OWSMessageCellType_Audio:
return CGSizeMake(maxMessageWidth, OWSAudioMessageView.bubbleHeight); return CGSizeMake(maxMessageWidth, OWSAudioMessageView.bubbleHeight);

@ -22,8 +22,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) TSQuotedMessage *quotedMessage; @property (nonatomic, readonly) TSQuotedMessage *quotedMessage;
@property (nonatomic, nullable, readonly) DisplayableText *displayableQuotedText; @property (nonatomic, nullable, readonly) DisplayableText *displayableQuotedText;
@property (nonatomic, readonly) UIFont *textMessageFont;
@property (nonatomic, nullable) OWSBubbleStrokeView *boundsStrokeView; @property (nonatomic, nullable) OWSBubbleStrokeView *boundsStrokeView;
@end @end
@ -67,7 +65,6 @@ NS_ASSUME_NONNULL_BEGIN
_quotedMessage = quotedMessage; _quotedMessage = quotedMessage;
_displayableQuotedText = displayableQuotedText; _displayableQuotedText = displayableQuotedText;
_textMessageFont = [UIFont ows_dynamicTypeBodyFont];
return self; return self;
} }
@ -85,22 +82,6 @@ NS_ASSUME_NONNULL_BEGIN
[TSAttachmentStream hasThumbnailForMimeType:self.quotedMessage.contentType]); [TSAttachmentStream hasThumbnailForMimeType:self.quotedMessage.contentType]);
} }
- (NSString *)quotedSnippet
{
if (self.displayableQuotedText.displayText.length > 0) {
return self.displayableQuotedText.displayText;
} else {
// TODO: Are we going to use the filename? For all mimetypes?
NSString *mimeType = self.quotedMessage.contentType;
if (mimeType.length > 0) {
return [TSAttachment emojiForMimeType:mimeType];
}
}
return @"";
}
- (UIColor *)highlightColor - (UIColor *)highlightColor
{ {
BOOL isIncomingQuote BOOL isIncomingQuote
@ -136,6 +117,7 @@ NS_ASSUME_NONNULL_BEGIN
quotedAttachmentView.layer.borderColor = [UIColor colorWithWhite:0.f alpha:0.1f].CGColor; quotedAttachmentView.layer.borderColor = [UIColor colorWithWhite:0.f alpha:0.1f].CGColor;
quotedAttachmentView.layer.borderWidth = 1.f; quotedAttachmentView.layer.borderWidth = 1.f;
quotedAttachmentView.layer.cornerRadius = 2.f; quotedAttachmentView.layer.cornerRadius = 2.f;
quotedAttachmentView.clipsToBounds = YES;
} else { } else {
// TODO: This asset is wrong. // TODO: This asset is wrong.
// TODO: There's a special asset for audio files. // TODO: There's a special asset for audio files.
@ -163,17 +145,8 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
OWSContactsManager *contactsManager = Environment.current.contactsManager; UILabel *quotedAuthorLabel = [self createQuotedAuthorLabel];
NSString *quotedAuthor = [contactsManager displayNameForPhoneIdentifier:self.quotedMessage.authorId];
UILabel *quotedAuthorLabel = [UILabel new];
{ {
quotedAuthorLabel.text = quotedAuthor;
quotedAuthorLabel.font = self.quotedAuthorFont;
// TODO:
quotedAuthorLabel.textColor = [UIColor ows_darkGrayColor];
quotedAuthorLabel.numberOfLines = 1;
quotedAuthorLabel.lineBreakMode = NSLineBreakByTruncatingTail;
[self addSubview:quotedAuthorLabel]; [self addSubview:quotedAuthorLabel];
[quotedAuthorLabel autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:self.quotedAuthorTopInset]; [quotedAuthorLabel autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:self.quotedAuthorTopInset];
[quotedAuthorLabel autoPinLeadingToSuperviewMarginWithInset:self.quotedContentHInset]; [quotedAuthorLabel autoPinLeadingToSuperviewMarginWithInset:self.quotedContentHInset];
@ -261,6 +234,77 @@ NS_ASSUME_NONNULL_BEGIN
return imageView; return imageView;
} }
- (UILabel *)createQuotedTextLabel
{
UIColor *textColor = self.quotedTextColor;
UIFont *font = self.quotedTextFont;
NSString *text = @"";
NSString *_Nullable fileTypeForSnippet = [self fileTypeForSnippet];
NSString *_Nullable sourceFilename = [self.quotedMessage.sourceFilename filterStringForDisplay];
if (self.displayableQuotedText.displayText.length > 0) {
text = self.displayableQuotedText.displayText;
textColor = self.quotedTextColor;
font = self.quotedTextFont;
} else if (fileTypeForSnippet) {
text = fileTypeForSnippet;
textColor = self.fileTypeTextColor;
font = self.fileTypeFont;
} else if (sourceFilename) {
text = sourceFilename;
textColor = self.filenameTextColor;
font = self.filenameFont;
}
UILabel *quotedTextLabel = [UILabel new];
quotedTextLabel.numberOfLines = 3;
quotedTextLabel.lineBreakMode = NSLineBreakByWordWrapping;
quotedTextLabel.text = text;
quotedTextLabel.textColor = textColor;
quotedTextLabel.font = font;
return quotedTextLabel;
}
- (nullable NSString *)fileTypeForSnippet
{
// TODO: Are we going to use the filename? For all mimetypes?
NSString *_Nullable contentType = self.quotedMessage.contentType;
if (contentType.length > 0) {
if ([MIMETypeUtil isAudio:contentType]) {
return NSLocalizedString(
@"QUOTED_REPLY_TYPE_AUDIO", @"Indicates this message is a quoted reply to an audio file.");
} else if ([MIMETypeUtil isVideo:contentType]) {
return NSLocalizedString(
@"QUOTED_REPLY_TYPE_VIDEO", @"Indicates this message is a quoted reply to a video file.");
}
} else if ([MIMETypeUtil isImage:contentType] || [MIMETypeUtil isAnimated:contentType]) {
return NSLocalizedString(
@"QUOTED_REPLY_TYPE_IMAGE", @"Indicates this message is a quoted reply to an image file.");
}
return nil;
}
- (UILabel *)createQuotedAuthorLabel
{
OWSContactsManager *contactsManager = Environment.current.contactsManager;
NSString *quotedAuthor = [contactsManager displayNameForPhoneIdentifier:self.quotedMessage.authorId];
NSString *quotedAuthorText =
[NSString stringWithFormat:
NSLocalizedString(@"QUOTED_REPLY_AUTHOR_INDICATOR_FORMAT",
@"Indicates the author of a quoted message. Embeds {{the author's name or phone number}}."),
quotedAuthor];
UILabel *quotedAuthorLabel = [UILabel new];
quotedAuthorLabel.text = quotedAuthorText;
quotedAuthorLabel.font = self.quotedAuthorFont;
quotedAuthorLabel.textColor = [self quotedAuthorColor];
quotedAuthorLabel.lineBreakMode = NSLineBreakByTruncatingTail;
quotedAuthorLabel.numberOfLines = 1;
return quotedAuthorLabel;
}
#pragma mark - Measurement #pragma mark - Measurement
- (CGSize)sizeForMaxWidth:(CGFloat)maxWidth - (CGSize)sizeForMaxWidth:(CGFloat)maxWidth
@ -286,14 +330,7 @@ NS_ASSUME_NONNULL_BEGIN
{ {
CGFloat maxQuotedAuthorWidth = maxWidth - result.width; CGFloat maxQuotedAuthorWidth = maxWidth - result.width;
OWSContactsManager *contactsManager = Environment.current.contactsManager; UILabel *quotedAuthorLabel = [self createQuotedAuthorLabel];
NSString *quotedAuthor = [contactsManager displayNameForPhoneIdentifier:self.quotedMessage.authorId];
UILabel *quotedAuthorLabel = [UILabel new];
quotedAuthorLabel.text = quotedAuthor;
quotedAuthorLabel.font = self.quotedAuthorFont;
quotedAuthorLabel.lineBreakMode = NSLineBreakByTruncatingTail;
quotedAuthorLabel.numberOfLines = 1;
CGSize quotedAuthorSize CGSize quotedAuthorSize
= CGSizeCeil([quotedAuthorLabel sizeThatFits:CGSizeMake(maxQuotedAuthorWidth, CGFLOAT_MAX)]); = CGSizeCeil([quotedAuthorLabel sizeThatFits:CGSizeMake(maxQuotedAuthorWidth, CGFLOAT_MAX)]);
@ -327,17 +364,14 @@ NS_ASSUME_NONNULL_BEGIN
return result; return result;
} }
- (UILabel *)createQuotedTextLabel - (UIFont *)quotedAuthorFont
{ {
UILabel *quotedTextLabel = [UILabel new]; return [UIFont ows_mediumFontWithSize:11.f];
quotedTextLabel.numberOfLines = 3; }
quotedTextLabel.lineBreakMode = NSLineBreakByWordWrapping;
quotedTextLabel.text = self.quotedSnippet;
quotedTextLabel.textColor = self.quotedTextColor;
// Honor dynamic type in the message bodies. - (UIColor *)quotedAuthorColor
quotedTextLabel.font = self.textMessageFont; {
return quotedTextLabel; return [UIColor colorWithRGBHex:0x8E8E93];
} }
- (UIColor *)quotedTextColor - (UIColor *)quotedTextColor
@ -345,77 +379,92 @@ NS_ASSUME_NONNULL_BEGIN
return [UIColor blackColor]; return [UIColor blackColor];
} }
// TODO: - (UIFont *)quotedTextFont
- (UIFont *)quotedAuthorFont
{ {
return [UIFont ows_regularFontWithSize:10.f]; // Honor dynamic type in the text.
// TODO: ?
return [UIFont ows_dynamicTypeBodyFont];
}
- (UIColor *)fileTypeTextColor
{
return [UIColor colorWithWhite:0.5f alpha:1.f];
}
- (UIFont *)fileTypeFont
{
UIFontDescriptor *fontD =
[self.quotedTextFont.fontDescriptor fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic];
UIFont *font = [UIFont fontWithDescriptor:fontD size:0];
OWSAssert(font);
return font ?: self.quotedTextFont;
}
- (UIColor *)filenameTextColor
{
return [UIColor colorWithWhite:0.5f alpha:1.f];
}
- (UIFont *)filenameFont
{
return self.quotedTextFont;
} }
// TODO:
- (CGFloat)quotedAuthorHeight - (CGFloat)quotedAuthorHeight
{ {
return (CGFloat)ceil([self quotedAuthorFont].lineHeight * 1.f); return (CGFloat)ceil([self quotedAuthorFont].lineHeight * 1.f);
} }
// TODO:
- (CGFloat)quotedAuthorTopInset - (CGFloat)quotedAuthorTopInset
{ {
return 4.f; return 8.f;
} }
// TODO: // TODO:
- (CGFloat)quotedAuthorBottomSpacing - (CGFloat)quotedAuthorBottomSpacing
{ {
return 2.f; return 3.f;
} }
// TODO:
- (CGFloat)quotedTextBottomInset - (CGFloat)quotedTextBottomInset
{ {
return 5.f; return 4.f;
} }
// TODO:
- (CGFloat)quotedReplyStripeThickness - (CGFloat)quotedReplyStripeThickness
{ {
return 2.f; return 2.f;
} }
// TODO:
- (CGFloat)quotedReplyStripeVExtension - (CGFloat)quotedReplyStripeVExtension
{ {
return 5.f; return 8.f;
} }
// The spacing between the vertical "quoted reply stripe" // The spacing between the vertical "quoted reply stripe"
// and the quoted message content. // and the quoted message content.
// TODO:
- (CGFloat)quotedReplyStripeHSpacing - (CGFloat)quotedReplyStripeHSpacing
{ {
return 8.f; return 4.f;
} }
// Distance from top edge of "quoted message" bubble to top of message bubble. // Distance from top edge of "quoted message" bubble to top of message bubble.
// TODO:
- (CGFloat)quotedAttachmentMinVInset - (CGFloat)quotedAttachmentMinVInset
{ {
return 10.f; return 12.f;
} }
// TODO:
- (CGFloat)quotedAttachmentSize - (CGFloat)quotedAttachmentSize
{ {
return 30.f; return 44.f;
} }
// TODO:
- (CGFloat)quotedAttachmentHSpacing - (CGFloat)quotedAttachmentHSpacing
{ {
return 10.f; return 8.f;
} }
// Distance from sides of the quoted content to the sides of the message bubble. // Distance from sides of the quoted content to the sides of the message bubble.
// TODO:
- (CGFloat)quotedContentHInset - (CGFloat)quotedContentHInset
{ {
return 8.f; return 8.f;

@ -2299,6 +2299,14 @@ typedef enum : NSUInteger {
- (void)scrollDownButtonTapped - (void)scrollDownButtonTapped
{ {
#ifdef DEBUG
CGPoint contentOffset = self.collectionView.contentOffset;
contentOffset.y += self.collectionView.height
- (self.collectionView.contentInset.top + self.collectionView.contentInset.bottom);
[self.collectionView setContentOffset:contentOffset animated:NO];
return;
#endif
NSIndexPath *indexPathOfUnreadMessagesIndicator = [self indexPathOfUnreadMessagesIndicator]; NSIndexPath *indexPathOfUnreadMessagesIndicator = [self indexPathOfUnreadMessagesIndicator];
if (indexPathOfUnreadMessagesIndicator != nil) { if (indexPathOfUnreadMessagesIndicator != nil) {
NSInteger unreadRow = indexPathOfUnreadMessagesIndicator.row; NSInteger unreadRow = indexPathOfUnreadMessagesIndicator.row;

@ -1405,6 +1405,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"QUESTIONMARK_PUNCTUATION" = "?"; "QUESTIONMARK_PUNCTUATION" = "?";
/* Indicates the author of a quoted message. Embeds {{the author's name or phone number}}. */
"QUOTED_REPLY_AUTHOR_INDICATOR_FORMAT" = "Replying to %@";
/* Indicates this message is a quoted reply to an audio file. */
"QUOTED_REPLY_TYPE_AUDIO" = "Audio";
/* Indicates this message is a quoted reply to an image file. */
"QUOTED_REPLY_TYPE_IMAGE" = "Image";
/* Indicates this message is a quoted reply to a video file. */
"QUOTED_REPLY_TYPE_VIDEO" = "Video";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"RATING_MSG" = "If you enjoy using Signal to have private conversations, you can support our project by rating it. It won't take more than a minute, and will help others find some privacy."; "RATING_MSG" = "If you enjoy using Signal to have private conversations, you can support our project by rating it. It won't take more than a minute, and will help others find some privacy.";

@ -132,4 +132,9 @@ CG_INLINE CGSize CGSizeCeil(CGSize size)
return CGSizeMake((CGFloat)ceil(size.width), (CGFloat)ceil(size.height)); return CGSizeMake((CGFloat)ceil(size.width), (CGFloat)ceil(size.height));
} }
CG_INLINE CGSize CGSizeRound(CGSize size)
{
return CGSizeMake((CGFloat)round(size.width), (CGFloat)round(size.height));
}
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

Loading…
Cancel
Save