From 93700f1044d2bab495378230ef8a6de44673286a Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Sun, 30 Apr 2017 10:34:28 -0400 Subject: [PATCH] Extract labels for phone numbers. // FREEBIE --- .../AddToBlockListViewController.m | 3 +- .../src/ViewControllers/ContactsViewHelper.m | 68 ++++++++++++++++++- .../src/ViewControllers/InboxTableViewCell.h | 7 -- .../src/ViewControllers/InboxTableViewCell.m | 45 ------------ .../ViewControllers/NewGroupViewController.m | 6 +- .../SelectRecipientViewController.m | 3 +- .../SelectThreadViewController.m | 3 +- .../ShowGroupMembersViewController.m | 3 +- .../UpdateGroupViewController.m | 3 +- Signal/src/contact/OWSContactsManager.h | 2 + Signal/src/contact/OWSContactsManager.m | 37 +++++++++- Signal/src/views/ContactTableViewCell.h | 5 ++ Signal/src/views/ContactTableViewCell.m | 11 +++ Signal/translations/bin/auto-genstrings | 9 --- .../translations/en.lproj/Localizable.strings | 27 ++++++++ 15 files changed, 152 insertions(+), 80 deletions(-) diff --git a/Signal/src/ViewControllers/AddToBlockListViewController.m b/Signal/src/ViewControllers/AddToBlockListViewController.m index 16b1f10e4..301d92d72 100644 --- a/Signal/src/ViewControllers/AddToBlockListViewController.m +++ b/Signal/src/ViewControllers/AddToBlockListViewController.m @@ -67,8 +67,7 @@ NS_ASSUME_NONNULL_BEGIN __weak AddToBlockListViewController *weakSelf = self; ContactsViewHelper *helper = self.contactsViewHelper; if ([helper isRecipientIdBlocked:contactAccount.recipientId]) { - // TODO: Use the account label. - NSString *displayName = [helper.contactsManager displayNameForContact:contactAccount.contact]; + NSString *displayName = [helper.contactsManager displayNameForContactAccount:contactAccount]; UIAlertController *controller = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_ALREADY_BLOCKED_ALERT_TITLE", @"A title of the alert if user tries to block a " diff --git a/Signal/src/ViewControllers/ContactsViewHelper.m b/Signal/src/ViewControllers/ContactsViewHelper.m index 497004d24..91c0d8c27 100644 --- a/Signal/src/ViewControllers/ContactsViewHelper.m +++ b/Signal/src/ViewControllers/ContactsViewHelper.m @@ -118,8 +118,7 @@ NS_ASSUME_NONNULL_BEGIN contactAccount.contact = contact; contactAccount.recipientId = recipientId; contactAccount.isMultipleAccountContact = YES; - // TODO: Store the phone number's "label" if possible. - contactAccount.multipleAccountLabel = recipientId; + contactAccount.multipleAccountLabel = [self accountLabelForContact:contact recipientId:recipientId]; [allRecipientContactAccounts addObject:contactAccount]; contactAccountMap[recipientId] = contactAccount; } @@ -131,6 +130,71 @@ NS_ASSUME_NONNULL_BEGIN [self.delegate contactsViewHelperDidUpdateContacts]; } +- (NSString *)accountLabelForContact:(Contact *)contact recipientId:(NSString *)recipientId +{ + OWSAssert(contact); + OWSAssert(recipientId.length > 0); + OWSAssert([contact.textSecureIdentifiers containsObject:recipientId]); + + if (contact.textSecureIdentifiers.count <= 1) { + return nil; + } + + // 1. Find the phone number type of this account. + OWSPhoneNumberType phoneNumberType = [contact phoneNumberTypeForPhoneNumber:recipientId]; + + NSString *phoneNumberLabel; + switch (phoneNumberType) { + case OWSPhoneNumberTypeMobile: + phoneNumberLabel = NSLocalizedString(@"PHONE_NUMBER_TYPE_MOBILE", @"Label for 'Mobile' phone numbers."); + break; + case OWSPhoneNumberTypeIPhone: + phoneNumberLabel = NSLocalizedString(@"PHONE_NUMBER_TYPE_IPHONE", @"Label for 'IPhone' phone numbers."); + break; + case OWSPhoneNumberTypeMain: + phoneNumberLabel = NSLocalizedString(@"PHONE_NUMBER_TYPE_MAIN", @"Label for 'Main' phone numbers."); + break; + case OWSPhoneNumberTypeHomeFAX: + phoneNumberLabel = NSLocalizedString(@"PHONE_NUMBER_TYPE_HOME_FAX", @"Label for 'HomeFAX' phone numbers."); + break; + case OWSPhoneNumberTypeWorkFAX: + phoneNumberLabel = NSLocalizedString(@"PHONE_NUMBER_TYPE_WORK_FAX", @"Label for 'Work FAX' phone numbers."); + break; + case OWSPhoneNumberTypeOtherFAX: + phoneNumberLabel + = NSLocalizedString(@"PHONE_NUMBER_TYPE_OTHER_FAX", @"Label for 'Other FAX' phone numbers."); + break; + case OWSPhoneNumberTypePager: + phoneNumberLabel = NSLocalizedString(@"PHONE_NUMBER_TYPE_PAGER", @"Label for 'Pager' phone numbers."); + break; + case OWSPhoneNumberTypeUnknown: + phoneNumberLabel = NSLocalizedString(@"PHONE_NUMBER_TYPE_UNKNOWN", @"Label for 'Unknown' phone numbers."); + break; + } + + // 2. Find all phone numbers for this contact of the same type. + NSMutableArray *phoneNumbersOfTheSameType = [NSMutableArray new]; + for (NSString *textSecureIdentifier in contact.textSecureIdentifiers) { + if (phoneNumberType == [contact phoneNumberTypeForPhoneNumber:textSecureIdentifier]) { + [phoneNumbersOfTheSameType addObject:textSecureIdentifier]; + } + } + + OWSAssert([phoneNumbersOfTheSameType containsObject:recipientId]); + if (phoneNumbersOfTheSameType.count > 0) { + NSUInteger index = + [[phoneNumbersOfTheSameType sortedArrayUsingSelector:@selector(compare:)] indexOfObject:recipientId]; + phoneNumberLabel = + [NSString stringWithFormat:NSLocalizedString(@"PHONE_NUMBER_TYPE_AND_INDEX_FORMAT", + @"Format for phone number label with an index. Embeds {{Phone number label " + @"(e.g. 'home')}} and {{index, e.g. 2}}."), + phoneNumberLabel, + (int)index]; + } + + return phoneNumberLabel; +} + - (BOOL)isContactHidden:(Contact *)contact { OWSAssert([NSThread isMainThread]); diff --git a/Signal/src/ViewControllers/InboxTableViewCell.h b/Signal/src/ViewControllers/InboxTableViewCell.h index 155632b1e..2e57a8767 100644 --- a/Signal/src/ViewControllers/InboxTableViewCell.h +++ b/Signal/src/ViewControllers/InboxTableViewCell.h @@ -31,13 +31,6 @@ typedef enum : NSUInteger { kArchiveState = 0, kInboxState = 1 } CellState; contactsManager:(OWSContactsManager *)contactsManager blockedPhoneNumberSet:(NSSet *)blockedPhoneNumberSet; -// This method is used to present _possible_ threads - threads -// that will be created if this cell is selected. -- (void)configureWithContact:(Contact *)contact - recipientId:(NSString *)recipientId - contactsManager:(OWSContactsManager *)contactsManager - isBlocked:(BOOL)isBlocked; - - (void)animateDisappear; @end diff --git a/Signal/src/ViewControllers/InboxTableViewCell.m b/Signal/src/ViewControllers/InboxTableViewCell.m index 13ec2f167..631afec80 100644 --- a/Signal/src/ViewControllers/InboxTableViewCell.m +++ b/Signal/src/ViewControllers/InboxTableViewCell.m @@ -138,51 +138,6 @@ NS_ASSUME_NONNULL_BEGIN }); } -- (void)configureWithContact:(Contact *)contact - recipientId:(NSString *)recipientId - contactsManager:(OWSContactsManager *)contactsManager - isBlocked:(BOOL)isBlocked -{ - OWSAssert([NSThread isMainThread]); - OWSAssert(contact); - OWSAssert(recipientId.length > 0); - OWSAssert(contactsManager); - - NSString *name = contact.fullName; - self.threadId = recipientId; - NSMutableAttributedString *snippetText = [NSMutableAttributedString new]; - if (isBlocked) { - // If thread is blocked, don't show a snippet or mute status. - [snippetText - appendAttributedString:[[NSAttributedString alloc] - initWithString:NSLocalizedString(@"HOME_VIEW_BLOCKED_CONTACT_CONVERSATION", - @"A label for conversations with blocked users.") - attributes:@{ - NSFontAttributeName : [UIFont ows_mediumFontWithSize:12], - NSForegroundColorAttributeName : [UIColor ows_blackColor], - }]]; - } - - self.nameLabel.text = name; - self.snippetLabel.attributedText = snippetText; - self.contactPictureView.image = [UIImage imageNamed:@"empty-group-avatar"]; - [UIUtil applyRoundedBorderToImageView:_contactPictureView]; - - self.separatorInset = UIEdgeInsetsMake(0, _contactPictureView.frame.size.width * 1.5f, 0, 0); - - [self updateCellForUnreadMessage]; - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - UIImage *avatar = [[[OWSContactAvatarBuilder alloc] initWithContactId:recipientId - name:contact.fullName - contactsManager:contactsManager] build]; - dispatch_async(dispatch_get_main_queue(), ^{ - if ([self.threadId isEqualToString:recipientId]) { - self.contactPictureView.image = avatar; - } - }); - }); -} - (void)updateCellForUnreadMessage { _nameLabel.font = [UIFont ows_boldFontWithSize:14.0f]; diff --git a/Signal/src/ViewControllers/NewGroupViewController.m b/Signal/src/ViewControllers/NewGroupViewController.m index 4052b8666..3867e8971 100644 --- a/Signal/src/ViewControllers/NewGroupViewController.m +++ b/Signal/src/ViewControllers/NewGroupViewController.m @@ -227,8 +227,7 @@ NS_ASSUME_NONNULL_BEGIN } if (contactAccount) { - // TODO: Use the account label. - [cell configureWithContact:contactAccount.contact contactsManager:helper.contactsManager]; + [cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; } else { [cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager]; } @@ -296,8 +295,7 @@ NS_ASSUME_NONNULL_BEGIN OWSAssert(cell.accessoryMessage == nil); } - // TODO: Use the account label. - [cell configureWithContact:contactAccount.contact contactsManager:helper.contactsManager]; + [cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; return cell; } diff --git a/Signal/src/ViewControllers/SelectRecipientViewController.m b/Signal/src/ViewControllers/SelectRecipientViewController.m index d91286252..40d565729 100644 --- a/Signal/src/ViewControllers/SelectRecipientViewController.m +++ b/Signal/src/ViewControllers/SelectRecipientViewController.m @@ -488,8 +488,7 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien } else { OWSAssert(cell.accessoryMessage == nil); } - // TODO: Use the account label. - [cell configureWithContact:contactAccount.contact contactsManager:helper.contactsManager]; + [cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; return cell; } customRowHeight:[ContactTableViewCell rowHeight] diff --git a/Signal/src/ViewControllers/SelectThreadViewController.m b/Signal/src/ViewControllers/SelectThreadViewController.m index 0c243a434..1f970a807 100644 --- a/Signal/src/ViewControllers/SelectThreadViewController.m +++ b/Signal/src/ViewControllers/SelectThreadViewController.m @@ -169,8 +169,7 @@ NS_ASSUME_NONNULL_BEGIN } else { OWSAssert(cell.accessoryMessage == nil); } - // TODO: Use contact account - [cell configureWithContact:contactAccount.contact contactsManager:helper.contactsManager]; + [cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; return cell; } customRowHeight:[ContactTableViewCell rowHeight] diff --git a/Signal/src/ViewControllers/ShowGroupMembersViewController.m b/Signal/src/ViewControllers/ShowGroupMembersViewController.m index d3d7288aa..4cfe563e9 100644 --- a/Signal/src/ViewControllers/ShowGroupMembersViewController.m +++ b/Signal/src/ViewControllers/ShowGroupMembersViewController.m @@ -116,8 +116,7 @@ NS_ASSUME_NONNULL_BEGIN } if (contactAccount) { - // TODO: Use the account label. - [cell configureWithContact:contactAccount.contact contactsManager:helper.contactsManager]; + [cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; } else { [cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager]; } diff --git a/Signal/src/ViewControllers/UpdateGroupViewController.m b/Signal/src/ViewControllers/UpdateGroupViewController.m index d9b11b2d7..29ccff350 100644 --- a/Signal/src/ViewControllers/UpdateGroupViewController.m +++ b/Signal/src/ViewControllers/UpdateGroupViewController.m @@ -265,8 +265,7 @@ NS_ASSUME_NONNULL_BEGIN } if (contactAccount) { - // TODO: Use the account label. - [cell configureWithContact:contactAccount.contact contactsManager:helper.contactsManager]; + [cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; } else { [cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager]; } diff --git a/Signal/src/contact/OWSContactsManager.h b/Signal/src/contact/OWSContactsManager.h index 6a721869f..f24c3dfcf 100644 --- a/Signal/src/contact/OWSContactsManager.h +++ b/Signal/src/contact/OWSContactsManager.h @@ -42,6 +42,8 @@ extern NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification; - (NSString *)displayNameForContact:(Contact *)contact; - (NSString *_Nonnull)displayNameForContactAccount:(ContactAccount *)contactAccount; - (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier; +- (NSAttributedString *_Nonnull)formattedDisplayNameForContactAccount:(ContactAccount *)contactAccount + font:(UIFont *_Nonnull)font; - (NSAttributedString *)formattedFullNameForContact:(Contact *)contact font:(UIFont *)font; - (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font; diff --git a/Signal/src/contact/OWSContactsManager.m b/Signal/src/contact/OWSContactsManager.m index 28d065e13..19dfa27f9 100644 --- a/Signal/src/contact/OWSContactsManager.m +++ b/Signal/src/contact/OWSContactsManager.m @@ -531,9 +531,40 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in { OWSAssert(contactAccount); - // TODO: We need to use the contact info label. - return (contactAccount.contact ? [self displayNameForContact:contactAccount.contact] - : [self displayNameForPhoneIdentifier:contactAccount.recipientId]); + NSString *baseName = (contactAccount.contact ? [self displayNameForContact:contactAccount.contact] + : [self displayNameForPhoneIdentifier:contactAccount.recipientId]); + OWSAssert(contactAccount.isMultipleAccountContact == (contactAccount.multipleAccountLabel != nil)); + if (contactAccount.multipleAccountLabel) { + return [NSString stringWithFormat:@"%@ (%@)", baseName, contactAccount.multipleAccountLabel]; + } else { + return baseName; + } +} + +- (NSAttributedString *_Nonnull)formattedDisplayNameForContactAccount:(ContactAccount *)contactAccount + font:(UIFont *_Nonnull)font +{ + OWSAssert(contactAccount); + OWSAssert(font); + + NSAttributedString *baseName = [self formattedFullNameForContact:contactAccount.contact font:font]; + OWSAssert(contactAccount.isMultipleAccountContact == (contactAccount.multipleAccountLabel != nil)); + if (contactAccount.multipleAccountLabel) { + NSMutableAttributedString *result = [NSMutableAttributedString new]; + [result appendAttributedString:baseName]; + [result appendAttributedString:[[NSAttributedString alloc] initWithString:@" (" + attributes:@{ + NSFontAttributeName : font, + }]]; + [result appendAttributedString:[[NSAttributedString alloc] initWithString:contactAccount.multipleAccountLabel]]; + [result appendAttributedString:[[NSAttributedString alloc] initWithString:@")" + attributes:@{ + NSFontAttributeName : font, + }]]; + return result; + } else { + return baseName; + } } - (NSAttributedString *_Nonnull)formattedFullNameForContact:(Contact *)contact font:(UIFont *_Nonnull)font diff --git a/Signal/src/views/ContactTableViewCell.h b/Signal/src/views/ContactTableViewCell.h index 445e92d51..5f260679a 100644 --- a/Signal/src/views/ContactTableViewCell.h +++ b/Signal/src/views/ContactTableViewCell.h @@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN extern NSString *const kContactsTable_CellReuseIdentifier; @class OWSContactsManager; +@class ContactAccount; @class TSThread; @interface ContactTableViewCell : UITableViewCell @@ -26,8 +27,12 @@ extern NSString *const kContactsTable_CellReuseIdentifier; + (CGFloat)rowHeight; +// TODO: Remove this method once "new 1:1 conversation" view is converted to use ContactAccounts. - (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager; +- (void)configureWithContactAccount:(ContactAccount *)contactAccount + contactsManager:(OWSContactsManager *)contactsManager; + - (void)configureWithRecipientId:(NSString *)recipientId contactsManager:(OWSContactsManager *)contactsManager; - (void)configureWithThread:(TSThread *)thread contactsManager:(OWSContactsManager *)contactsManager; diff --git a/Signal/src/views/ContactTableViewCell.m b/Signal/src/views/ContactTableViewCell.m index cc058f40d..6cd18cdc2 100644 --- a/Signal/src/views/ContactTableViewCell.m +++ b/Signal/src/views/ContactTableViewCell.m @@ -3,6 +3,7 @@ // #import "ContactTableViewCell.h" +#import "ContactAccount.h" #import "Environment.h" #import "OWSContactAvatarBuilder.h" #import "OWSContactsManager.h" @@ -89,6 +90,16 @@ NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseI contactsManager:contactsManager]; } +- (void)configureWithContactAccount:(ContactAccount *)contactAccount + contactsManager:(OWSContactsManager *)contactsManager +{ + [self configureWithRecipientId:contactAccount.recipientId + avatarName:contactAccount.contact.fullName + displayName:[contactsManager formattedDisplayNameForContactAccount:contactAccount + font:self.nameLabel.font] + contactsManager:contactsManager]; +} + - (void)configureWithRecipientId:(NSString *)recipientId contactsManager:(OWSContactsManager *)contactsManager { [self diff --git a/Signal/translations/bin/auto-genstrings b/Signal/translations/bin/auto-genstrings index 83241223e..6d0b6dbcc 100755 --- a/Signal/translations/bin/auto-genstrings +++ b/Signal/translations/bin/auto-genstrings @@ -4,15 +4,6 @@ set -e SSK_DIR="../SignalServiceKit/src" -pushd $SSK_DIR -CURRENT_SSK_BRANCH=$(git status|awk 'NR==1{print $3}') -if [ $CURRENT_SSK_BRANCH != "master" ] -then - echo "[!] Error - SSK must be on master to be sure we're generating up-to-date strings" - exit 1 -fi -popd - TARGETS="Signal/src ${SSK_DIR}" TMP="$(mktemp -d)" STRINGFILE="Signal/translations/en.lproj/Localizable.strings" diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index b30f2d2b8..d0fcbaf70 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -838,6 +838,33 @@ /* The title of the 'oversize text message' view. */ "OVERSIZE_TEXT_MESSAGE_VIEW_TITLE" = "Message"; +/* Format for phone number label with an index. Embeds {{Phone number label (e.g. 'home')}} and {{index, e.g. 2}}. */ +"PHONE_NUMBER_TYPE_AND_INDEX_FORMAT" = "%@ (%d)"; + +/* Label for 'HomeFAX' phone numbers. */ +"PHONE_NUMBER_TYPE_HOME_FAX" = "Home Fax"; + +/* Label for 'IPhone' phone numbers. */ +"PHONE_NUMBER_TYPE_IPHONE" = "iPhone"; + +/* Label for 'Main' phone numbers. */ +"PHONE_NUMBER_TYPE_MAIN" = "Main"; + +/* Label for 'Mobile' phone numbers. */ +"PHONE_NUMBER_TYPE_MOBILE" = "Mobile"; + +/* Label for 'Other FAX' phone numbers. */ +"PHONE_NUMBER_TYPE_OTHER_FAX" = "Other Fax"; + +/* Label for 'Pager' phone numbers. */ +"PHONE_NUMBER_TYPE_PAGER" = "Pager"; + +/* Label for 'Unknown' phone numbers. */ +"PHONE_NUMBER_TYPE_UNKNOWN" = "Unknown"; + +/* Label for 'Work FAX' phone numbers. */ +"PHONE_NUMBER_TYPE_WORK_FAX" = "Work Fax"; + /* Alert body when verifying with {{contact name}} */ "PRIVACY_VERIFICATION_FAILED_I_HAVE_WRONG_KEY_FOR_THEM" = "This doesn't look like your safety number with %@. Are you verifying the correct contact?";