From 3048a0146f2f28ad41081136d703b257457ae19a Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 15 Mar 2017 17:56:26 -0300 Subject: [PATCH 1/3] Fix non-contact lookup for non-US users. // FREEBIE --- .../MessageComposeTableViewController.m | 159 ++++++++++++------ 1 file changed, 107 insertions(+), 52 deletions(-) diff --git a/Signal/src/view controllers/MessageComposeTableViewController.m b/Signal/src/view controllers/MessageComposeTableViewController.m index 89e5f0e77..208c56137 100644 --- a/Signal/src/view controllers/MessageComposeTableViewController.m +++ b/Signal/src/view controllers/MessageComposeTableViewController.m @@ -22,8 +22,6 @@ NS_ASSUME_NONNULL_BEGIN MFMessageComposeViewControllerDelegate> @property (nonatomic) IBOutlet UITableViewCell *inviteCell; -@property (nonatomic) UITableViewCell *conversationForNonContactCell; -@property (nonatomic) UITableViewCell *inviteViaSMSCell; @property (nonatomic) IBOutlet OWSNoSignalContactsView *noSignalContactsView; @property (nonatomic) UISearchController *searchController; @@ -31,14 +29,16 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) UIBarButtonItem *addGroup; @property (nonatomic) UIView *loadingBackgroundView; -@property (nonatomic) NSString *currentSearchTerm; -@property (copy) NSArray *contacts; -@property (copy) NSArray *searchResults; +@property (nonatomic, copy) NSArray *contacts; +@property (nonatomic, copy) NSArray *searchResults; @property (nonatomic, readonly) OWSContactsManager *contactsManager; -// This property should be set IFF the current search text can -// be parsed as a phone number. If set, it contains a E164 value. -@property (nonatomic) NSString *searchPhoneNumber; +// A list of possible phone numbers parsed from the search text as +// E164 values. +@property (nonatomic) NSArray *searchPhoneNumbers; +// A list of possible phone numbers parsed from the search text +// that correspond to known accounts as E164 values. +@property (nonatomic) NSArray *searchPhoneNumberWithAccounts; // This dictionary is used to cache the set of phone numbers // which are known to correspond to Signal accounts. @property (nonatomic, nonnull, readonly) NSMutableSet *phoneNumberAccountSet; @@ -132,9 +132,6 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie self.searchController.searchBar.backgroundColor = [UIColor whiteColor]; self.inviteCell.textLabel.text = NSLocalizedString( @"INVITE_FRIENDS_CONTACT_TABLE_BUTTON", @"Text for button at the top of the contact picker"); - - self.conversationForNonContactCell = [UITableViewCell new]; - self.inviteViaSMSCell = [UITableViewCell new]; self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; [self createLoadingAndBackgroundViews]; @@ -275,8 +272,6 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie self.inviteCell.hidden = YES; - self.conversationForNonContactCell.hidden = YES; - self.inviteViaSMSCell.hidden = YES; self.searchController.searchBar.hidden = YES; self.tableView.backgroundView = self.noSignalContactsView; self.tableView.backgroundView.opaque = YES; @@ -288,8 +283,10 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie self.searchController.searchBar.hidden = NO; self.tableView.backgroundView = nil; self.inviteCell.hidden = NO; - self.conversationForNonContactCell.hidden = NO; - self.inviteViaSMSCell.hidden = NO; + } + + for (UITableViewCell *cell in self.tableView.visibleCells) { + cell.hidden = show; } } @@ -353,34 +350,47 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie OWSContactsSearcher *contactsSearcher = [[OWSContactsSearcher alloc] initWithContacts: self.contacts]; self.searchResults = [contactsSearcher filterWithString:searchText]; - NSString *formattedNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:searchText].toE164; + NSMutableArray *searchPhoneNumbers = [NSMutableArray new]; + for (PhoneNumber *phoneNumber in [PhoneNumber tryParsePhoneNumbersFromsUserSpecifiedText:searchText + clientPhoneNumber:[TSStorageManager localNumber]]) { + [searchPhoneNumbers addObject:phoneNumber.toE164]; + } // text to a non-signal number if we have no results and a valid phone # - if (self.searchResults.count == 0 && searchText.length > 8 && formattedNumber) { - self.currentSearchTerm = formattedNumber; - self.searchPhoneNumber = formattedNumber; + if (self.searchResults.count == 0 && searchText.length > 8 && searchPhoneNumbers.count > 0) { + self.searchPhoneNumbers = searchPhoneNumbers; // Kick off account lookup if necessary. - [self checkIsNonContactPhoneNumberSignalUser:formattedNumber]; + [self checkForAccountsForPhoneNumbers:searchPhoneNumbers]; } else { - _searchPhoneNumber = nil; + _searchPhoneNumbers = nil; } } -- (void)checkIsNonContactPhoneNumberSignalUser:(NSString *)phoneNumber +- (void)checkForAccountsForPhoneNumbers:(NSArray *)phoneNumbers { - if ([self.phoneNumberAccountSet containsObject:phoneNumber]) { + NSMutableArray *unknownPhoneNumbers = [NSMutableArray new]; + for (NSString *phoneNumber in phoneNumbers) { + if (![self.phoneNumberAccountSet containsObject:phoneNumber]) { + [unknownPhoneNumbers addObject:phoneNumber]; + } + } + if ([unknownPhoneNumbers count] < 1) { return; } __weak MessageComposeTableViewController *weakSelf = self; - [[ContactsUpdater sharedUpdater] lookupIdentifier:phoneNumber - success:^(SignalRecipient *recipient) { + [[ContactsUpdater sharedUpdater] lookupIdentifiers:unknownPhoneNumbers + success:^(NSArray *recipients) { MessageComposeTableViewController *strongSelf = weakSelf; if (!strongSelf) { return; } - if (![strongSelf.phoneNumberAccountSet containsObject:phoneNumber]) { + NSUInteger oldCount = strongSelf.phoneNumberAccountSet.count; + for (SignalRecipient *recipient in recipients) { + NSString *phoneNumber = recipient.uniqueId; [strongSelf.phoneNumberAccountSet addObject:phoneNumber]; - [strongSelf.tableView reloadData]; + } + if (oldCount != strongSelf.phoneNumberAccountSet.count) { + [strongSelf ensureSearchPhoneNumberWithAccounts]; } } failure:^(NSError *error) { @@ -388,24 +398,47 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie }]; } -- (void)setSearchPhoneNumber:(NSString *)searchPhoneNumber { - if ([_searchPhoneNumber isEqualToString:searchPhoneNumber]) { +- (void)setSearchPhoneNumbers:(NSArray *)searchPhoneNumbers { + if ([_searchPhoneNumbers isEqual:searchPhoneNumbers]) { return; } + + _searchPhoneNumbers = searchPhoneNumbers; + + [self ensureSearchPhoneNumberWithAccounts]; + + [self.tableView reloadData]; +} + +- (void)ensureSearchPhoneNumberWithAccounts { + NSMutableArray *searchPhoneNumberWithAccounts = [NSMutableArray new]; + for (NSString *phoneNumber in self.searchPhoneNumbers) { + if ([self.phoneNumberAccountSet containsObject:phoneNumber]) { + [searchPhoneNumberWithAccounts addObject:phoneNumber]; + } + } + self.searchPhoneNumberWithAccounts = searchPhoneNumberWithAccounts; +} - _searchPhoneNumber = searchPhoneNumber; +- (void)setSearchPhoneNumberWithAccounts:(NSArray *)searchPhoneNumberWithAccounts { + if ([_searchPhoneNumberWithAccounts isEqual:searchPhoneNumberWithAccounts]) { + return; + } + + _searchPhoneNumberWithAccounts = searchPhoneNumberWithAccounts; [self.tableView reloadData]; } #pragma mark - Send Normal Text to Unknown Contact -- (void)sendText { +- (void)sendTextToPhoneNumber:(NSString *)phoneNumber { + OWSAssert([phoneNumber length] > 0); NSString *confirmMessage = NSLocalizedString(@"SEND_SMS_CONFIRM_TITLE", @""); - if ([self.currentSearchTerm length] > 0) { - confirmMessage = NSLocalizedString(@"SEND_SMS_INVITE_TITLE", @""); - confirmMessage = [confirmMessage stringByAppendingString:self.currentSearchTerm]; - confirmMessage = [confirmMessage stringByAppendingString:NSLocalizedString(@"QUESTIONMARK_PUNCTUATION", @"")]; + if ([phoneNumber length] > 0) { + confirmMessage = [[NSLocalizedString(@"SEND_SMS_INVITE_TITLE", @"") + stringByAppendingString:phoneNumber] + stringByAppendingString:NSLocalizedString(@"QUESTIONMARK_PUNCTUATION", @"")]; } UIAlertController *alertController = @@ -429,8 +462,7 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init]; picker.messageComposeDelegate = self; - picker.recipients = - [self.currentSearchTerm length] > 0 ? [NSArray arrayWithObject:self.currentSearchTerm] : nil; + picker.recipients = @[phoneNumber,]; picker.body = [NSLocalizedString(@"SMS_INVITE_BODY", @"") stringByAppendingString: @" https://itunes.apple.com/us/app/signal-private-messenger/id874139669?mt=8"]; @@ -512,10 +544,10 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie BOOL showInviteViaSMS = NO; BOOL showInviteFlow = NO; - BOOL hasPhoneNumber = self.searchPhoneNumber.length > 0; - BOOL isKnownSignalUser = hasPhoneNumber && [self.phoneNumberAccountSet containsObject:self.searchPhoneNumber]; + BOOL hasPhoneNumber = self.searchPhoneNumbers.count > 0; + BOOL hasKnownSignalUser = self.searchPhoneNumberWithAccounts.count > 0; BOOL isInviteFlowSupported = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(9, 0); - if (hasPhoneNumber && isKnownSignalUser) { + if (hasKnownSignalUser) { showNonContactConversation = YES; } else if (hasPhoneNumber) { showInviteViaSMS = YES; @@ -524,9 +556,9 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie } if (section == MessageComposeTableViewControllerSectionInviteNonContactConversation) { - return showNonContactConversation ? 1 : 0; + return showNonContactConversation ? (NSInteger) self.searchPhoneNumberWithAccounts.count : 0; } else if (section == MessageComposeTableViewControllerSectionInviteViaSMS) { - return showInviteViaSMS ? 1 : 0; + return showInviteViaSMS ? (NSInteger) self.searchPhoneNumbers.count : 0; } else if (section == MessageComposeTableViewControllerSectionInviteFlow) { return showInviteFlow ? 1 : 0; } else { @@ -543,16 +575,29 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == MessageComposeTableViewControllerSectionInviteNonContactConversation) { - self.conversationForNonContactCell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(@"NEW_CONVERSATION_FOR_NON_CONTACT_FORMAT", + if (indexPath.row < 0 || + indexPath.row >= (NSInteger) self.searchPhoneNumberWithAccounts.count) { + OWSAssert(0); + } + NSString *phoneNumber = self.searchPhoneNumberWithAccounts[(NSUInteger) indexPath.row]; + UITableViewCell *conversationForNonContactCell = [UITableViewCell new]; + conversationForNonContactCell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(@"NEW_CONVERSATION_FOR_NON_CONTACT_FORMAT", @"Text for button to start a new conversation with a non-contact"), - self.searchPhoneNumber]; - return self.conversationForNonContactCell; + phoneNumber]; + return conversationForNonContactCell; } else if (indexPath.section == MessageComposeTableViewControllerSectionInviteViaSMS) { - self.inviteViaSMSCell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(@"SEND_INVITE_VIA_SMS_BUTTON_FORMAT", + if (indexPath.row < 0 || + indexPath.row >= (NSInteger) self.searchPhoneNumbers.count) { + OWSAssert(0); + } + NSString *phoneNumber = self.searchPhoneNumbers[(NSUInteger) indexPath.row]; + UITableViewCell *inviteViaSMSCell = [UITableViewCell new]; + inviteViaSMSCell.textLabel.text = [NSString stringWithFormat:NSLocalizedString(@"SEND_INVITE_VIA_SMS_BUTTON_FORMAT", @"Text for button to send a Signal invite via SMS. %@ is placeholder for the receipient's phone number."), - self.searchPhoneNumber]; - return self.inviteViaSMSCell; + phoneNumber]; + return inviteViaSMSCell; } else if (indexPath.section == MessageComposeTableViewControllerSectionInviteFlow) { + self.inviteCell.hidden = NO; return self.inviteCell; } else { OWSAssert(indexPath.section == MessageComposeTableViewControllerSectionContacts) @@ -571,16 +616,26 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == MessageComposeTableViewControllerSectionInviteNonContactConversation) { - OWSAssert(self.searchPhoneNumber.length > 0); + if (indexPath.row < 0 || + indexPath.row >= (NSInteger) self.searchPhoneNumberWithAccounts.count) { + OWSAssert(0); + } + NSString *phoneNumber = self.searchPhoneNumberWithAccounts[(NSUInteger) indexPath.row]; + OWSAssert(phoneNumber.length > 0); - if (self.searchPhoneNumber.length > 0) { + if (phoneNumber.length > 0) { [self dismissViewControllerAnimated:YES completion:^() { - [Environment messageIdentifier:self.searchPhoneNumber withCompose:YES]; + [Environment messageIdentifier:phoneNumber withCompose:YES]; }]; } } else if (indexPath.section == MessageComposeTableViewControllerSectionInviteViaSMS) { - [self sendText]; + if (indexPath.row < 0 || + indexPath.row >= (NSInteger) self.searchPhoneNumbers.count) { + OWSAssert(0); + } + NSString *phoneNumber = self.searchPhoneNumbers[(NSUInteger) indexPath.row]; + [self sendTextToPhoneNumber:phoneNumber]; } else if (indexPath.section == MessageComposeTableViewControllerSectionInviteFlow) { void (^showInvite)() = ^{ OWSInviteFlow *inviteFlow = From 82179c6d47b356baa16a56d93502ce0d9a9c565b Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 16 Mar 2017 14:11:05 -0300 Subject: [PATCH 2/3] Respond to CR. // FREEBIE --- .../MessageComposeTableViewController.m | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Signal/src/view controllers/MessageComposeTableViewController.m b/Signal/src/view controllers/MessageComposeTableViewController.m index 208c56137..f3c25ecfd 100644 --- a/Signal/src/view controllers/MessageComposeTableViewController.m +++ b/Signal/src/view controllers/MessageComposeTableViewController.m @@ -35,10 +35,10 @@ NS_ASSUME_NONNULL_BEGIN // A list of possible phone numbers parsed from the search text as // E164 values. -@property (nonatomic) NSArray *searchPhoneNumbers; +@property (nonatomic) NSArray *searchPhoneNumbers; // A list of possible phone numbers parsed from the search text // that correspond to known accounts as E164 values. -@property (nonatomic) NSArray *searchPhoneNumberWithAccounts; +@property (nonatomic) NSArray *searchPhoneNumberWithAccounts; // This dictionary is used to cache the set of phone numbers // which are known to correspond to Signal accounts. @property (nonatomic, nonnull, readonly) NSMutableSet *phoneNumberAccountSet; @@ -63,7 +63,6 @@ typedef NS_ENUM(NSInteger, AdvancedSettingsTableViewControllerSection) { MessageComposeTableViewControllerSection_Count // meta section }; -NSString *const MessageComposeTableViewControllerCellInvite = @"ContactTableInviteCell"; NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableViewCell"; @implementation MessageComposeTableViewController @@ -350,7 +349,7 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie OWSContactsSearcher *contactsSearcher = [[OWSContactsSearcher alloc] initWithContacts: self.contacts]; self.searchResults = [contactsSearcher filterWithString:searchText]; - NSMutableArray *searchPhoneNumbers = [NSMutableArray new]; + NSMutableArray *searchPhoneNumbers = [NSMutableArray new]; for (PhoneNumber *phoneNumber in [PhoneNumber tryParsePhoneNumbersFromsUserSpecifiedText:searchText clientPhoneNumber:[TSStorageManager localNumber]]) { [searchPhoneNumbers addObject:phoneNumber.toE164]; @@ -398,7 +397,7 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie }]; } -- (void)setSearchPhoneNumbers:(NSArray *)searchPhoneNumbers { +- (void)setSearchPhoneNumbers:(NSArray *)searchPhoneNumbers { if ([_searchPhoneNumbers isEqual:searchPhoneNumbers]) { return; } @@ -411,16 +410,17 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie } - (void)ensureSearchPhoneNumberWithAccounts { - NSMutableArray *searchPhoneNumberWithAccounts = [NSMutableArray new]; + NSMutableArray *searchPhoneNumberWithAccounts = [NSMutableArray new]; for (NSString *phoneNumber in self.searchPhoneNumbers) { - if ([self.phoneNumberAccountSet containsObject:phoneNumber]) { + if ([self.phoneNumberAccountSet containsObject:phoneNumber] && + ![searchPhoneNumberWithAccounts containsObject:phoneNumber]) { [searchPhoneNumberWithAccounts addObject:phoneNumber]; } } self.searchPhoneNumberWithAccounts = searchPhoneNumberWithAccounts; } -- (void)setSearchPhoneNumberWithAccounts:(NSArray *)searchPhoneNumberWithAccounts { +- (void)setSearchPhoneNumberWithAccounts:(NSArray *)searchPhoneNumberWithAccounts { if ([_searchPhoneNumberWithAccounts isEqual:searchPhoneNumberWithAccounts]) { return; } @@ -604,6 +604,7 @@ NSString *const MessageComposeTableViewControllerCellContact = @"ContactTableVie ContactTableViewCell *cell = (ContactTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MessageComposeTableViewControllerCellContact]; + cell.hidden = NO; [cell configureWithContact:[self contactForIndexPath:indexPath] contactsManager:self.contactsManager]; From 09938603764cee0fc9df203f7b7b8d978cf23f33 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 16 Mar 2017 14:36:02 -0300 Subject: [PATCH 3/3] [SSK] Update SSK pod to reflect corresponding changes. // FREEBIE --- Podfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Podfile.lock b/Podfile.lock index a2fea2274..512d4032d 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -136,7 +136,7 @@ CHECKOUT OPTIONS: :commit: a3c843cc8a423c5924c663490978f81dba34d04e :git: https://github.com/WhisperSystems/SignalProtocolKit.git SignalServiceKit: - :commit: ca81e139bbe968dbaf41445ea4c92d45f57f6f5f + :commit: 312f398dddb5eac902ae5a7739f0ae814caa7912 :git: https://github.com/WhisperSystems/SignalServiceKit.git SocketRocket: :commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf @@ -169,4 +169,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 7088298933b189805c955880c8d1be86da3078af -COCOAPODS: 1.2.0 +COCOAPODS: 1.1.1