From f50fe92d57a656f7ee6591bff6fc9ec2b0d5785f Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 10 Dec 2019 14:27:38 +1100 Subject: [PATCH] WIP --- .../Components/ProfilePictureView.swift | 9 +++-- .../Loki/Redesign/Style Guide/Colors.swift | 2 + .../Loki/Redesign/Style Guide/Values.swift | 1 + .../ConversationView/Cells/OWSBubbleView.m | 3 +- .../Cells/OWSMessageBubbleView.m | 14 +++---- .../ConversationView/Cells/OWSMessageCell.m | 25 +++++------- .../Cells/OWSMessageFooterView.m | 37 +----------------- .../Cells/OWSMessageHeaderView.m | 26 ++++++++----- SignalMessaging/utils/ConversationStyle.swift | 39 ++++++++----------- 9 files changed, 62 insertions(+), 94 deletions(-) diff --git a/Signal/src/Loki/Redesign/Components/ProfilePictureView.swift b/Signal/src/Loki/Redesign/Components/ProfilePictureView.swift index dbc8fcd41..499f5d9cf 100644 --- a/Signal/src/Loki/Redesign/Components/ProfilePictureView.swift +++ b/Signal/src/Loki/Redesign/Components/ProfilePictureView.swift @@ -1,10 +1,11 @@ +@objc(LKProfilePictureView) final class ProfilePictureView : UIView { private var imageViewWidthConstraint: NSLayoutConstraint! private var imageViewHeightConstraint: NSLayoutConstraint! - var size: CGFloat! - var hexEncodedPublicKey: String! - var additionalHexEncodedPublicKey: String? + @objc var size: CGFloat = 0 // Not an implicitly unwrapped optional due to Obj-C limitations + @objc var hexEncodedPublicKey: String! + @objc var additionalHexEncodedPublicKey: String? // MARK: Components private lazy var imageView = getImageView() @@ -37,7 +38,7 @@ final class ProfilePictureView : UIView { } // MARK: Updating - func update() { + @objc func update() { if let imageViewWidthConstraint = imageViewWidthConstraint, let imageViewHeightConstraint = imageViewHeightConstraint { imageView.removeConstraint(imageViewWidthConstraint) imageView.removeConstraint(imageViewHeightConstraint) diff --git a/Signal/src/Loki/Redesign/Style Guide/Colors.swift b/Signal/src/Loki/Redesign/Style Guide/Colors.swift index 916725218..54e6ac3e0 100644 --- a/Signal/src/Loki/Redesign/Style Guide/Colors.swift +++ b/Signal/src/Loki/Redesign/Style Guide/Colors.swift @@ -33,4 +33,6 @@ final class Colors : NSObject { @objc static let fakeChatBubbleText = UIColor(hex: 0x000000) @objc static let composeViewBackground = UIColor(hex: 0x1B1B1B) @objc static let composeViewTextFieldBackground = UIColor(hex: 0x141414) + @objc static let receivedMessageBackgroundColor = UIColor(hex: 0x222325) + @objc static let sentMessageBackgroundColor = UIColor(hex: 0x3F4146) } diff --git a/Signal/src/Loki/Redesign/Style Guide/Values.swift b/Signal/src/Loki/Redesign/Style Guide/Values.swift index 88e0ea2ae..a9b037450 100644 --- a/Signal/src/Loki/Redesign/Style Guide/Values.swift +++ b/Signal/src/Loki/Redesign/Style Guide/Values.swift @@ -42,6 +42,7 @@ final class Values : NSObject { @objc static let fakeChatBubbleCornerRadius = CGFloat(10) @objc static let fakeChatViewHeight = CGFloat(234) @objc static var composeViewTextFieldBorderThickness: CGFloat { return 1 / UIScreen.main.scale } + @objc static let messageBubbleCornerRadius: CGFloat = 10 // MARK: - Distances @objc static let verySmallSpacing = CGFloat(4) diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m index 14ee8e436..a7ee86c10 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m @@ -5,6 +5,7 @@ #import "OWSBubbleView.h" #import "MainAppContext.h" #import +#import "Session-Swift.h" NS_ASSUME_NONNULL_BEGIN @@ -37,7 +38,7 @@ UIRectCorner UIRectCornerForOWSDirectionalRectCorner(OWSDirectionalRectCorner co return rectCorner; } -const CGFloat kOWSMessageCellCornerRadius_Large = 18; +const CGFloat kOWSMessageCellCornerRadius_Large = 10; // LKValues.messageBubbleCornerRadius const CGFloat kOWSMessageCellCornerRadius_Small = 4; @interface OWSBubbleView () diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m index c4f79d343..11be8bce8 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m @@ -146,7 +146,7 @@ NS_ASSUME_NONNULL_BEGIN break; } - return UIFont.ows_dynamicTypeBodyFont; + return [UIFont systemFontOfSize:LKValues.mediumFontSize]; } #pragma mark - Convenience Accessors @@ -497,7 +497,7 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)senderNameBottomSpacing { - return 2.f; + return 0.f; } - (OWSDirectionalRectCorner)sharpCorners @@ -623,7 +623,7 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)textViewVSpacing { - return 2.f; + return 4.f; } - (CGFloat)bodyMediaQuotedReplyVSpacing @@ -741,15 +741,15 @@ NS_ASSUME_NONNULL_BEGIN OWSAssertDebug(self.senderNameLabel); OWSAssertDebug(self.shouldShowSenderName); - self.senderNameLabel.textColor = self.bodyTextColor; + self.senderNameLabel.textColor = [LKColors.text colorWithAlphaComponent:LKValues.unimportantElementOpacity]; self.senderNameLabel.font = OWSMessageBubbleView.senderNameFont; - self.senderNameLabel.attributedText = self.viewItem.senderName; + self.senderNameLabel.text = self.viewItem.senderName.string; self.senderNameLabel.lineBreakMode = NSLineBreakByTruncatingTail; } + (UIFont *)senderNameFont { - return UIFont.ows_dynamicTypeSubheadlineFont.ows_mediumWeight; + return [UIFont boldSystemFontOfSize:LKValues.smallFontSize]; } + (NSDictionary *)senderNamePrimaryAttributes @@ -789,7 +789,7 @@ NS_ASSUME_NONNULL_BEGIN tapForMoreLabel.text = NSLocalizedString(@"CONVERSATION_VIEW_OVERSIZE_TEXT_TAP_FOR_MORE", @"Indicator on truncated text messages that they can be tapped to see the entire text message."); tapForMoreLabel.font = [self tapForMoreFont]; - tapForMoreLabel.textColor = [self.bodyTextColor colorWithAlphaComponent:0.85]; + tapForMoreLabel.textColor = [self.bodyTextColor colorWithAlphaComponent:0.8]; tapForMoreLabel.textAlignment = [tapForMoreLabel textAlignmentUnnatural]; return tapForMoreLabel; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index 6eef3c5ed..9f557822a 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) OWSMessageHeaderView *headerView; @property (nonatomic) OWSMessageBubbleView *messageBubbleView; @property (nonatomic) NSLayoutConstraint *messageBubbleViewBottomConstraint; -@property (nonatomic) AvatarImageView *avatarView; +@property (nonatomic) LKProfilePictureView *avatarView; @property (nonatomic) UIImageView *moderatorIconImageView; @property (nonatomic, nullable) LKFriendRequestView *friendRequestView; @property (nonatomic, nullable) UIImageView *sendFailureBadgeView; @@ -59,7 +59,7 @@ NS_ASSUME_NONNULL_BEGIN self.headerView = [OWSMessageHeaderView new]; - self.avatarView = [[AvatarImageView alloc] init]; + self.avatarView = [[LKProfilePictureView alloc] init]; [self.avatarView autoSetDimension:ALDimensionWidth toSize:self.avatarSize]; [self.avatarView autoSetDimension:ALDimensionHeight toSize:self.avatarSize]; @@ -179,7 +179,7 @@ NS_ASSUME_NONNULL_BEGIN self.sendFailureBadgeView = [UIImageView new]; self.sendFailureBadgeView.image = [self.sendFailureBadge imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - self.sendFailureBadgeView.tintColor = [UIColor ows_destructiveRedColor]; + self.sendFailureBadgeView.tintColor = LKColors.destructive; [self.contentView addSubview:self.sendFailureBadgeView]; CGFloat sendFailureBadgeBottomMargin @@ -229,10 +229,7 @@ NS_ASSUME_NONNULL_BEGIN if ([self updateAvatarView]) { [self.viewConstraints addObjectsFromArray:@[ - // V-align the "group sender" avatar with the - // last line of the text (if any, or where it - // would be). - [self.messageBubbleView autoPinLeadingToTrailingEdgeOfView:self.avatarView offset:8], + [self.messageBubbleView autoPinLeadingToTrailingEdgeOfView:self.avatarView offset:LKValues.largeSpacing], [self.messageBubbleView autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:self.avatarView], ]]; @@ -292,12 +289,11 @@ NS_ASSUME_NONNULL_BEGIN } TSIncomingMessage *incomingMessage = (TSIncomingMessage *)self.viewItem.interaction; - UIImage *_Nullable authorAvatarImage = - [[[OWSContactAvatarBuilder alloc] initWithSignalId:incomingMessage.authorId - colorName:self.viewItem.authorConversationColorName - diameter:self.avatarSize] build]; - self.avatarView.image = authorAvatarImage; + [self.contentView addSubview:self.avatarView]; + self.avatarView.size = self.avatarSize; + self.avatarView.hexEncodedPublicKey = incomingMessage.authorId; + [self.avatarView update]; // Loki: Show the moderator icon if needed if (self.viewItem.isGroupThread && !self.viewItem.isRSSFeed) { @@ -323,9 +319,9 @@ NS_ASSUME_NONNULL_BEGIN return YES; } -- (NSUInteger)avatarSize +- (CGFloat)avatarSize { - return 36.f; + return LKValues.smallProfilePictureSize; } - (void)otherUsersProfileDidChange:(NSNotification *)notification @@ -412,7 +408,6 @@ NS_ASSUME_NONNULL_BEGIN [self.friendRequestView removeFromSuperview]; self.friendRequestView = nil; - self.avatarView.image = nil; [self.avatarView removeFromSuperview]; self.moderatorIconImageView.image = nil; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.m index b06d4b9ca..d63a8baa8 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageFooterView.m @@ -57,14 +57,13 @@ NS_ASSUME_NONNULL_BEGIN [leftStackView addArrangedSubview:self.messageTimerView]; self.statusIndicatorImageView = [UIImageView new]; - [self addArrangedSubview:self.statusIndicatorImageView]; self.userInteractionEnabled = NO; } - (void)configureFonts { - self.timestampLabel.font = UIFont.ows_dynamicTypeCaption1Font; + self.timestampLabel.font = [UIFont systemFontOfSize:LKValues.verySmallFontSize]; } - (CGFloat)hSpacing @@ -97,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN UIColor *textColor; if (isOverlayingMedia) { - textColor = [UIColor whiteColor]; + textColor = LKColors.text; } else { textColor = [conversationStyle bubbleSecondaryTextColorWithIsIncoming:isIncoming]; } @@ -117,34 +116,7 @@ NS_ASSUME_NONNULL_BEGIN if (viewItem.interaction.interactionType == OWSInteractionType_OutgoingMessage) { TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)viewItem.interaction; - UIImage *_Nullable statusIndicatorImage = nil; - MessageReceiptStatus messageStatus = - [MessageRecipientStatusUtils recipientStatusWithOutgoingMessage:outgoingMessage]; - switch (messageStatus) { - case MessageReceiptStatusCalculatingPoW: - statusIndicatorImage = [UIImage imageNamed:@"Cog"]; - [self animateSpinningIcon]; - break; - case MessageReceiptStatusUploading: - case MessageReceiptStatusSending: - statusIndicatorImage = [UIImage imageNamed:@"message_status_sending"]; - [self animateSpinningIcon]; - break; - case MessageReceiptStatusSent: - case MessageReceiptStatusSkipped: - statusIndicatorImage = [UIImage imageNamed:@"message_status_sent"]; - break; - case MessageReceiptStatusDelivered: - statusIndicatorImage = [UIImage imageNamed:@"message_status_delivered"]; - break; - case MessageReceiptStatusRead: - statusIndicatorImage = [UIImage imageNamed:@"message_status_read"]; - break; - case MessageReceiptStatusFailed: - // No status indicator icon. - break; - } __block BOOL isNoteToSelf = NO; [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { @@ -253,11 +225,6 @@ NS_ASSUME_NONNULL_BEGIN CGFloat timestampLabelWidth = [self.timestampLabel sizeThatFits:CGSizeZero].width; result.width = timestampLabelWidth; - if (viewItem.interaction.interactionType == OWSInteractionType_OutgoingMessage) { - if (![self isFailedOutgoingMessage:viewItem]) { - result.width += (self.maxImageWidth + self.hSpacing); - } - } if (viewItem.isExpiringMessage) { result.width += ([OWSMessageTimerView measureSize].width + self.hSpacing); diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageHeaderView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageHeaderView.m index 69809cb4f..98db100ea 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageHeaderView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageHeaderView.m @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN -const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 23; +const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 16; @interface OWSMessageHeaderView () @@ -55,6 +55,7 @@ const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 23; self.titleLabel = [UILabel new]; self.titleLabel.textAlignment = NSTextAlignmentCenter; self.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail; + self.titleLabel.textColor = [LKColors.text colorWithAlphaComponent:0.8]; self.subtitleLabel = [UILabel new]; // The subtitle may wrap to a second line. @@ -87,7 +88,8 @@ const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 23; CGFloat strokeThickness = [self strokeThicknessWithViewItem:viewItem]; self.strokeView.layer.cornerRadius = strokeThickness * 0.5f; self.strokeView.backgroundColor = [self strokeColorWithViewItem:viewItem]; - + self.strokeView.hidden = viewItem.unreadIndicator == nil; + self.subtitleLabel.hidden = self.subtitleLabel.text.length < 1; [NSLayoutConstraint deactivateConstraints:self.layoutConstraints]; @@ -105,9 +107,9 @@ const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 23; OWSAssertDebug(viewItem); if (viewItem.unreadIndicator) { - return 4.f; - } else { return 1.f; + } else { + return 0.f; } } @@ -127,18 +129,18 @@ const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 23; OWSAssertDebug(viewItem); NSDate *date = viewItem.interaction.receivedAtDate; - NSString *dateString = [DateUtil formatDateForConversationDateBreaks:date].localizedUppercaseString; + NSString *dateString = [DateUtil formatDateForConversationDateBreaks:date]; // Update cell to reflect changes in dynamic text. if (viewItem.unreadIndicator) { - self.titleLabel.font = UIFont.ows_dynamicTypeCaption1Font.ows_mediumWeight; + self.titleLabel.font = [UIFont boldSystemFontOfSize:LKValues.verySmallFontSize]; NSString *title = NSLocalizedString( @"MESSAGES_VIEW_UNREAD_INDICATOR", @"Indicator that separates read from unread messages."); if (viewItem.shouldShowDate) { title = [[dateString rtlSafeAppend:@" \u00B7 "] rtlSafeAppend:title]; } - self.titleLabel.text = title.localizedUppercaseString; + self.titleLabel.text = title; if (!viewItem.unreadIndicator.hasMoreUnseenMessages) { self.subtitleLabel.text = nil; @@ -152,7 +154,7 @@ const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 23; @"changes.")); } } else { - self.titleLabel.font = UIFont.ows_dynamicTypeCaption1Font; + self.titleLabel.font = [UIFont boldSystemFontOfSize:LKValues.verySmallFontSize]; self.titleLabel.text = dateString; self.subtitleLabel.text = nil; } @@ -172,13 +174,17 @@ const CGFloat OWSMessageHeaderViewDateHeaderVMargin = 23; CGFloat strokeThickness = [self strokeThicknessWithViewItem:viewItem]; result.height += strokeThickness; + if (strokeThickness != 0) { + result.height += self.stackView.spacing; + } + CGFloat maxTextWidth = conversationStyle.headerViewContentWidth; CGSize titleSize = [self.titleLabel sizeThatFits:CGSizeMake(maxTextWidth, CGFLOAT_MAX)]; - result.height += titleSize.height + self.stackView.spacing; + result.height += titleSize.height; if (self.subtitleLabel.text.length > 0) { CGSize subtitleSize = [self.subtitleLabel sizeThatFits:CGSizeMake(maxTextWidth, CGFLOAT_MAX)]; - result.height += subtitleSize.height + self.stackView.spacing; + result.height += self.stackView.spacing + subtitleSize.height; } result.height += OWSMessageHeaderViewDateHeaderVMargin; diff --git a/SignalMessaging/utils/ConversationStyle.swift b/SignalMessaging/utils/ConversationStyle.swift index c8c39effa..75f92dbb7 100644 --- a/SignalMessaging/utils/ConversationStyle.swift +++ b/SignalMessaging/utils/ConversationStyle.swift @@ -18,14 +18,14 @@ public class ConversationStyle: NSObject { } } - @objc public let contentMarginTop: CGFloat = 24 - @objc public let contentMarginBottom: CGFloat = 24 + @objc public let contentMarginTop: CGFloat = 24 // Values.largeSpacing + @objc public let contentMarginBottom: CGFloat = 24 // Values.largeSpacing @objc public var gutterLeading: CGFloat = 0 @objc public var gutterTrailing: CGFloat = 0 - @objc public var headerGutterLeading: CGFloat = 28 - @objc public var headerGutterTrailing: CGFloat = 28 + @objc public var headerGutterLeading: CGFloat = 35 // Values.veryLargeSpacing + @objc public var headerGutterTrailing: CGFloat = 35 // Values.veryLargeSpacing // These are the gutters used by "full width" views // like "contact offer" and "info message". @@ -91,7 +91,7 @@ public class ConversationStyle: NSObject { @objc public func updateProperties() { if thread.isGroupThread() { - gutterLeading = 52 + gutterLeading = 16 + 35 + 24 // Values.mediumSpacing + Values.smallProfilePictureSize + Values.largeSpacing gutterTrailing = 16 } else { gutterLeading = 16 @@ -99,15 +99,15 @@ public class ConversationStyle: NSObject { } fullWidthGutterLeading = 16 fullWidthGutterTrailing = 16 - headerGutterLeading = 28 - headerGutterTrailing = 28 + headerGutterLeading = 16 + headerGutterTrailing = 16 errorGutterTrailing = 16 maxMessageWidth = floor(contentWidth - 32) - let messageTextFont = UIFont.ows_dynamicTypeBody + let messageTextFont = UIFont.systemFont(ofSize: 13) // Values.smallFontSize - let baseFontOffset: CGFloat = 11 + let baseFontOffset: CGFloat = 16 // Don't include the distance from the "cap height" to the top of the UILabel // in the top margin. @@ -117,12 +117,7 @@ public class ConversationStyle: NSObject { // negative value. textInsetBottom = max(0, round(baseFontOffset - abs(messageTextFont.descender))) - if _isDebugAssertConfiguration(), UIFont.ows_dynamicTypeBody.pointSize == 17 { -// assert(textInsetTop == 7) -// assert(textInsetBottom == 7) - } - - textInsetHorizontal = 12 + textInsetHorizontal = 16 lastTextLineAxis = CGFloat(round(baseFontOffset + messageTextFont.capHeight * 0.5)) @@ -142,17 +137,17 @@ public class ConversationStyle: NSObject { @objc private static var defaultBubbleColorIncoming: UIColor { - return UIColor.lokiDarkGray() + return UIColor(rgbHex: 0x222325) // Colors.receivedMessageBackgroundColor } @objc - public let bubbleColorOutgoingFailed = UIColor.lokiGreen() + public let bubbleColorOutgoingFailed = UIColor(rgbHex: 0x3F4146) // Colors.sentMessageBackgroundColor @objc - public let bubbleColorOutgoingSending = UIColor.lokiGreen() + public let bubbleColorOutgoingSending = UIColor(rgbHex: 0x3F4146) // Colors.sentMessageBackgroundColor @objc - public let bubbleColorOutgoingSent = UIColor.lokiGreen() + public let bubbleColorOutgoingSent = UIColor(rgbHex: 0x3F4146) // Colors.sentMessageBackgroundColor @objc public let dateBreakTextColor = UIColor.ows_gray60 @@ -187,12 +182,12 @@ public class ConversationStyle: NSObject { @objc public static var bubbleTextColorIncoming: UIColor { - return Theme.isDarkThemeEnabled ? UIColor.ows_gray05 : UIColor.ows_gray90 + return UIColor(rgbHex: 0xFFFFFF) // Colors.text } @objc public static var bubbleTextColorOutgoing: UIColor { - return Theme.isDarkThemeEnabled ? UIColor.ows_gray05 : UIColor.ows_white + return UIColor(rgbHex: 0xFFFFFF) // Colors.text } @objc @@ -218,7 +213,7 @@ public class ConversationStyle: NSObject { @objc public func bubbleSecondaryTextColor(isIncoming: Bool) -> UIColor { - return bubbleTextColor(isIncoming: isIncoming).withAlphaComponent(0.7) + return bubbleTextColor(isIncoming: isIncoming).withAlphaComponent(0.6) // Values.unimportantElementOpacity } @objc