diff --git a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m index be1b815f2..967cd44be 100644 --- a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m +++ b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m @@ -1118,17 +1118,25 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) { - (void)setNavigationTitle { - NSString *navTitle = self.thread.name; - if (self.isGroupConversation && [navTitle length] == 0) { - navTitle = NSLocalizedString(@"NEW_GROUP_DEFAULT_TITLE", @""); + NSAttributedString *name; + if (self.thread.isGroupThread) { + if (self.thread.name.length == 0) { + name = [[NSAttributedString alloc] initWithString:NSLocalizedString(@"NEW_GROUP_DEFAULT_TITLE", @"")]; + } else { + name = [[NSAttributedString alloc] initWithString:self.thread.name]; + } + } else { + name = [self.contactsManager attributedStringForConversationTitleWithPhoneIdentifier:self.thread.contactIdentifier + primaryFont:self.navigationBarTitleLabel.font + secondaryFont:[UIFont ows_footnoteFont]]; } self.title = nil; - if ([navTitle isEqualToString:self.navigationBarTitleLabel.text]) { + if ([name isEqual:self.navigationBarTitleLabel.attributedText]) { return; } - self.navigationBarTitleLabel.text = navTitle; + self.navigationBarTitleLabel.attributedText = name; // Changing the title requires relayout of the nav bar contents. OWSDisappearingMessagesConfiguration *configuration = diff --git a/Signal/src/ViewControllers/InboxTableViewCell.m b/Signal/src/ViewControllers/InboxTableViewCell.m index 5f194feca..647502a26 100644 --- a/Signal/src/ViewControllers/InboxTableViewCell.m +++ b/Signal/src/ViewControllers/InboxTableViewCell.m @@ -76,6 +76,7 @@ const NSUInteger kAvatarViewDiameter = 52; self.nameLabel = [UILabel new]; self.nameLabel.lineBreakMode = NSLineBreakByTruncatingTail; + self.nameLabel.font = [UIFont ows_boldFontWithSize:14.0f]; [self.contentView addSubview:self.nameLabel]; [self.nameLabel autoPinLeadingToTrailingOfView:self.avatarView margin:13.f]; [self.nameLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:self.avatarView]; @@ -162,11 +163,7 @@ const NSUInteger kAvatarViewDiameter = 52; NSString *contactIdentifier = thread.contactIdentifier; isBlocked = [blockedPhoneNumberSet containsObject:contactIdentifier]; } - - NSString *name = thread.name; - if (name.length == 0 && [thread isKindOfClass:[TSGroupThread class]]) { - name = NSLocalizedString(@"NEW_GROUP_DEFAULT_TITLE", @""); - } + self.threadId = thread.uniqueId; NSMutableAttributedString *snippetText = [NSMutableAttributedString new]; if (isBlocked) { @@ -206,18 +203,28 @@ const NSUInteger kAvatarViewDiameter = 52; NSAttributedString *attributedDate = [self dateAttributedString:thread.lastMessageDate]; NSUInteger unreadCount = [[TSMessagesManager sharedManager] unreadMessagesInThread:thread]; - self.nameLabel.text = name; + NSAttributedString *name; + if (thread.isGroupThread) { + if (thread.name.length == 0) { + name = [[NSAttributedString alloc] initWithString:NSLocalizedString(@"NEW_GROUP_DEFAULT_TITLE", @"")]; + } else { + name = [[NSAttributedString alloc] initWithString:thread.name]; + } + } else { + name = [contactsManager attributedStringForConversationTitleWithPhoneIdentifier:thread.contactIdentifier + primaryFont:self.nameLabel.font + secondaryFont:[UIFont ows_footnoteFont]]; + } + + self.nameLabel.attributedText = name; self.snippetLabel.attributedText = snippetText; self.timeLabel.attributedText = attributedDate; self.avatarView.image = nil; self.separatorInset = UIEdgeInsetsMake(0, self.avatarSize * 1.5f, 0, 0); - if (thread.hasUnreadMessages) { - [self updateCellForUnreadMessage]; - } else { - [self updateCellForReadMessage]; - } + _timeLabel.textColor = thread.hasUnreadMessages ? [UIColor ows_materialBlueColor] : [UIColor ows_darkGrayColor]; + if (unreadCount > 0) { self.unreadBadge.hidden = NO; self.unreadLabel.hidden = NO; @@ -231,18 +238,6 @@ const NSUInteger kAvatarViewDiameter = 52; [OWSAvatarBuilder buildImageForThread:thread diameter:kAvatarViewDiameter contactsManager:contactsManager]; } -- (void)updateCellForUnreadMessage { - _nameLabel.font = [UIFont ows_boldFontWithSize:14.0f]; - _nameLabel.textColor = [UIColor ows_blackColor]; - _timeLabel.textColor = [UIColor ows_materialBlueColor]; -} - -- (void)updateCellForReadMessage { - _nameLabel.font = [UIFont ows_boldFontWithSize:14.0f]; - _nameLabel.textColor = [UIColor ows_blackColor]; - _timeLabel.textColor = [UIColor ows_darkGrayColor]; -} - #pragma mark - Date formatting - (NSAttributedString *)dateAttributedString:(NSDate *)date { diff --git a/Signal/src/contact/OWSContactsManager.h b/Signal/src/contact/OWSContactsManager.h index 4d5e4848e..e3d4fa464 100644 --- a/Signal/src/contact/OWSContactsManager.h +++ b/Signal/src/contact/OWSContactsManager.h @@ -59,7 +59,9 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification; - (NSAttributedString *)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount font:(UIFont *_Nonnull)font; - (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font; - (NSAttributedString *)attributedStringForMessageFooterWithPhoneIdentifier:(NSString *)recipientId; - +- (NSAttributedString *)attributedStringForConversationTitleWithPhoneIdentifier:(NSString *)recipientId + primaryFont:(UIFont *)primaryFont + secondaryFont:(UIFont *)secondaryFont; @end NS_ASSUME_NONNULL_END diff --git a/Signal/src/contact/OWSContactsManager.m b/Signal/src/contact/OWSContactsManager.m index 49ebc5ae0..b9099fd59 100644 --- a/Signal/src/contact/OWSContactsManager.m +++ b/Signal/src/contact/OWSContactsManager.m @@ -550,6 +550,38 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account return [[NSAttributedString alloc] initWithString:recipientId]; } +- (NSAttributedString *)attributedStringForConversationTitleWithPhoneIdentifier:(NSString *)recipientId + primaryFont:(UIFont *)primaryFont + secondaryFont:(UIFont *)secondaryFont +{ + // Prefer a saved name from system contacts, if available + NSString *_Nullable savedContactName = [self cachedDisplayNameForRecipientId:recipientId]; + if (savedContactName.length > 0) { + return [[NSAttributedString alloc] initWithString:savedContactName]; + } + + NSString *_Nullable profileName = [self.profileManager profileNameForRecipientId:recipientId]; + if (profileName.length > 0) { + NSString *numberAndProfileNameFormat = NSLocalizedString(@"PROFILE_NAME_AND_PHONE_NUMBER_LABEL_FORMAT", + @"Label text combining the phone number and profile name separated by a simple demarcation character. " + @"Phone number should be most prominent. '%1$@' is replaced with {{phone number}} and '%2$@' is replaced " + @"with {{profile name}}"); + + NSString *numberAndProfileName = + [NSString stringWithFormat:numberAndProfileNameFormat, recipientId, profileName]; + + NSRange recipientIdRange = [numberAndProfileName rangeOfString:recipientId]; + NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:numberAndProfileName + attributes:@{ NSFontAttributeName: secondaryFont }]; + [attributedString addAttribute:NSFontAttributeName value:primaryFont range:recipientIdRange]; + + return [attributedString copy]; + } + + // else fall back to recipient id + return [[NSAttributedString alloc] initWithString:recipientId]; +} + - (nullable SignalAccount *)signalAccountForRecipientId:(NSString *)recipientId { OWSAssert(recipientId.length > 0);