Tweak message cells.

pull/1/head
Matthew Chen 7 years ago
parent ac6f78a5fc
commit 98ac13f9be

@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) UIButton *addToContactsButton;
@property (nonatomic) UIButton *addToProfileWhitelistButton;
@property (nonatomic) UIButton *blockButton;
@property (nonatomic) NSArray<NSLayoutConstraint *> *layoutConstraints;
@property (nonatomic) UIStackView *stackView;
@end
@ -44,16 +46,12 @@ NS_ASSUME_NONNULL_BEGIN
self.layoutMargins = UIEdgeInsetsZero;
self.contentView.layoutMargins = UIEdgeInsetsZero;
// [self setTranslatesAutoresizingMaskIntoConstraints:NO];
self.titleLabel = [UILabel new];
self.titleLabel.textColor = [UIColor blackColor];
self.titleLabel.font = [self titleFont];
self.titleLabel.text = NSLocalizedString(@"CONVERSATION_VIEW_CONTACTS_OFFER_TITLE",
@"Title for the group of buttons show for unknown contacts offering to add them to contacts, etc.");
self.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self.contentView addSubview:self.titleLabel];
self.addToContactsButton = [self
createButtonWithTitle:
@ -68,6 +66,25 @@ NS_ASSUME_NONNULL_BEGIN
[self createButtonWithTitle:NSLocalizedString(@"CONVERSATION_VIEW_UNKNOWN_CONTACT_BLOCK_OFFER",
@"Message shown in conversation view that offers to block an unknown user.")
selector:@selector(block)];
self.stackView = [[UIStackView alloc] initWithArrangedSubviews:@[
self.titleLabel,
]];
self.stackView.axis = UILayoutConstraintAxisVertical;
self.stackView.spacing = self.vSpacing;
self.stackView.alignment = UIStackViewAlignmentCenter;
self.stackView.layoutMargins = UIEdgeInsetsZero;
[self.contentView addSubview:self.stackView];
}
- (void)configureFonts
{
self.titleLabel.font = UIFont.ows_dynamicTypeBodyFont.ows_mediumWeight;
UIFont *buttonFont = UIFont.ows_dynamicTypeBodyFont;
self.addToContactsButton.titleLabel.font = buttonFont;
self.addToProfileWhitelistButton.titleLabel.font = buttonFont;
self.blockButton.titleLabel.font = buttonFont;
}
- (UIButton *)createButtonWithTitle:(NSString *)title selector:(SEL)selector
@ -75,12 +92,10 @@ NS_ASSUME_NONNULL_BEGIN
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitle:title forState:UIControlStateNormal];
[button setTitleColor:[UIColor ows_materialBlueColor] forState:UIControlStateNormal];
button.titleLabel.font = self.buttonFont;
button.titleLabel.textAlignment = NSTextAlignmentCenter;
[button setBackgroundColor:[UIColor colorWithRGBHex:0xf5f5f5]];
button.layer.cornerRadius = 5.f;
[button addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:button];
return button;
}
@ -91,30 +106,55 @@ NS_ASSUME_NONNULL_BEGIN
- (void)loadForDisplayWithTransaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssert(self.layoutInfo);
OWSAssert(self.layoutInfo.viewWidth > 0);
OWSAssert(self.viewItem);
OWSAssert([self.viewItem.interaction isKindOfClass:[OWSContactOffersInteraction class]]);
[self configureFonts];
OWSContactOffersInteraction *interaction = (OWSContactOffersInteraction *)self.viewItem.interaction;
OWSAssert(
interaction.hasBlockOffer || interaction.hasAddToContactsOffer || interaction.hasAddToProfileWhitelistOffer);
[self setNeedsLayout];
}
- (UIFont *)titleFont
{
return UIFont.ows_dynamicTypeBodyFont.ows_mediumWeight;
}
- (UIFont *)buttonFont
{
return UIFont.ows_dynamicTypeBodyFont;
}
CGFloat buttonWidth = 0.f;
if (interaction.hasAddToContactsOffer) {
[self.stackView addArrangedSubview:self.addToContactsButton];
buttonWidth = MAX(buttonWidth, [self.addToContactsButton sizeThatFits:CGSizeZero].width);
}
if (interaction.hasAddToProfileWhitelistOffer) {
[self.stackView addArrangedSubview:self.addToProfileWhitelistButton];
buttonWidth = MAX(buttonWidth, [self.addToProfileWhitelistButton sizeThatFits:CGSizeZero].width);
}
if (interaction.hasBlockOffer) {
[self.stackView addArrangedSubview:self.blockButton];
buttonWidth = MAX(buttonWidth, [self.blockButton sizeThatFits:CGSizeZero].width);
}
- (CGFloat)hMargin
{
return 10.f;
buttonWidth = (2 * self.buttonHPadding + (CGFloat)ceil(buttonWidth));
CGFloat hMargins = (self.layoutInfo.fullWidthGutterLeading + self.layoutInfo.fullWidthGutterTrailing);
CGFloat maxButtonWidth = self.layoutInfo.viewWidth - hMargins;
buttonWidth = MIN(buttonWidth, maxButtonWidth);
CGFloat buttonHeight = self.buttonHeight;
[NSLayoutConstraint deactivateConstraints:self.layoutConstraints];
self.layoutConstraints = @[
[self.addToContactsButton autoSetDimension:ALDimensionWidth toSize:buttonWidth],
[self.addToProfileWhitelistButton autoSetDimension:ALDimensionWidth toSize:buttonWidth],
[self.blockButton autoSetDimension:ALDimensionWidth toSize:buttonWidth],
[self.addToContactsButton autoSetDimension:ALDimensionHeight toSize:buttonHeight],
[self.addToProfileWhitelistButton autoSetDimension:ALDimensionHeight toSize:buttonHeight],
[self.blockButton autoSetDimension:ALDimensionHeight toSize:buttonHeight],
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:self.topVMargin],
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:self.bottomVMargin],
// TODO: Honor "full-width gutters"?
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:self.layoutInfo.fullWidthGutterLeading],
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:self.layoutInfo.fullWidthGutterTrailing],
];
}
- (CGFloat)topVMargin
@ -132,47 +172,19 @@ NS_ASSUME_NONNULL_BEGIN
return 5.f;
}
- (CGFloat)buttonVSpacing
- (CGFloat)buttonHPadding
{
return 5.f;
return 60.f;
}
- (void)layoutSubviews
- (CGFloat)vSpacing
{
[super layoutSubviews];
OWSContactOffersInteraction *interaction = (OWSContactOffersInteraction *)self.viewItem.interaction;
return 5.f;
}
// We're using a bit of a hack to get this and the unread indicator to layout as
// "full width" cells. These cells will end up with an erroneous left margin that we
// want to reverse.
CGFloat contentWidth = self.width;
CGFloat left = -self.left;
CGRect titleFrame = self.contentView.bounds;
titleFrame.origin = CGPointMake(left + self.hMargin, self.topVMargin);
titleFrame.size.width = contentWidth - 2 * self.hMargin;
titleFrame.size.height = ceil([self.titleLabel sizeThatFits:CGSizeZero].height);
self.titleLabel.frame = titleFrame;
__block CGFloat y = round(self.titleLabel.bottom + self.buttonVSpacing);
void (^layoutButton)(UIButton *, BOOL) = ^(UIButton *button, BOOL isVisible) {
if (isVisible) {
button.hidden = NO;
button.frame = CGRectMake(round(left + self.hMargin),
round(y),
floor(contentWidth - 2 * self.hMargin),
ceil([button sizeThatFits:CGSizeZero].height + self.buttonVPadding));
y = round(button.bottom + self.buttonVSpacing);
} else {
button.hidden = YES;
}
};
layoutButton(self.addToContactsButton, interaction.hasAddToContactsOffer);
layoutButton(self.addToProfileWhitelistButton, interaction.hasAddToProfileWhitelistOffer);
layoutButton(self.blockButton, interaction.hasBlockOffer);
- (CGFloat)buttonHeight
{
return (self.buttonVPadding + CGSizeCeil([self.addToContactsButton sizeThatFits:CGSizeZero]).height);
}
- (CGSize)cellSize
@ -182,9 +194,10 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(self.viewItem);
OWSAssert([self.viewItem.interaction isKindOfClass:[OWSContactOffersInteraction class]]);
[self configureFonts];
OWSContactOffersInteraction *interaction = (OWSContactOffersInteraction *)self.viewItem.interaction;
// TODO: Should we use viewWidth?
CGSize result = CGSizeMake(self.layoutInfo.viewWidth, 0);
result.height += self.topVMargin;
result.height += self.bottomVMargin;
@ -193,8 +206,7 @@ NS_ASSUME_NONNULL_BEGIN
int buttonCount = ((interaction.hasBlockOffer ? 1 : 0) + (interaction.hasAddToContactsOffer ? 1 : 0)
+ (interaction.hasAddToProfileWhitelistOffer ? 1 : 0));
result.height += buttonCount
* (self.buttonVPadding + self.buttonVSpacing + ceil([self.addToContactsButton sizeThatFits:CGSizeZero].height));
result.height += buttonCount * (self.vSpacing + self.buttonHeight);
return result;
}
@ -236,6 +248,15 @@ NS_ASSUME_NONNULL_BEGIN
[self.delegate tappedUnknownContactBlockOfferMessage:self.interaction];
}
- (void)prepareForReuse
{
[super prepareForReuse];
[self.addToContactsButton removeFromSuperview];
[self.addToProfileWhitelistButton removeFromSuperview];
[self.blockButton removeFromSuperview];
}
@end
NS_ASSUME_NONNULL_END

@ -51,8 +51,6 @@ NS_ASSUME_NONNULL_BEGIN
self.layoutMargins = UIEdgeInsetsZero;
self.contentView.layoutMargins = UIEdgeInsetsZero;
self.backgroundColor = [UIColor whiteColor];
self.imageView = [UIImageView new];
[self.imageView autoSetDimension:ALDimensionWidth toSize:self.iconSize];
[self.imageView autoSetDimension:ALDimensionHeight toSize:self.iconSize];
@ -70,6 +68,7 @@ NS_ASSUME_NONNULL_BEGIN
self.stackView.axis = UILayoutConstraintAxisHorizontal;
self.stackView.spacing = self.hSpacing;
self.stackView.alignment = UIStackViewAlignmentCenter;
self.stackView.layoutMargins = UIEdgeInsetsZero;
[self.contentView addSubview:self.stackView];
UITapGestureRecognizer *tap =
@ -112,18 +111,15 @@ NS_ASSUME_NONNULL_BEGIN
[self.titleLabel autoSetDimension:ALDimensionWidth toSize:titleSize.width],
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:self.topVMargin],
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:self.bottomVMargin],
// H-center the stack.
[self.stackView autoHCenterInSuperview],
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeLeading
withInset:self.layoutInfo.fullWidthGutterLeading + self.hMargin
withInset:self.layoutInfo.fullWidthGutterLeading
relation:NSLayoutRelationGreaterThanOrEqual],
[self.stackView autoPinEdgeToSuperviewEdge:ALEdgeTrailing
withInset:self.layoutInfo.fullWidthGutterTrailing + self.hMargin
withInset:self.layoutInfo.fullWidthGutterTrailing
relation:NSLayoutRelationGreaterThanOrEqual],
];
[self.contentView logFrameLaterWithLabel:@"contentView"];
[self.stackView logFrameLaterWithLabel:@"stackView"];
[self.titleLabel logFrameLaterWithLabel:@"titleLabel"];
}
- (UIColor *)textColor
@ -248,11 +244,6 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (CGFloat)hMargin
{
return 25.f;
}
- (CGFloat)topVMargin
{
return 5.f;
@ -278,8 +269,9 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(self.layoutInfo);
OWSAssert(self.viewItem);
CGFloat hMargins = (self.layoutInfo.fullWidthGutterLeading + self.layoutInfo.fullWidthGutterTrailing);
CGFloat maxTitleWidth
= (CGFloat)floor(self.layoutInfo.fullWidthContentWidth - (2 * self.hMargin + self.iconSize + self.hSpacing));
= (CGFloat)floor(self.layoutInfo.fullWidthContentWidth - (hMargins + self.iconSize + self.hSpacing));
return [self.titleLabel sizeThatFits:CGSizeMake(maxTitleWidth, CGFLOAT_MAX)];
}

@ -16,13 +16,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, nullable) TSUnreadIndicatorInteraction *interaction;
// TODO:
//@property (nonatomic) UIView *bannerView;
//@property (nonatomic) UIView *bannerTopHighlightView;
//@property (nonatomic) UIView *bannerBottomHighlightView1;
//@property (nonatomic) UIView *bannerBottomHighlightView2;
@property (nonatomic) UILabel *titleLabel;
//@property (nonatomic) UILabel *subtitleLabel;
@property (nonatomic) UIView *strokeView;
@property (nonatomic) NSArray<NSLayoutConstraint *> *layoutConstraints;
@end
@ -50,57 +45,26 @@ NS_ASSUME_NONNULL_BEGIN
self.layoutMargins = UIEdgeInsetsZero;
self.contentView.layoutMargins = UIEdgeInsetsZero;
// self.backgroundColor = [UIColor whiteColor];
// self.bannerView = [UIView new];
// self.bannerView.backgroundColor = [UIColor colorWithRGBHex:0xf6eee3];
// [self.contentView addSubview:self.bannerView];
//
// self.bannerTopHighlightView = [UIView new];
// self.bannerTopHighlightView.backgroundColor = [UIColor colorWithRGBHex:0xf9f3eb];
// [self.bannerView addSubview:self.bannerTopHighlightView];
//
// self.bannerBottomHighlightView1 = [UIView new];
// self.bannerBottomHighlightView1.backgroundColor = [UIColor colorWithRGBHex:0xd1c6b8];
// [self.bannerView addSubview:self.bannerBottomHighlightView1];
//
// self.bannerBottomHighlightView2 = [UIView new];
// self.bannerBottomHighlightView2.backgroundColor = [UIColor colorWithRGBHex:0xdbcfc0];
// [self.bannerView addSubview:self.bannerBottomHighlightView2];
self.strokeView = [UIView new];
// TODO: color.
self.strokeView.backgroundColor = [UIColor colorWithRGBHex:0xf6eee3];
[self.contentView addSubview:self.strokeView];
self.titleLabel = [UILabel new];
// TODO: color.
self.titleLabel.textColor = [UIColor colorWithRGBHex:0x403e3b];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self.contentView addSubview:self.titleLabel];
// self.subtitleLabel = [UILabel new];
// self.subtitleLabel.textColor = [UIColor ows_infoMessageBorderColor];
// self.subtitleLabel.font = [self subtitleFont];
// // The subtitle may wrap to a second line.
// self.subtitleLabel.numberOfLines = 0;
// self.subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping;
// self.subtitleLabel.textAlignment = NSTextAlignmentCenter;
// [self.contentView addSubview:self.subtitleLabel];
[self configureFonts];
}
- (void)configureFonts
{
// Update cell to reflect changes in dynamic text.
self.titleLabel.font = UIFont.ows_dynamicTypeBodyFont;
// self.subtitleLabel.font = [self subtitleFont];
// - (UIFont *)titleFont
// {
// return UIFont.ows_dynamicTypeBodyFont;
// }
//
// - (UIFont *)subtitleFont
// {
// return UIFont.ows_dynamicTypeCaption1Font;
// }
// TODO: Font size.
self.titleLabel.font = UIFont.ows_dynamicTypeSubheadlineFont;
}
+ (NSString *)cellReuseIdentifier
@ -119,20 +83,21 @@ NS_ASSUME_NONNULL_BEGIN
TSUnreadIndicatorInteraction *interaction = (TSUnreadIndicatorInteraction *)self.viewItem.interaction;
self.titleLabel.text = [self titleForInteraction:interaction];
// self.subtitleLabel.text = [self subtitleForInteraction:interaction];
self.backgroundColor = [UIColor whiteColor];
[NSLayoutConstraint deactivateConstraints:self.layoutConstraints];
self.layoutConstraints = @[
// TODO: Constants.
[self.titleLabel autoVCenterInSuperview],
[self.titleLabel autoPinLeadingToSuperviewMarginWithInset:self.layoutInfo.fullWidthGutterLeading],
[self.titleLabel autoPinTrailingToSuperviewMarginWithInset:self.layoutInfo.fullWidthGutterTrailing],
];
// TODO:
// [self setNeedsLayout];
// TODO: offset.
[self.strokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:self.titleLabel withOffset:0.f],
[self.strokeView autoPinLeadingToSuperviewMarginWithInset:self.layoutInfo.fullWidthGutterLeading],
[self.strokeView autoPinTrailingToSuperviewMarginWithInset:self.layoutInfo.fullWidthGutterTrailing],
[self.strokeView autoSetDimension:ALDimensionHeight toSize:1.f],
];
}
- (NSString *)titleForInteraction:(TSUnreadIndicatorInteraction *)interaction
@ -141,98 +106,6 @@ NS_ASSUME_NONNULL_BEGIN
.uppercaseString;
}
//- (NSString *)subtitleForInteraction:(TSUnreadIndicatorInteraction *)interaction
//{
// if (!interaction.hasMoreUnseenMessages) {
// return nil;
// }
// NSString *subtitleFormat = (interaction.missingUnseenSafetyNumberChangeCount > 0
// ? NSLocalizedString(@"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_FORMAT",
// @"Messages that indicates that there are more unseen messages that be revealed by tapping the 'load
// "
// @"earlier messages' button. Embeds {{the name of the 'load earlier messages' button}}")
// : NSLocalizedString(
// @"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES_FORMAT",
// @"Messages that indicates that there are more unseen messages including safety number changes that "
// @"be revealed by tapping the 'load earlier messages' button. Embeds {{the name of the 'load earlier
// "
// @"messages' button}}."));
// NSString *loadMoreButtonName = NSLocalizedString(
// @"load_earlier_messages", @"Label for button that loads more messages in conversation view.");
// return [NSString stringWithFormat:subtitleFormat, loadMoreButtonName];
//}
//- (CGFloat)subtitleHMargin
//{
// return 20.f;
//}
//
//- (CGFloat)subtitleVSpacing
//{
// return 3.f;
//}
//
//- (CGFloat)titleInnerHMargin
//{
// return 10.f;
//}
//
//- (CGFloat)titleVMargin
//{
// return 5.5f;
//}
//
//- (CGFloat)topVMargin
//{
// return 5.f;
//}
//
//- (CGFloat)bottomVMargin
//{
// return 5.f;
//}
//- (void)layoutSubviews
//{
// [super layoutSubviews];
//
// [self.titleLabel sizeToFit];
//
// // It's a bit of a hack, but we use a view that extends _outside_ the cell's bounds
// // to draw its background, since we want the background to extend to the edges of the
// // collection view.
// //
// // This layout logic assumes that the cell insets are symmetrical and can be deduced
// // from the cell frame.
// CGRect bannerViewFrame = CGRectMake(-self.left,
// round(self.topVMargin),
// round(self.width + self.left * 2.f),
// round(self.titleLabel.height + self.titleVMargin * 2.f));
// self.bannerView.frame = [self convertRect:bannerViewFrame toView:self.contentView];
//
// // The highlights should be 1px (not 1pt), so adapt their thickness to
// // the device resolution.
// CGFloat kHighlightThickness = 1.f / [UIScreen mainScreen].scale;
// self.bannerTopHighlightView.frame = CGRectMake(0, 0, self.bannerView.width, kHighlightThickness);
// self.bannerBottomHighlightView1.frame
// = CGRectMake(0, self.bannerView.height - kHighlightThickness * 2.f, self.bannerView.width,
// kHighlightThickness);
// self.bannerBottomHighlightView2.frame
// = CGRectMake(0, self.bannerView.height - kHighlightThickness * 1.f, self.bannerView.width,
// kHighlightThickness);
//
// [self.titleLabel centerOnSuperview];
//
// if (self.subtitleLabel.text.length > 0) {
// CGSize subtitleSize = [self.subtitleLabel
// sizeThatFits:CGSizeMake(self.contentView.width - [self subtitleHMargin] * 2.f, CGFLOAT_MAX)];
// self.subtitleLabel.frame = CGRectMake(round((self.contentView.width - subtitleSize.width) * 0.5f),
// round(self.bannerView.bottom + self.subtitleVSpacing),
// ceil(subtitleSize.width),
// ceil(subtitleSize.height));
// }
//}
- (CGSize)cellSize
{
OWSAssert(self.layoutInfo);
@ -241,28 +114,9 @@ NS_ASSUME_NONNULL_BEGIN
[self configureFonts];
// TSUnreadIndicatorInteraction *interaction = (TSUnreadIndicatorInteraction *)self.viewItem.interaction;
// TODO:
CGSize result = CGSizeMake(self.layoutInfo.fullWidthContentWidth, self.titleLabel.font.lineHeight + 24.f * 2);
// result.height += self.titleVMargin * 2.f;
// result.height += self.topVMargin;
// result.height += self.bottomVMargin;
//
// NSString *title = [self titleForInteraction:interaction];
// NSString *subtitle = [self subtitleForInteraction:interaction];
//
// self.titleLabel.text = title;
// result.height += ceil([self.titleLabel sizeThatFits:CGSizeZero].height);
//
// if (subtitle.length > 0) {
// result.height += self.subtitleVSpacing;
//
// self.subtitleLabel.text = subtitle;
// result.height += ceil(
// [self.subtitleLabel sizeThatFits:CGSizeMake(self.layoutInfo.fullWidthContentWidth -
// self.subtitleHMargin * 2.f, CGFLOAT_MAX)].height);
// }
// TODO: offset.
CGFloat vOffset = 24.f;
CGSize result = CGSizeMake(self.layoutInfo.fullWidthContentWidth, self.titleLabel.font.lineHeight + vOffset * 2);
return CGSizeCeil(result);
}

@ -20,8 +20,8 @@ public class ConversationLayoutInfo: NSObject {
}
}
@objc public let contentMarginTop: CGFloat = 0
@objc public let contentMarginBottom: CGFloat = 0
@objc public let contentMarginTop: CGFloat = 10
@objc public let contentMarginBottom: CGFloat = 10
@objc public var gutterLeading: CGFloat = 0
@objc public var gutterTrailing: CGFloat = 0
@ -59,9 +59,9 @@ public class ConversationLayoutInfo: NSObject {
gutterLeading = 40
gutterTrailing = 20
}
// TODO: Should these be symmetric?
fullWidthGutterLeading = gutterLeading
fullWidthGutterTrailing = gutterTrailing
// TODO: Should these be symmetric? Should they reflect the other gutters?
fullWidthGutterLeading = 20
fullWidthGutterTrailing = 20
contentWidth = viewWidth - (gutterLeading + gutterTrailing)

Loading…
Cancel
Save