From 7d5ad0e165af67106cc9ec60caaf2a2591245fe6 Mon Sep 17 00:00:00 2001
From: Matthew Chen <matthew@signal.org>
Date: Tue, 26 Jun 2018 10:17:03 -0400
Subject: [PATCH] Introduce message cell footer view.

---
 .../Cells/OWSMessageFooterView.h              |  2 +-
 .../Cells/OWSMessageFooterView.m              | 91 ++++++++++++-------
 .../ViewControllers/HomeView/HomeViewCell.m   | 13 +--
 Signal/src/util/DateUtil.h                    |  3 +
 Signal/src/util/DateUtil.m                    | 23 +++++
 5 files changed, 86 insertions(+), 46 deletions(-)

diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.h b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.h
index a3d1dfcda..28836b316 100644
--- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.h
+++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.h
@@ -6,7 +6,7 @@
 
 NS_ASSUME_NONNULL_BEGIN
 
-@interface OWSMessageFooterView : UIView
+@interface OWSMessageFooterView : UIStackView
 
 - (void)configureWithConversationViewItem:(ConversationViewItem *)viewItem;
 
diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.m
index 656b17a60..4d854e09e 100644
--- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.m
+++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.m
@@ -11,6 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
 @interface OWSMessageFooterView ()
 
 @property (nonatomic) UILabel *timestampLabel;
+@property (nonatomic) UIView *spacerView;
 @property (nonatomic) UILabel *statusLabel;
 @property (nonatomic) UIView *statusIndicatorView;
 
@@ -35,10 +36,16 @@ NS_ASSUME_NONNULL_BEGIN
 
     self.layoutMargins = UIEdgeInsetsZero;
 
+    self.axis = UILayoutConstraintAxisHorizontal;
+    self.spacing = self.hSpacing;
+    self.alignment = UIStackViewAlignmentCenter;
+
     self.timestampLabel = [UILabel new];
     // TODO: Color
     self.timestampLabel.textColor = [UIColor lightGrayColor];
-    [self addSubview:self.timestampLabel];
+
+    self.spacerView = [UIView new];
+    [self.spacerView setContentHuggingLow];
 
     self.statusLabel = [UILabel new];
     // TODO: Color
@@ -49,30 +56,30 @@ NS_ASSUME_NONNULL_BEGIN
     [self.statusIndicatorView autoSetDimension:ALDimensionHeight toSize:self.statusIndicatorSize];
     self.statusIndicatorView.layer.cornerRadius = self.statusIndicatorSize * 0.5f;
 
-    // TODO: Review constant with Myles.0
-    UIStackView *statusStackView = [[UIStackView alloc] initWithArrangedSubviews:@[
-        self.statusLabel,
-        self.statusIndicatorView,
-    ]];
-    statusStackView.axis = UILayoutConstraintAxisHorizontal;
-    statusStackView.spacing = self.hSpacing;
-    [self addSubview:statusStackView];
-
-    [self.timestampLabel autoPinEdgeToSuperviewEdge:ALEdgeLeading];
-    [statusStackView autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
-    [self.timestampLabel autoVCenterInSuperview];
-    [statusStackView autoVCenterInSuperview];
-    [self.timestampLabel autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:0 relation:NSLayoutRelationGreaterThanOrEqual];
-    [self.timestampLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom
-                                          withInset:0
-                                           relation:NSLayoutRelationGreaterThanOrEqual];
-    [statusStackView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:0 relation:NSLayoutRelationGreaterThanOrEqual];
-    [statusStackView autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:0 relation:NSLayoutRelationGreaterThanOrEqual];
-    [statusStackView autoPinEdge:ALEdgeLeading
-                          toEdge:ALEdgeTrailing
-                          ofView:self.timestampLabel
-                      withOffset:self.hSpacing
-                        relation:NSLayoutRelationGreaterThanOrEqual];
+    //    // TODO: Review constant with Myles.0
+    //    UIStackView *statusStackView = [[UIStackView alloc] initWithArrangedSubviews:@[
+    //        self.statusLabel,
+    //        self.statusIndicatorView,
+    //    ]];
+    //    statusStackView.axis = UILayoutConstraintAxisHorizontal;
+    //    statusStackView.spacing = self.hSpacing;
+    //    [self addSubview:statusStackView];
+
+    //    [self.timestampLabel autoPinEdgeToSuperviewEdge:ALEdgeLeading];
+    //    [statusStackView autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
+    //    [self.timestampLabel autoVCenterInSuperview];
+    //    [statusStackView autoVCenterInSuperview];
+    //    [self.timestampLabel autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:0
+    //    relation:NSLayoutRelationGreaterThanOrEqual]; [self.timestampLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom
+    //                                          withInset:0
+    //                                           relation:NSLayoutRelationGreaterThanOrEqual];
+    //    [statusStackView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:0
+    //    relation:NSLayoutRelationGreaterThanOrEqual]; [statusStackView autoPinEdgeToSuperviewEdge:ALEdgeBottom
+    //    withInset:0 relation:NSLayoutRelationGreaterThanOrEqual]; [statusStackView autoPinEdge:ALEdgeLeading
+    //                          toEdge:ALEdgeTrailing
+    //                          ofView:self.timestampLabel
+    //                      withOffset:self.hSpacing
+    //                        relation:NSLayoutRelationGreaterThanOrEqual];
 }
 
 - (void)configureFonts
@@ -84,13 +91,13 @@ NS_ASSUME_NONNULL_BEGIN
 - (CGFloat)statusIndicatorSize
 {
     // TODO: Review constant.
-    return 16.f;
+    return 12.f;
 }
 
 - (CGFloat)hSpacing
 {
     // TODO: Review constant.
-    return 10.f;
+    return 8.f;
 }
 
 #pragma mark - Load
@@ -102,7 +109,23 @@ NS_ASSUME_NONNULL_BEGIN
     [self configureLabelsWithConversationViewItem:viewItem];
 
     // TODO:
-    self.statusIndicatorView.backgroundColor = [UIColor redColor];
+    self.statusIndicatorView.backgroundColor = [UIColor orangeColor];
+
+    for (UIView *subview in @[
+             self.timestampLabel,
+             self.statusLabel,
+             self.statusIndicatorView,
+         ]) {
+        [subview removeFromSuperview];
+    }
+    if (viewItem.interaction.interactionType == OWSInteractionType_OutgoingMessage) {
+        [self addArrangedSubview:self.timestampLabel];
+        [self addArrangedSubview:self.spacerView];
+        [self addArrangedSubview:self.statusLabel];
+        [self addArrangedSubview:self.statusIndicatorView];
+    } else {
+        [self addArrangedSubview:self.timestampLabel];
+    }
 }
 
 - (void)configureLabelsWithConversationViewItem:(ConversationViewItem *)viewItem
@@ -111,9 +134,7 @@ NS_ASSUME_NONNULL_BEGIN
 
     [self configureFonts];
 
-    // TODO: Correct text.
-    self.timestampLabel.text =
-        [DateUtil formatPastTimestampRelativeToNow:viewItem.interaction.timestamp isRTL:CurrentAppContext().isRTL];
+    self.timestampLabel.text = [DateUtil formatTimestampShort:viewItem.interaction.timestamp];
     self.statusLabel.text = [self messageStatusTextForConversationViewItem:viewItem];
 }
 
@@ -126,8 +147,12 @@ NS_ASSUME_NONNULL_BEGIN
     CGSize result = CGSizeZero;
     result.height
         = MAX(self.timestampLabel.font.lineHeight, MAX(self.statusLabel.font.lineHeight, self.statusIndicatorSize));
-    result.width = ([self.timestampLabel sizeThatFits:CGSizeZero].width +
-        [self.statusLabel sizeThatFits:CGSizeZero].width + self.statusIndicatorSize + self.hSpacing * 2.f);
+    if (viewItem.interaction.interactionType == OWSInteractionType_OutgoingMessage) {
+        result.width = ([self.timestampLabel sizeThatFits:CGSizeZero].width +
+            [self.statusLabel sizeThatFits:CGSizeZero].width + self.statusIndicatorSize + self.hSpacing * 3.f);
+    } else {
+        result.width = [self.timestampLabel sizeThatFits:CGSizeZero].width;
+    }
     return CGSizeCeil(result);
 }
 
diff --git a/Signal/src/ViewControllers/HomeView/HomeViewCell.m b/Signal/src/ViewControllers/HomeView/HomeViewCell.m
index abc1af63c..fa9feb95a 100644
--- a/Signal/src/ViewControllers/HomeView/HomeViewCell.m
+++ b/Signal/src/ViewControllers/HomeView/HomeViewCell.m
@@ -342,18 +342,7 @@ NS_ASSUME_NONNULL_BEGIN
         return @"";
     }
 
-    NSString *dateTimeString;
-    if (![DateUtil dateIsThisYear:date]) {
-        dateTimeString = [[DateUtil dateFormatter] stringFromDate:date];
-    } else if ([DateUtil dateIsOlderThanOneWeek:date]) {
-        dateTimeString = [[DateUtil monthAndDayFormatter] stringFromDate:date];
-    } else if ([DateUtil dateIsOlderThanToday:date]) {
-        dateTimeString = [[DateUtil shortDayOfWeekFormatter] stringFromDate:date];
-    } else {
-        dateTimeString = [[DateUtil timeFormatter] stringFromDate:date];
-    }
-
-    return dateTimeString.uppercaseString;
+    return [DateUtil formatDateShort:date];
 }
 
 #pragma mark - Constants
diff --git a/Signal/src/util/DateUtil.h b/Signal/src/util/DateUtil.h
index 0ef6bf2d1..913808b2e 100644
--- a/Signal/src/util/DateUtil.h
+++ b/Signal/src/util/DateUtil.h
@@ -20,6 +20,9 @@ NS_ASSUME_NONNULL_BEGIN
 + (NSString *)formatPastTimestampRelativeToNow:(uint64_t)pastTimestamp
                                          isRTL:(BOOL)isRTL NS_SWIFT_NAME(formatPastTimestampRelativeToNow(_:isRTL:));
 
++ (NSString *)formatTimestampShort:(uint64_t)timestamp;
++ (NSString *)formatDateShort:(NSDate *)date;
+
 @end
 
 NS_ASSUME_NONNULL_END
diff --git a/Signal/src/util/DateUtil.m b/Signal/src/util/DateUtil.m
index 168728be2..3152b6e92 100644
--- a/Signal/src/util/DateUtil.m
+++ b/Signal/src/util/DateUtil.m
@@ -165,6 +165,29 @@ static NSString *const DATE_FORMAT_WEEKDAY = @"EEEE";
                                                                 isRTL:isRTL];
 }
 
++ (NSString *)formatTimestampShort:(uint64_t)timestamp
+{
+    return [self formatDateShort:[NSDate ows_dateWithMillisecondsSince1970:timestamp]];
+}
+
++ (NSString *)formatDateShort:(NSDate *)date
+{
+    OWSAssert(date);
+
+    NSString *dateTimeString;
+    if (![DateUtil dateIsThisYear:date]) {
+        dateTimeString = [[DateUtil dateFormatter] stringFromDate:date];
+    } else if ([DateUtil dateIsOlderThanOneWeek:date]) {
+        dateTimeString = [[DateUtil monthAndDayFormatter] stringFromDate:date];
+    } else if ([DateUtil dateIsOlderThanToday:date]) {
+        dateTimeString = [[DateUtil shortDayOfWeekFormatter] stringFromDate:date];
+    } else {
+        dateTimeString = [[DateUtil timeFormatter] stringFromDate:date];
+    }
+
+    return dateTimeString.uppercaseString;
+}
+
 @end
 
 NS_ASSUME_NONNULL_END