diff --git a/Signal/src/ViewControllers/HomeView/HomeViewCell.m b/Signal/src/ViewControllers/HomeView/HomeViewCell.m index 8fbf77420..2658d5d10 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewCell.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewCell.m @@ -23,12 +23,13 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) UILabel *dateTimeLabel; @property (nonatomic) MessageStatusView *messageStatusView; @property (nonatomic) TypingIndicatorView *typingIndicatorView; -@property (nonatomic) UIStackView *previewStackView; @property (nonatomic) UIView *unreadBadge; @property (nonatomic) UILabel *unreadLabel; @property (nonatomic, nullable) ThreadViewModel *thread; +@property (nonatomic, nullable) NSAttributedString *overrideSnippet; +@property (nonatomic) BOOL isBlocked; @property (nonatomic, readonly) NSMutableArray *viewConstraints; @@ -118,25 +119,19 @@ NS_ASSUME_NONNULL_BEGIN self.snippetLabel.font = [self snippetFont]; self.snippetLabel.numberOfLines = 1; self.snippetLabel.lineBreakMode = NSLineBreakByTruncatingTail; + [self.snippetLabel setContentHuggingHorizontalLow]; + [self.snippetLabel setCompressionResistanceHorizontalLow]; self.typingIndicatorView = [TypingIndicatorView new]; - - self.previewStackView = [[UIStackView alloc] initWithArrangedSubviews:@[ - self.snippetLabel, - self.typingIndicatorView, - ]]; - self.previewStackView.axis = UILayoutConstraintAxisVertical; - self.previewStackView.alignment = UIStackViewAlignmentLeading; - [self.previewStackView setContentHuggingHorizontalLow]; - [self.previewStackView setCompressionResistanceHorizontalLow]; + [self.contentView addSubview:self.typingIndicatorView]; UIStackView *bottomRowView = [[UIStackView alloc] initWithArrangedSubviews:@[ - self.previewStackView, + self.snippetLabel, self.messageStatusView, ]]; - + bottomRowView.axis = UILayoutConstraintAxisHorizontal; - bottomRowView.alignment = UIStackViewAlignmentCenter; + bottomRowView.alignment = UIStackViewAlignmentLastBaseline; bottomRowView.spacing = 6.f; UIStackView *vStackView = [[UIStackView alloc] initWithArrangedSubviews:@[ @@ -171,6 +166,9 @@ NS_ASSUME_NONNULL_BEGIN [self.contentView addSubview:self.unreadBadge]; [self.unreadBadge autoAlignAxis:ALAxisHorizontal toSameAxisOfView:self.nameLabel]; + + [self.typingIndicatorView autoPinEdge:ALEdgeLeading toEdge:ALEdgeLeading ofView:self.snippetLabel]; + [self.typingIndicatorView autoAlignAxis:ALAxisHorizontal toSameAxisOfView:self.snippetLabel]; } - (void)dealloc @@ -213,6 +211,8 @@ NS_ASSUME_NONNULL_BEGIN [OWSTableItem configureCell:self]; self.thread = thread; + self.overrideSnippet = overrideSnippet; + self.isBlocked = isBlocked; BOOL hasUnreadMessages = thread.hasUnreadMessages; @@ -231,18 +231,8 @@ NS_ASSUME_NONNULL_BEGIN // changes to the dynamic type settings are reflected. self.snippetLabel.font = [self snippetFont]; - if (overrideSnippet) { - self.snippetLabel.attributedText = overrideSnippet; - } else { - self.snippetLabel.attributedText = [self attributedSnippetForThread:thread isBlocked:isBlocked]; - } [self updatePreview]; - CGFloat previewHeight = MAX(self.snippetLabel.font.lineHeight, - TypingIndicatorView.kMaxRadiusPt); - [self.viewConstraints addObjectsFromArray:@[ - [self.previewStackView autoSetDimension:ALDimensionHeight - toSize:previewHeight], - ]]; + self.dateTimeLabel.text = (overrideDate ? [self stringForDate:overrideDate] : [self stringForDate:thread.lastMessageDate]); @@ -469,6 +459,7 @@ NS_ASSUME_NONNULL_BEGIN [self.viewConstraints removeAllObjects]; self.thread = nil; + self.overrideSnippet = nil; self.avatarView.image = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; @@ -532,11 +523,20 @@ NS_ASSUME_NONNULL_BEGIN - (void)updatePreview { if ([self.typingIndicators typingRecipientIdForThread:self.thread.threadRecord] != nil) { - self.snippetLabel.hidden = YES; + // If we hide snippetLabel, our layout will break since UIStackView will remove + // it from the layout. Wrapping the preview views (the snippet label and the + // typing indicator) in a UIStackView proved non-trivial since we're using + // UIStackViewAlignmentLastBaseline. Therefore we hide the _contents_ of the + // snippet label using an empty string. + self.snippetLabel.text = @" "; self.typingIndicatorView.hidden = NO; [self.typingIndicatorView startAnimation]; } else { - self.snippetLabel.hidden = NO; + if (self.overrideSnippet) { + self.snippetLabel.attributedText = self.overrideSnippet; + } else { + self.snippetLabel.attributedText = [self attributedSnippetForThread:self.thread isBlocked:self.isBlocked]; + } self.typingIndicatorView.hidden = YES; [self.typingIndicatorView stopAnimation]; }