Add SignalAccount class.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-05-01 12:51:59 -04:00
parent 93700f1044
commit 6801963a1b
30 changed files with 552 additions and 823 deletions

View file

@ -25,7 +25,6 @@
345671011E89A5F1006EE662 /* ThreadUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671001E89A5F1006EE662 /* ThreadUtil.m */; }; 345671011E89A5F1006EE662 /* ThreadUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671001E89A5F1006EE662 /* ThreadUtil.m */; };
3456710A1E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */; }; 3456710A1E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */; };
3472229F1EB22FFE00E53955 /* AddToGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */; }; 3472229F1EB22FFE00E53955 /* AddToGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */; };
34B3F8321E8DF11D0035BE1A /* GroupContactsResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8311E8DF11D0035BE1A /* GroupContactsResult.m */; };
34B3F8711E8DF1700035BE1A /* AboutTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */; }; 34B3F8711E8DF1700035BE1A /* AboutTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */; };
34B3F8721E8DF1700035BE1A /* AdvancedSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8371E8DF1700035BE1A /* AdvancedSettingsTableViewController.m */; }; 34B3F8721E8DF1700035BE1A /* AdvancedSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8371E8DF1700035BE1A /* AdvancedSettingsTableViewController.m */; };
34B3F8731E8DF1700035BE1A /* AttachmentApprovalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8381E8DF1700035BE1A /* AttachmentApprovalViewController.swift */; }; 34B3F8731E8DF1700035BE1A /* AttachmentApprovalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8381E8DF1700035BE1A /* AttachmentApprovalViewController.swift */; };
@ -70,7 +69,7 @@
34D5CCA61EA934A4005515DB /* NSTimer+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCA51EA934A4005515DB /* NSTimer+OWS.m */; }; 34D5CCA61EA934A4005515DB /* NSTimer+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCA51EA934A4005515DB /* NSTimer+OWS.m */; };
34D5CCA91EAE3D30005515DB /* GroupViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCA81EAE3D30005515DB /* GroupViewHelper.m */; }; 34D5CCA91EAE3D30005515DB /* GroupViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCA81EAE3D30005515DB /* GroupViewHelper.m */; };
34D5CCB11EAE7E7F005515DB /* SelectRecipientViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCB01EAE7E7F005515DB /* SelectRecipientViewController.m */; }; 34D5CCB11EAE7E7F005515DB /* SelectRecipientViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCB01EAE7E7F005515DB /* SelectRecipientViewController.m */; };
34D5CCB41EAEA225005515DB /* ContactAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCB31EAEA225005515DB /* ContactAccount.m */; }; 34D5CCB41EAEA225005515DB /* SignalAccount.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCB31EAEA225005515DB /* SignalAccount.m */; };
34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DFCB841E8E04B500053165 /* AddToBlockListViewController.m */; }; 34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DFCB841E8E04B500053165 /* AddToBlockListViewController.m */; };
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */; }; 34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */; };
450573FE1E78A06D00615BB4 /* OWS103EnableVideoCalling.m in Sources */ = {isa = PBXBuildFile; fileRef = 450573FD1E78A06D00615BB4 /* OWS103EnableVideoCalling.m */; }; 450573FE1E78A06D00615BB4 /* OWS103EnableVideoCalling.m in Sources */ = {isa = PBXBuildFile; fileRef = 450573FD1E78A06D00615BB4 /* OWS103EnableVideoCalling.m */; };
@ -386,8 +385,6 @@
345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSGenericAttachmentAdapter.m; sourceTree = "<group>"; }; 345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSGenericAttachmentAdapter.m; sourceTree = "<group>"; };
3472229D1EB22FFE00E53955 /* AddToGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToGroupViewController.h; sourceTree = "<group>"; }; 3472229D1EB22FFE00E53955 /* AddToGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToGroupViewController.h; sourceTree = "<group>"; };
3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToGroupViewController.m; sourceTree = "<group>"; }; 3472229E1EB22FFE00E53955 /* AddToGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToGroupViewController.m; sourceTree = "<group>"; };
34B3F8301E8DF11D0035BE1A /* GroupContactsResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GroupContactsResult.h; sourceTree = "<group>"; };
34B3F8311E8DF11D0035BE1A /* GroupContactsResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GroupContactsResult.m; sourceTree = "<group>"; };
34B3F8341E8DF1700035BE1A /* AboutTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutTableViewController.h; sourceTree = "<group>"; }; 34B3F8341E8DF1700035BE1A /* AboutTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutTableViewController.h; sourceTree = "<group>"; };
34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutTableViewController.m; sourceTree = "<group>"; }; 34B3F8351E8DF1700035BE1A /* AboutTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutTableViewController.m; sourceTree = "<group>"; };
34B3F8361E8DF1700035BE1A /* AdvancedSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdvancedSettingsTableViewController.h; sourceTree = "<group>"; }; 34B3F8361E8DF1700035BE1A /* AdvancedSettingsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdvancedSettingsTableViewController.h; sourceTree = "<group>"; };
@ -467,8 +464,8 @@
34D5CCAB1EAE7136005515DB /* OWSConversationSettingsViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSConversationSettingsViewDelegate.h; sourceTree = "<group>"; }; 34D5CCAB1EAE7136005515DB /* OWSConversationSettingsViewDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSConversationSettingsViewDelegate.h; sourceTree = "<group>"; };
34D5CCAF1EAE7E7F005515DB /* SelectRecipientViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectRecipientViewController.h; sourceTree = "<group>"; }; 34D5CCAF1EAE7E7F005515DB /* SelectRecipientViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectRecipientViewController.h; sourceTree = "<group>"; };
34D5CCB01EAE7E7F005515DB /* SelectRecipientViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectRecipientViewController.m; sourceTree = "<group>"; }; 34D5CCB01EAE7E7F005515DB /* SelectRecipientViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SelectRecipientViewController.m; sourceTree = "<group>"; };
34D5CCB21EAEA225005515DB /* ContactAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactAccount.h; sourceTree = "<group>"; }; 34D5CCB21EAEA225005515DB /* SignalAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalAccount.h; sourceTree = "<group>"; };
34D5CCB31EAEA225005515DB /* ContactAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactAccount.m; sourceTree = "<group>"; }; 34D5CCB31EAEA225005515DB /* SignalAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SignalAccount.m; sourceTree = "<group>"; };
34DFCB831E8E04B400053165 /* AddToBlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToBlockListViewController.h; sourceTree = "<group>"; }; 34DFCB831E8E04B400053165 /* AddToBlockListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddToBlockListViewController.h; sourceTree = "<group>"; };
34DFCB841E8E04B500053165 /* AddToBlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToBlockListViewController.m; sourceTree = "<group>"; }; 34DFCB841E8E04B500053165 /* AddToBlockListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddToBlockListViewController.m; sourceTree = "<group>"; };
34FD936E1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSAnyTouchGestureRecognizer.h; path = views/OWSAnyTouchGestureRecognizer.h; sourceTree = "<group>"; }; 34FD936E1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSAnyTouchGestureRecognizer.h; path = views/OWSAnyTouchGestureRecognizer.h; sourceTree = "<group>"; };
@ -878,8 +875,6 @@
34B3F83B1E8DF1700035BE1A /* CallViewController.swift */, 34B3F83B1E8DF1700035BE1A /* CallViewController.swift */,
34B3F83C1E8DF1700035BE1A /* CodeVerificationViewController.h */, 34B3F83C1E8DF1700035BE1A /* CodeVerificationViewController.h */,
34B3F83D1E8DF1700035BE1A /* CodeVerificationViewController.m */, 34B3F83D1E8DF1700035BE1A /* CodeVerificationViewController.m */,
34D5CCB21EAEA225005515DB /* ContactAccount.h */,
34D5CCB31EAEA225005515DB /* ContactAccount.m */,
34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */, 34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */,
34B3F83F1E8DF1700035BE1A /* ContactsPicker.xib */, 34B3F83F1E8DF1700035BE1A /* ContactsPicker.xib */,
340CB2221EAC155C0001CAA1 /* ContactsViewHelper.h */, 340CB2221EAC155C0001CAA1 /* ContactsViewHelper.h */,
@ -941,6 +936,8 @@
34B3F8691E8DF1700035BE1A /* SettingsTableViewController.m */, 34B3F8691E8DF1700035BE1A /* SettingsTableViewController.m */,
34B3F86A1E8DF1700035BE1A /* ShowGroupMembersViewController.h */, 34B3F86A1E8DF1700035BE1A /* ShowGroupMembersViewController.h */,
34B3F86B1E8DF1700035BE1A /* ShowGroupMembersViewController.m */, 34B3F86B1E8DF1700035BE1A /* ShowGroupMembersViewController.m */,
34D5CCB21EAEA225005515DB /* SignalAccount.h */,
34D5CCB31EAEA225005515DB /* SignalAccount.m */,
34B3F86C1E8DF1700035BE1A /* SignalAttachment.swift */, 34B3F86C1E8DF1700035BE1A /* SignalAttachment.swift */,
34B3F86D1E8DF1700035BE1A /* SignalsNavigationController.h */, 34B3F86D1E8DF1700035BE1A /* SignalsNavigationController.h */,
34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */, 34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */,
@ -1193,8 +1190,6 @@
76EB040318170B33006006FC /* contact */ = { 76EB040318170B33006006FC /* contact */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
34B3F8301E8DF11D0035BE1A /* GroupContactsResult.h */,
34B3F8311E8DF11D0035BE1A /* GroupContactsResult.m */,
76EB040818170B33006006FC /* OWSContactsManager.h */, 76EB040818170B33006006FC /* OWSContactsManager.h */,
76EB040918170B33006006FC /* OWSContactsManager.m */, 76EB040918170B33006006FC /* OWSContactsManager.m */,
45843D1D1D2236B30013E85A /* OWSContactsSearcher.h */, 45843D1D1D2236B30013E85A /* OWSContactsSearcher.h */,
@ -2040,7 +2035,7 @@
34D5CCB11EAE7E7F005515DB /* SelectRecipientViewController.m in Sources */, 34D5CCB11EAE7E7F005515DB /* SelectRecipientViewController.m in Sources */,
34B3F88F1E8DF1710035BE1A /* RegistrationViewController.m in Sources */, 34B3F88F1E8DF1710035BE1A /* RegistrationViewController.m in Sources */,
34B3F8901E8DF1710035BE1A /* SettingsTableViewController.m in Sources */, 34B3F8901E8DF1710035BE1A /* SettingsTableViewController.m in Sources */,
34D5CCB41EAEA225005515DB /* ContactAccount.m in Sources */, 34D5CCB41EAEA225005515DB /* SignalAccount.m in Sources */,
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */, 34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */,
343D3D9B1E9283F100165CA4 /* BlockListUIUtils.m in Sources */, 343D3D9B1E9283F100165CA4 /* BlockListUIUtils.m in Sources */,
34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */, 34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */,
@ -2076,7 +2071,6 @@
452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */, 452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */,
452EA0971EA662330078744B /* AttachmentPointerAdapter.swift in Sources */, 452EA0971EA662330078744B /* AttachmentPointerAdapter.swift in Sources */,
34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */, 34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */,
34B3F8321E8DF11D0035BE1A /* GroupContactsResult.m in Sources */,
45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */, 45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */,
45666EC61D99483D008FE134 /* OWSAvatarBuilder.m in Sources */, 45666EC61D99483D008FE134 /* OWSAvatarBuilder.m in Sources */,
45E615161E8C590B0018AD52 /* DisplayableTextFilter.swift in Sources */, 45E615161E8C590B0018AD52 /* DisplayableTextFilter.swift in Sources */,

View file

@ -23,6 +23,7 @@
#import "PrivacySettingsTableViewController.h" #import "PrivacySettingsTableViewController.h"
#import "PropertyListPreferences.h" #import "PropertyListPreferences.h"
#import "PushManager.h" #import "PushManager.h"
#import "SignalAccount.h"
#import "TSSocketManager.h" #import "TSSocketManager.h"
#import "TSStorageManager+Calling.h" #import "TSStorageManager+Calling.h"
#import "UIColor+OWS.h" #import "UIColor+OWS.h"

View file

@ -4,9 +4,9 @@
#import "AddToBlockListViewController.h" #import "AddToBlockListViewController.h"
#import "BlockListUIUtils.h" #import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactsViewHelper.h" #import "ContactsViewHelper.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "SignalAccount.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -60,14 +60,14 @@ NS_ASSUME_NONNULL_BEGIN
}]; }];
} }
- (void)contactAccountWasSelected:(ContactAccount *)contactAccount - (void)signalAccountWasSelected:(SignalAccount *)signalAccount
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
__weak AddToBlockListViewController *weakSelf = self; __weak AddToBlockListViewController *weakSelf = self;
ContactsViewHelper *helper = self.contactsViewHelper; ContactsViewHelper *helper = self.contactsViewHelper;
if ([helper isRecipientIdBlocked:contactAccount.recipientId]) { if ([helper isRecipientIdBlocked:signalAccount.recipientId]) {
NSString *displayName = [helper.contactsManager displayNameForContactAccount:contactAccount]; NSString *displayName = [helper.contactsManager displayNameForSignalAccount:signalAccount];
UIAlertController *controller = [UIAlertController UIAlertController *controller = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_ALREADY_BLOCKED_ALERT_TITLE", alertControllerWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_ALREADY_BLOCKED_ALERT_TITLE",
@"A title of the alert if user tries to block a " @"A title of the alert if user tries to block a "
@ -88,15 +88,15 @@ NS_ASSUME_NONNULL_BEGIN
[self presentViewController:controller animated:YES completion:nil]; [self presentViewController:controller animated:YES completion:nil];
return; return;
} }
[BlockListUIUtils showBlockContactAccountActionSheet:contactAccount [BlockListUIUtils showBlockSignalAccountActionSheet:signalAccount
fromViewController:self fromViewController:self
blockingManager:helper.blockingManager blockingManager:helper.blockingManager
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) { completionBlock:^(BOOL isBlocked) {
if (isBlocked) { if (isBlocked) {
[weakSelf.navigationController popViewControllerAnimated:YES]; [weakSelf.navigationController popViewControllerAnimated:YES];
} }
}]; }];
} }
- (BOOL)shouldHideLocalNumber - (BOOL)shouldHideLocalNumber

View file

@ -4,9 +4,9 @@
#import "AddToGroupViewController.h" #import "AddToGroupViewController.h"
#import "BlockListUIUtils.h" #import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactsViewHelper.h" #import "ContactsViewHelper.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "SignalAccount.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -66,24 +66,24 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
- (void)contactAccountWasSelected:(ContactAccount *)contactAccount - (void)signalAccountWasSelected:(SignalAccount *)signalAccount
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
__weak AddToGroupViewController *weakSelf = self; __weak AddToGroupViewController *weakSelf = self;
ContactsViewHelper *helper = self.contactsViewHelper; ContactsViewHelper *helper = self.contactsViewHelper;
if ([helper isRecipientIdBlocked:contactAccount.recipientId]) { if ([helper isRecipientIdBlocked:signalAccount.recipientId]) {
[BlockListUIUtils showUnblockContactAccountActionSheet:contactAccount [BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self fromViewController:self
blockingManager:helper.blockingManager blockingManager:helper.blockingManager
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) { completionBlock:^(BOOL isBlocked) {
if (isBlocked) { if (isBlocked) {
[weakSelf addToGroup:contactAccount.recipientId]; [weakSelf addToGroup:signalAccount.recipientId];
} }
}]; }];
} else { } else {
[self addToGroup:contactAccount.recipientId]; [self addToGroup:signalAccount.recipientId];
} }
} }

View file

@ -7,7 +7,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class Contact; @class Contact;
@class ContactAccount; @class SignalAccount;
@class OWSBlockingManager; @class OWSBlockingManager;
@class OWSContactsManager; @class OWSContactsManager;
@ -25,11 +25,11 @@ typedef void (^BlockActionCompletionBlock)(BOOL isBlocked);
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
completionBlock:(nullable BlockActionCompletionBlock)completionBlock; completionBlock:(nullable BlockActionCompletionBlock)completionBlock;
+ (void)showBlockContactAccountActionSheet:(ContactAccount *)contactAccount + (void)showBlockSignalAccountActionSheet:(SignalAccount *)signalAccount
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
blockingManager:(OWSBlockingManager *)blockingManager blockingManager:(OWSBlockingManager *)blockingManager
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
completionBlock:(nullable BlockActionCompletionBlock)completionBlock; completionBlock:(nullable BlockActionCompletionBlock)completionBlock;
#pragma mark - Unblock #pragma mark - Unblock
@ -39,11 +39,11 @@ typedef void (^BlockActionCompletionBlock)(BOOL isBlocked);
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
completionBlock:(nullable BlockActionCompletionBlock)completionBlock; completionBlock:(nullable BlockActionCompletionBlock)completionBlock;
+ (void)showUnblockContactAccountActionSheet:(ContactAccount *)contactAccount + (void)showUnblockSignalAccountActionSheet:(SignalAccount *)signalAccount
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
blockingManager:(OWSBlockingManager *)blockingManager blockingManager:(OWSBlockingManager *)blockingManager
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
completionBlock:(nullable BlockActionCompletionBlock)completionBlock; completionBlock:(nullable BlockActionCompletionBlock)completionBlock;
#pragma mark - UI Utils #pragma mark - UI Utils

View file

@ -3,9 +3,9 @@
// //
#import "BlockListUIUtils.h" #import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "PhoneNumber.h" #import "PhoneNumber.h"
#import "SignalAccount.h"
#import <SignalServiceKit/Contact.h> #import <SignalServiceKit/Contact.h>
#import <SignalServiceKit/OWSBlockingManager.h> #import <SignalServiceKit/OWSBlockingManager.h>
#import <SignalServiceKit/TSAccountManager.h> #import <SignalServiceKit/TSAccountManager.h>
@ -32,14 +32,14 @@ typedef void (^BlockAlertCompletionBlock)();
completionBlock:completionBlock]; completionBlock:completionBlock];
} }
+ (void)showBlockContactAccountActionSheet:(ContactAccount *)contactAccount + (void)showBlockSignalAccountActionSheet:(SignalAccount *)signalAccount
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
blockingManager:(OWSBlockingManager *)blockingManager blockingManager:(OWSBlockingManager *)blockingManager
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
completionBlock:(nullable BlockActionCompletionBlock)completionBlock completionBlock:(nullable BlockActionCompletionBlock)completionBlock
{ {
NSString *displayName = [contactsManager displayNameForContactAccount:contactAccount]; NSString *displayName = [contactsManager displayNameForSignalAccount:signalAccount];
[self showBlockPhoneNumbersActionSheet:@[ contactAccount.recipientId ] [self showBlockPhoneNumbersActionSheet:@[ signalAccount.recipientId ]
displayName:displayName displayName:displayName
fromViewController:fromViewController fromViewController:fromViewController
blockingManager:blockingManager blockingManager:blockingManager
@ -159,14 +159,14 @@ typedef void (^BlockAlertCompletionBlock)();
completionBlock:completionBlock]; completionBlock:completionBlock];
} }
+ (void)showUnblockContactAccountActionSheet:(ContactAccount *)contactAccount + (void)showUnblockSignalAccountActionSheet:(SignalAccount *)signalAccount
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
blockingManager:(OWSBlockingManager *)blockingManager blockingManager:(OWSBlockingManager *)blockingManager
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
completionBlock:(nullable BlockActionCompletionBlock)completionBlock completionBlock:(nullable BlockActionCompletionBlock)completionBlock
{ {
NSString *displayName = [contactsManager displayNameForContactAccount:contactAccount]; NSString *displayName = [contactsManager displayNameForSignalAccount:signalAccount];
[self showUnblockPhoneNumbersActionSheet:@[ contactAccount.recipientId ] [self showUnblockPhoneNumbersActionSheet:@[ signalAccount.recipientId ]
displayName:displayName displayName:displayName
fromViewController:fromViewController fromViewController:fromViewController
blockingManager:blockingManager blockingManager:blockingManager

View file

@ -4,6 +4,6 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@interface BlockListViewController : UITableViewController @interface BlockListViewController : UIViewController
@end @end

View file

@ -5,69 +5,46 @@
#import "BlockListViewController.h" #import "BlockListViewController.h"
#import "AddToBlockListViewController.h" #import "AddToBlockListViewController.h"
#import "BlockListUIUtils.h" #import "BlockListUIUtils.h"
#import "ContactsViewHelper.h"
#import "Environment.h" #import "Environment.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "OWSTableViewController.h"
#import "PhoneNumber.h" #import "PhoneNumber.h"
#import "UIFont+OWS.h" #import "UIFont+OWS.h"
#import "UIView+OWS.h"
#import <SignalServiceKit/OWSBlockingManager.h> #import <SignalServiceKit/OWSBlockingManager.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface BlockListViewController () @interface BlockListViewController () <ContactsViewHelperDelegate>
@property (nonatomic, readonly) OWSBlockingManager *blockingManager; @property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper;
@property (nonatomic, readonly) NSArray<NSString *> *blockedPhoneNumbers;
@property (nonatomic, readonly) OWSContactsManager *contactsManager; @property (nonatomic, readonly) OWSTableViewController *tableViewController;
@property (nonatomic) NSArray<Contact *> *contacts;
@end @end
#pragma mark - #pragma mark -
typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
BlockListViewControllerSection_Add,
BlockListViewControllerSection_BlockList,
BlockListViewControllerSection_Count // meta section
};
@implementation BlockListViewController @implementation BlockListViewController
- (instancetype)init
{
return [super initWithStyle:UITableViewStyleGrouped];
}
- (void)loadView - (void)loadView
{ {
[super loadView]; [super loadView];
_blockingManager = [OWSBlockingManager sharedManager]; _contactsViewHelper = [ContactsViewHelper new];
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers]; _contactsViewHelper.delegate = self;
_contactsManager = [Environment getCurrent].contactsManager;
self.contacts = [self.contactsManager.signalContacts copy];
self.title self.title
= NSLocalizedString(@"SETTINGS_BLOCK_LIST_TITLE", @"Label for the block list section of the settings view"); = NSLocalizedString(@"SETTINGS_BLOCK_LIST_TITLE", @"Label for the block list section of the settings view");
[self addNotificationListeners]; _tableViewController = [OWSTableViewController new];
} [self.view addSubview:self.tableViewController.view];
[_tableViewController.view autoPinWidthToSuperview];
[_tableViewController.view autoPinToTopLayoutGuideOfViewController:self withInset:0];
[_tableViewController.view autoPinToBottomLayoutGuideOfViewController:self withInset:0];
- (void)addNotificationListeners [self updateTableContents];
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(blockedPhoneNumbersDidChange:)
name:kNSNotificationName_BlockedPhoneNumbersDidChange
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(signalRecipientsDidChange:)
name:OWSContactsManagerSignalRecipientsDidChangeNotification
object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
} }
- (void)viewDidLoad - (void)viewDidLoad
@ -78,120 +55,75 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
#pragma mark - Table view data source #pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView - (void)updateTableContents
{ {
return BlockListViewControllerSection_Count; OWSTableContents *contents = [OWSTableContents new];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section __weak BlockListViewController *weakSelf = self;
{ ContactsViewHelper *helper = self.contactsViewHelper;
switch (section) {
case BlockListViewControllerSection_Add: // Add section
return 1;
case BlockListViewControllerSection_BlockList: OWSTableSection *addSection = [OWSTableSection new];
return (NSInteger) _blockedPhoneNumbers.count; addSection.footerTitle = NSLocalizedString(
default: @"BLOCK_BEHAVIOR_EXPLANATION", @"An explanation of the consequences of blocking another user.");
OWSAssert(0);
return 0; [addSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
UITableViewCell *cell = [UITableViewCell new];
cell.textLabel.text = NSLocalizedString(
@"SETTINGS_BLOCK_LIST_ADD_BUTTON", @"A label for the 'add phone number' button in the block list table.");
cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f];
cell.textLabel.textColor = [UIColor blackColor];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
} }
} actionBlock:^{
AddToBlockListViewController *vc = [[AddToBlockListViewController alloc] init];
NSAssert(self.navigationController != nil, @"Navigation controller must not be nil");
NSAssert(vc != nil, @"Privacy Settings View Controller must not be nil");
[weakSelf.navigationController pushViewController:vc animated:YES];
}]];
[contents addSection:addSection];
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section // Blocklist section
{
switch (section) {
case BlockListViewControllerSection_Add:
return NSLocalizedString(@"BLOCK_BEHAVIOR_EXPLANATION",
@"An explanation of the consequences of blocking another user.");
default:
return nil;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath OWSTableSection *blocklistSection = [OWSTableSection new];
{ NSArray<NSString *> *blockedPhoneNumbers =
UITableViewCell *cell = [UITableViewCell new]; [helper.blockedPhoneNumbers sortedArrayUsingSelector:@selector(compare:)];
OWSAssert(cell); for (NSString *phoneNumber in blockedPhoneNumbers) {
[blocklistSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
switch (indexPath.section) { // TODO: Use ContactTableViewCell.
case BlockListViewControllerSection_Add: UITableViewCell *cell = [UITableViewCell new];
cell.textLabel.text = NSLocalizedString( NSString *displayName = [helper.contactsManager displayNameForPhoneIdentifier:phoneNumber];
@"SETTINGS_BLOCK_LIST_ADD_BUTTON", @"A label for the 'add phone number' button in the block list table.");
cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break;
case BlockListViewControllerSection_BlockList: {
NSString *displayName = [self displayNameForIndexPath:indexPath];
cell.textLabel.text = displayName; cell.textLabel.text = displayName;
cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f]; cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f];
cell.accessoryType = UITableViewCellAccessoryCheckmark; cell.accessoryType = UITableViewCellAccessoryCheckmark;
break; cell.textLabel.textColor = [UIColor blackColor];
return cell;
} }
default: actionBlock:^{
OWSAssert(0); [BlockListUIUtils showUnblockPhoneNumberActionSheet:phoneNumber
return 0; fromViewController:weakSelf
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:nil];
}]];
} }
[contents addSection:blocklistSection];
return cell;
self.tableViewController.contents = contents;
} }
- (NSString *)displayNameForIndexPath:(NSIndexPath *)indexPath #pragma mark - ContactsViewHelperDelegate
- (void)contactsViewHelperDidUpdateContacts
{ {
NSString *phoneNumber = _blockedPhoneNumbers[(NSUInteger)indexPath.item]; [self updateTableContents];
NSString *displayName = [_contactsManager displayNameForPhoneIdentifier:phoneNumber];
return displayName;
} }
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath - (BOOL)shouldHideLocalNumber
{ {
[tableView deselectRowAtIndexPath:indexPath animated:YES]; return YES;
switch (indexPath.section) {
case BlockListViewControllerSection_Add:
{
AddToBlockListViewController *vc = [[AddToBlockListViewController alloc] init];
NSAssert(self.navigationController != nil, @"Navigation controller must not be nil");
NSAssert(vc != nil, @"Privacy Settings View Controller must not be nil");
[self.navigationController pushViewController:vc animated:YES];
break;
}
case BlockListViewControllerSection_BlockList: {
NSString *phoneNumber = _blockedPhoneNumbers[(NSUInteger)indexPath.item];
[BlockListUIUtils showUnblockPhoneNumberActionSheet:phoneNumber
fromViewController:self
blockingManager:_blockingManager
contactsManager:_contactsManager
completionBlock:nil];
break;
}
default:
OWSAssert(0);
}
}
#pragma mark - Actions
- (void)blockedPhoneNumbersDidChange:(id)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
[self.tableView reloadData];
});
}
- (void)signalRecipientsDidChange:(NSNotification *)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
[self updateContacts];
});
}
- (void)updateContacts
{
OWSAssert([NSThread isMainThread]);
self.contacts = [self.contactsManager.signalContacts copy];
[self.tableView reloadData];
} }
#pragma mark - Logging #pragma mark - Logging

View file

@ -1,27 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@class Contact;
// We want to be able to present contacts with multiple signal
// accounts in the UI. This class represents a given (contact,
// signal account) tuple.
@interface ContactAccount : NSObject
@property (nonatomic) Contact *contact;
// An E164 value identifying the signal account.
@property (nonatomic) NSString *recipientId;
@property (nonatomic) BOOL isMultipleAccountContact;
// For contacts with more than one signal account,
// this is a label for the account.
@property (nonatomic) NSString *multipleAccountLabel;
@end
NS_ASSUME_NONNULL_END

View file

@ -1,13 +0,0 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "ContactAccount.h"
NS_ASSUME_NONNULL_BEGIN
@implementation ContactAccount
@end
NS_ASSUME_NONNULL_END

View file

@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
@class ContactsViewHelper; @class ContactsViewHelper;
@class Contact; @class Contact;
@class ContactAccount; @class SignalAccount;
@protocol ContactsViewHelperDelegate <NSObject> @protocol ContactsViewHelperDelegate <NSObject>
@ -28,18 +28,12 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) OWSContactsManager *contactsManager; @property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic, readonly) OWSBlockingManager *blockingManager; @property (nonatomic, readonly) OWSBlockingManager *blockingManager;
// A list of all of the current user's contacts which have @property (nonatomic, readonly) NSDictionary<NSString *, SignalAccount *> *signalAccountMap;
// at least one signal account. @property (nonatomic, readonly) NSArray<SignalAccount *> *signalAccounts;
- (nullable NSArray<Contact *> *)allRecipientContacts;
// A list of all of the current user's ContactAccounts. @property (nonatomic, readonly) NSArray<NSString *> *blockedPhoneNumbers;
// See the comments on the ContactAccount class.
//
// The list is ordered by contact sorting (by OWSContactsManager)
// and within contacts by phone number, alphabetically.
- (nullable NSArray<ContactAccount *> *)allRecipientContactAccounts;
- (nullable ContactAccount *)contactAccountForRecipientId:(NSString *)recipientId; - (nullable SignalAccount *)signalAccountForRecipientId:(NSString *)recipientId;
- (nullable NSArray<NSString *> *)blockedPhoneNumbers; - (nullable NSArray<NSString *> *)blockedPhoneNumbers;
@ -48,6 +42,8 @@ NS_ASSUME_NONNULL_BEGIN
// //
// Returns true if _any_ number associated with this contact // Returns true if _any_ number associated with this contact
// is blocked. // is blocked.
//
// TODO: Is this obsolete?
- (BOOL)isContactBlocked:(Contact *)contact; - (BOOL)isContactBlocked:(Contact *)contact;
// This method is faster than OWSBlockingManager but // This method is faster than OWSBlockingManager but
@ -56,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSString *)localNumber; - (NSString *)localNumber;
- (NSArray<ContactAccount *> *)contactAccountsMatchingSearchString:(NSString *)searchText; - (NSArray<SignalAccount *> *)signalAccountsMatchingSearchString:(NSString *)searchText;
@end @end

View file

@ -3,9 +3,9 @@
// //
#import "ContactsViewHelper.h" #import "ContactsViewHelper.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h" #import "ContactTableViewCell.h"
#import "Environment.h" #import "Environment.h"
#import "SignalAccount.h"
#import <SignalServiceKit/Contact.h> #import <SignalServiceKit/Contact.h>
#import <SignalServiceKit/OWSBlockingManager.h> #import <SignalServiceKit/OWSBlockingManager.h>
#import <SignalServiceKit/TSAccountManager.h> #import <SignalServiceKit/TSAccountManager.h>
@ -14,12 +14,10 @@ NS_ASSUME_NONNULL_BEGIN
@interface ContactsViewHelper () @interface ContactsViewHelper ()
@property (nonatomic, nullable) NSArray<Contact *> *allRecipientContacts; @property (nonatomic) NSDictionary<NSString *, SignalAccount *> *signalAccountMap;
@property (nonatomic, nullable) NSArray<ContactAccount *> *allRecipientContactAccounts; @property (nonatomic) NSArray<SignalAccount *> *signalAccounts;
// A map of recipient id-to-contact account.
@property (nonatomic, nullable) NSDictionary<NSString *, ContactAccount *> *contactAccountMap;
@property (nonatomic, nullable) NSArray<NSString *> *blockedPhoneNumbers; @property (nonatomic) NSArray<NSString *> *blockedPhoneNumbers;
@end @end
@ -38,7 +36,8 @@ NS_ASSUME_NONNULL_BEGIN
self.blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers]; self.blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
_contactsManager = [Environment getCurrent].contactsManager; _contactsManager = [Environment getCurrent].contactsManager;
[self updateContacts]; self.signalAccountMap = self.contactsManager.signalAccountMap;
self.signalAccounts = self.contactsManager.signalAccounts;
[self observeNotifications]; [self observeNotifications];
@ -48,8 +47,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)observeNotifications - (void)observeNotifications
{ {
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(signalRecipientsDidChange:) selector:@selector(signalAccountsDidChange:)
name:OWSContactsManagerSignalRecipientsDidChangeNotification name:OWSContactsManagerSignalAccountsDidChangeNotification
object:nil]; object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(blockedPhoneNumbersDidChange:) selector:@selector(blockedPhoneNumbersDidChange:)
@ -62,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
- (void)signalRecipientsDidChange:(NSNotification *)notification - (void)signalAccountsDidChange:(NSNotification *)notification
{ {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
[self updateContacts]; [self updateContacts];
@ -80,131 +79,19 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Contacts #pragma mark - Contacts
- (nullable ContactAccount *)contactAccountForRecipientId:(NSString *)recipientId - (nullable SignalAccount *)signalAccountForRecipientId:(NSString *)recipientId
{ {
OWSAssert([NSThread isMainThread]); OWSAssert([NSThread isMainThread]);
OWSAssert(recipientId.length > 0); OWSAssert(recipientId.length > 0);
return self.contactAccountMap[recipientId]; return self.signalAccountMap[recipientId];
} }
- (void)updateContacts - (BOOL)isSignalAccountHidden:(SignalAccount *)signalAccount
{ {
OWSAssert([NSThread isMainThread]); OWSAssert([NSThread isMainThread]);
self.allRecipientContacts = [self filteredContacts]; if ([self.delegate shouldHideLocalNumber] && [self isCurrentUser:signalAccount]) {
}
- (void)setAllRecipientContacts:(nullable NSArray<Contact *> *)allRecipientContacts
{
OWSAssert([NSThread isMainThread]);
_allRecipientContacts = allRecipientContacts;
NSMutableArray<ContactAccount *> *allRecipientContactAccounts = [NSMutableArray new];
NSMutableDictionary<NSString *, ContactAccount *> *contactAccountMap = [NSMutableDictionary new];
for (Contact *contact in allRecipientContacts) {
if (contact.textSecureIdentifiers.count == 1) {
ContactAccount *contactAccount = [ContactAccount new];
contactAccount.contact = contact;
NSString *recipientId = contact.textSecureIdentifiers[0];
contactAccount.recipientId = recipientId;
[allRecipientContactAccounts addObject:contactAccount];
contactAccountMap[recipientId] = contactAccount;
} else if (contact.textSecureIdentifiers.count > 1) {
for (NSString *recipientId in
[contact.textSecureIdentifiers sortedArrayUsingSelector:@selector(compare:)]) {
ContactAccount *contactAccount = [ContactAccount new];
contactAccount.contact = contact;
contactAccount.recipientId = recipientId;
contactAccount.isMultipleAccountContact = YES;
contactAccount.multipleAccountLabel = [self accountLabelForContact:contact recipientId:recipientId];
[allRecipientContactAccounts addObject:contactAccount];
contactAccountMap[recipientId] = contactAccount;
}
}
}
self.allRecipientContactAccounts = [allRecipientContactAccounts copy];
self.contactAccountMap = [contactAccountMap copy];
[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]);
if (contact.parsedPhoneNumbers.count < 1) {
// Hide contacts without any valid phone numbers.
return YES;
}
if ([self.delegate shouldHideLocalNumber] && [self isCurrentUserContact:contact]) {
// We never want to add ourselves to a group. // We never want to add ourselves to a group.
return YES; return YES;
} }
@ -212,12 +99,17 @@ NS_ASSUME_NONNULL_BEGIN
return NO; return NO;
} }
- (BOOL)isCurrentUserContact:(Contact *)contact - (BOOL)isCurrentUser:(SignalAccount *)signalAccount
{ {
OWSAssert([NSThread isMainThread]); OWSAssert([NSThread isMainThread]);
for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) { NSString *localNumber = [TSAccountManager localNumber];
if ([[phoneNumber toE164] isEqualToString:[TSAccountManager localNumber]]) { if ([signalAccount.recipientId isEqualToString:localNumber]) {
return YES;
}
for (PhoneNumber *phoneNumber in signalAccount.contact.parsedPhoneNumbers) {
if ([[phoneNumber toE164] isEqualToString:localNumber]) {
return YES; return YES;
} }
} }
@ -255,43 +147,48 @@ NS_ASSUME_NONNULL_BEGIN
return [_blockedPhoneNumbers containsObject:recipientId]; return [_blockedPhoneNumbers containsObject:recipientId];
} }
- (NSArray<Contact *> *_Nonnull)filteredContacts - (void)updateContacts
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
NSMutableArray<Contact *> *result = [NSMutableArray new]; NSMutableDictionary<NSString *, SignalAccount *> *signalAccountMap = [NSMutableDictionary new];
for (Contact *contact in self.contactsManager.signalContacts) { NSMutableArray<SignalAccount *> *signalAccounts = [NSMutableArray new];
if (![self isContactHidden:contact]) { for (SignalAccount *signalAccount in self.contactsManager.signalAccounts) {
[result addObject:contact]; if (![self isSignalAccountHidden:signalAccount]) {
signalAccountMap[signalAccount.recipientId] = signalAccount;
[signalAccounts addObject:signalAccount];
} }
} }
return [result copy]; self.signalAccountMap = signalAccountMap;
self.signalAccounts = signalAccounts;
[self.delegate contactsViewHelperDidUpdateContacts];
} }
- (BOOL)doesContactAccount:(ContactAccount *)contactAccount matchSearchTerm:(NSString *)searchTerm - (BOOL)doesSignalAccount:(SignalAccount *)signalAccount matchSearchTerm:(NSString *)searchTerm
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
OWSAssert(searchTerm.length > 0); OWSAssert(searchTerm.length > 0);
if ([contactAccount.contact.fullName.lowercaseString containsString:searchTerm.lowercaseString]) { if ([signalAccount.contact.fullName.lowercaseString containsString:searchTerm.lowercaseString]) {
return YES; return YES;
} }
NSString *asPhoneNumber = [PhoneNumber removeFormattingCharacters:searchTerm]; NSString *asPhoneNumber = [PhoneNumber removeFormattingCharacters:searchTerm];
if (asPhoneNumber.length > 0 && [contactAccount.recipientId containsString:asPhoneNumber]) { if (asPhoneNumber.length > 0 && [signalAccount.recipientId containsString:asPhoneNumber]) {
return YES; return YES;
} }
return NO; return NO;
} }
- (BOOL)doesContactAccount:(ContactAccount *)contactAccount matchSearchTerms:(NSArray<NSString *> *)searchTerms - (BOOL)doesSignalAccount:(SignalAccount *)signalAccount matchSearchTerms:(NSArray<NSString *> *)searchTerms
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
OWSAssert(searchTerms.count > 0); OWSAssert(searchTerms.count > 0);
for (NSString *searchTerm in searchTerms) { for (NSString *searchTerm in searchTerms) {
if (![self doesContactAccount:contactAccount matchSearchTerm:searchTerm]) { if (![self doesSignalAccount:signalAccount matchSearchTerm:searchTerm]) {
return NO; return NO;
} }
} }
@ -299,20 +196,20 @@ NS_ASSUME_NONNULL_BEGIN
return YES; return YES;
} }
- (NSArray<ContactAccount *> *)contactAccountsMatchingSearchString:(NSString *)searchText - (NSArray<SignalAccount *> *)signalAccountsMatchingSearchString:(NSString *)searchText
{ {
NSArray<NSString *> *searchTerms = NSArray<NSString *> *searchTerms =
[[searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] [[searchText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (searchTerms.count < 1) { if (searchTerms.count < 1) {
return self.allRecipientContactAccounts; return self.signalAccounts;
} }
return [self.allRecipientContactAccounts return [self.signalAccounts
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(ContactAccount *contactAccount, filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SignalAccount *signalAccount,
NSDictionary<NSString *, id> *_Nullable bindings) { NSDictionary<NSString *, id> *_Nullable bindings) {
return [self doesContactAccount:contactAccount matchSearchTerms:searchTerms]; return [self doesSignalAccount:signalAccount matchSearchTerms:searchTerms];
}]]; }]];
} }

View file

@ -6,7 +6,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class ContactAccount; @class SignalAccount;
@class GroupViewHelper; @class GroupViewHelper;
@class OWSContactsManager; @class OWSContactsManager;
@class TSThread; @class TSThread;
@ -27,10 +27,10 @@ typedef void (^GroupViewSuccessBlock)();
@property (nonatomic, weak) id<GroupViewHelperDelegate> delegate; @property (nonatomic, weak) id<GroupViewHelperDelegate> delegate;
- (void)showRemoveFromGroupAlertForContactAccount:(ContactAccount *)contactAccount - (void)showRemoveFromGroupAlertForSignalAccount:(SignalAccount *)signalAccount
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
successBlock:(GroupViewSuccessBlock)successBlock; successBlock:(GroupViewSuccessBlock)successBlock;
- (void)showRemoveFromGroupAlertForRecipientId:(NSString *)recipientId - (void)showRemoveFromGroupAlertForRecipientId:(NSString *)recipientId
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController

View file

@ -23,17 +23,17 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Alerts #pragma mark - Alerts
- (void)showRemoveFromGroupAlertForContactAccount:(ContactAccount *)contactAccount - (void)showRemoveFromGroupAlertForSignalAccount:(SignalAccount *)signalAccount
fromViewController:(UIViewController *)fromViewController fromViewController:(UIViewController *)fromViewController
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
successBlock:(GroupViewSuccessBlock)successBlock successBlock:(GroupViewSuccessBlock)successBlock
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
OWSAssert(fromViewController); OWSAssert(fromViewController);
OWSAssert(contactsManager); OWSAssert(contactsManager);
OWSAssert(successBlock); OWSAssert(successBlock);
NSString *displayName = [contactsManager displayNameForContactAccount:contactAccount]; NSString *displayName = [contactsManager displayNameForSignalAccount:signalAccount];
UIAlertController *controller = [UIAlertController UIAlertController *controller = [UIAlertController
alertControllerWithTitle: alertControllerWithTitle:
NSLocalizedString(@"EDIT_GROUP_REMOVE_MEMBER_ALERT_TITLE", NSLocalizedString(@"EDIT_GROUP_REMOVE_MEMBER_ALERT_TITLE",

View file

@ -4,7 +4,6 @@
#import "NewGroupViewController.h" #import "NewGroupViewController.h"
#import "AddToGroupViewController.h" #import "AddToGroupViewController.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h" #import "ContactTableViewCell.h"
#import "ContactsViewHelper.h" #import "ContactsViewHelper.h"
#import "Environment.h" #import "Environment.h"
@ -13,6 +12,7 @@
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "OWSTableViewController.h" #import "OWSTableViewController.h"
#import "SecurityUtils.h" #import "SecurityUtils.h"
#import "SignalAccount.h"
#import "SignalKeyingStorage.h" #import "SignalKeyingStorage.h"
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
#import "UIUtil.h" #import "UIUtil.h"
@ -185,15 +185,15 @@ NS_ASSUME_NONNULL_BEGIN
__weak NewGroupViewController *weakSelf = self; __weak NewGroupViewController *weakSelf = self;
ContactsViewHelper *helper = self.contactsViewHelper; ContactsViewHelper *helper = self.contactsViewHelper;
NSArray<ContactAccount *> *allRecipientContactAccounts = self.contactsViewHelper.allRecipientContactAccounts; NSArray<SignalAccount *> *signalAccounts = self.contactsViewHelper.signalAccounts;
NSMutableSet *nonContactMemberRecipientIds = [self.memberRecipientIds mutableCopy]; NSMutableSet *nonContactMemberRecipientIds = [self.memberRecipientIds mutableCopy];
for (ContactAccount *contactAccount in allRecipientContactAccounts) { for (SignalAccount *signalAccount in signalAccounts) {
[nonContactMemberRecipientIds removeObject:contactAccount.recipientId]; [nonContactMemberRecipientIds removeObject:signalAccount.recipientId];
} }
// Non-contact Members // Non-contact Members
if (nonContactMemberRecipientIds.count > 0 || allRecipientContactAccounts.count < 1) { if (nonContactMemberRecipientIds.count > 0 || signalAccounts.count < 1) {
OWSTableSection *nonContactsSection = [OWSTableSection new]; OWSTableSection *nonContactsSection = [OWSTableSection new];
nonContactsSection.headerTitle = NSLocalizedString( nonContactsSection.headerTitle = NSLocalizedString(
@ -212,7 +212,7 @@ NS_ASSUME_NONNULL_BEGIN
} }
ContactTableViewCell *cell = [ContactTableViewCell new]; ContactTableViewCell *cell = [ContactTableViewCell new];
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId]; SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
BOOL isCurrentMember = [weakSelf.memberRecipientIds containsObject:recipientId]; BOOL isCurrentMember = [weakSelf.memberRecipientIds containsObject:recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:recipientId]; BOOL isBlocked = [helper isRecipientIdBlocked:recipientId];
if (isCurrentMember) { if (isCurrentMember) {
@ -226,8 +226,8 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(cell.accessoryMessage == nil); OWSAssert(cell.accessoryMessage == nil);
} }
if (contactAccount) { if (signalAccount) {
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; [cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
} else { } else {
[cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager]; [cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager];
} }
@ -236,15 +236,15 @@ NS_ASSUME_NONNULL_BEGIN
} }
customRowHeight:[ContactTableViewCell rowHeight] customRowHeight:[ContactTableViewCell rowHeight]
actionBlock:^{ actionBlock:^{
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId]; SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
if (contactAccount) { if (signalAccount) {
[weakSelf.groupViewHelper [weakSelf.groupViewHelper
showRemoveFromGroupAlertForContactAccount:contactAccount showRemoveFromGroupAlertForSignalAccount:signalAccount
fromViewController:weakSelf fromViewController:weakSelf
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
successBlock:^{ successBlock:^{
[weakSelf removeContactAccount:contactAccount]; [weakSelf removeSignalAccount:signalAccount];
}]; }];
} else { } else {
[weakSelf.groupViewHelper [weakSelf.groupViewHelper
showRemoveFromGroupAlertForRecipientId:recipientId showRemoveFromGroupAlertForRecipientId:recipientId
@ -261,18 +261,18 @@ NS_ASSUME_NONNULL_BEGIN
// Contacts // Contacts
OWSTableSection *contactAccountSection = [OWSTableSection new]; OWSTableSection *signalAccountSection = [OWSTableSection new];
contactAccountSection.headerTitle = NSLocalizedString( signalAccountSection.headerTitle = NSLocalizedString(
@"EDIT_GROUP_CONTACTS_SECTION_TITLE", @"a title for the contacts section of the 'new/update group' view."); @"EDIT_GROUP_CONTACTS_SECTION_TITLE", @"a title for the contacts section of the 'new/update group' view.");
if (allRecipientContactAccounts.count > 0) { if (signalAccounts.count > 0) {
if (nonContactMemberRecipientIds.count < 1) { if (nonContactMemberRecipientIds.count < 1) {
// We always want to offer a way to add non-contacts. // We always want to offer a way to add non-contacts.
[contactAccountSection addItem:[self createAddNonContactItem]]; [signalAccountSection addItem:[self createAddNonContactItem]];
} }
for (ContactAccount *contactAccount in allRecipientContactAccounts) { for (SignalAccount *signalAccount in signalAccounts) {
[contactAccountSection [signalAccountSection
addItem:[OWSTableItem itemWithCustomCellBlock:^{ addItem:[OWSTableItem itemWithCustomCellBlock:^{
NewGroupViewController *strongSelf = weakSelf; NewGroupViewController *strongSelf = weakSelf;
if (!strongSelf) { if (!strongSelf) {
@ -281,7 +281,7 @@ NS_ASSUME_NONNULL_BEGIN
ContactTableViewCell *cell = [ContactTableViewCell new]; ContactTableViewCell *cell = [ContactTableViewCell new];
NSString *recipientId = contactAccount.recipientId; NSString *recipientId = signalAccount.recipientId;
BOOL isCurrentMember = [weakSelf.memberRecipientIds containsObject:recipientId]; BOOL isCurrentMember = [weakSelf.memberRecipientIds containsObject:recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:recipientId]; BOOL isBlocked = [helper isRecipientIdBlocked:recipientId];
if (isCurrentMember) { if (isCurrentMember) {
@ -295,29 +295,29 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(cell.accessoryMessage == nil); OWSAssert(cell.accessoryMessage == nil);
} }
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; [cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
return cell; return cell;
} }
customRowHeight:[ContactTableViewCell rowHeight] customRowHeight:[ContactTableViewCell rowHeight]
actionBlock:^{ actionBlock:^{
NSString *recipientId = contactAccount.recipientId; NSString *recipientId = signalAccount.recipientId;
BOOL isCurrentMember = [weakSelf.memberRecipientIds containsObject:recipientId]; BOOL isCurrentMember = [weakSelf.memberRecipientIds containsObject:recipientId];
if (isCurrentMember) { if (isCurrentMember) {
[weakSelf.groupViewHelper [weakSelf.groupViewHelper
showRemoveFromGroupAlertForContactAccount:contactAccount showRemoveFromGroupAlertForSignalAccount:signalAccount
fromViewController:weakSelf fromViewController:weakSelf
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
successBlock:^{ successBlock:^{
[weakSelf removeContactAccount:contactAccount]; [weakSelf removeSignalAccount:signalAccount];
}]; }];
} else { } else {
[weakSelf addRecipientId:recipientId]; [weakSelf addRecipientId:recipientId];
} }
}]]; }]];
} }
} else { } else {
[contactAccountSection addItem:[OWSTableItem itemWithCustomCellBlock:^{ [signalAccountSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
UITableViewCell *cell = [UITableViewCell new]; UITableViewCell *cell = [UITableViewCell new];
cell.textLabel.text = NSLocalizedString( cell.textLabel.text = NSLocalizedString(
@"SETTINGS_BLOCK_LIST_NO_CONTACTS", @"A label that indicates the user has no Signal contacts."); @"SETTINGS_BLOCK_LIST_NO_CONTACTS", @"A label that indicates the user has no Signal contacts.");
@ -326,9 +326,9 @@ NS_ASSUME_NONNULL_BEGIN
cell.textLabel.textAlignment = NSTextAlignmentCenter; cell.textLabel.textAlignment = NSTextAlignmentCenter;
return cell; return cell;
} }
actionBlock:nil]]; actionBlock:nil]];
} }
[contents addSection:contactAccountSection]; [contents addSection:signalAccountSection];
self.tableViewController.contents = contents; self.tableViewController.contents = contents;
} }
@ -354,11 +354,11 @@ NS_ASSUME_NONNULL_BEGIN
}]; }];
} }
- (void)removeContactAccount:(ContactAccount *)contactAccount - (void)removeSignalAccount:(SignalAccount *)signalAccount
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
[self.memberRecipientIds removeObject:contactAccount.recipientId]; [self.memberRecipientIds removeObject:signalAccount.recipientId];
[self updateTableContents]; [self updateTableContents];
} }

View file

@ -4,7 +4,7 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@class ContactAccount; @class SignalAccount;
@protocol SelectRecipientViewControllerDelegate <NSObject> @protocol SelectRecipientViewControllerDelegate <NSObject>
@ -14,7 +14,7 @@
- (void)phoneNumberWasSelected:(NSString *)phoneNumber; - (void)phoneNumberWasSelected:(NSString *)phoneNumber;
- (void)contactAccountWasSelected:(ContactAccount *)contactAccount; - (void)signalAccountWasSelected:(SignalAccount *)signalAccount;
- (BOOL)shouldHideLocalNumber; - (BOOL)shouldHideLocalNumber;

View file

@ -3,7 +3,6 @@
// //
#import "SelectRecipientViewController.h" #import "SelectRecipientViewController.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h" #import "ContactTableViewCell.h"
#import "ContactsViewHelper.h" #import "ContactsViewHelper.h"
#import "CountryCodeViewController.h" #import "CountryCodeViewController.h"
@ -12,6 +11,7 @@
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "OWSTableViewController.h" #import "OWSTableViewController.h"
#import "PhoneNumber.h" #import "PhoneNumber.h"
#import "SignalAccount.h"
#import "StringUtil.h" #import "StringUtil.h"
#import "UIFont+OWS.h" #import "UIFont+OWS.h"
#import "UIUtil.h" #import "UIUtil.h"
@ -455,8 +455,8 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien
if (![self.delegate shouldHideContacts]) { if (![self.delegate shouldHideContacts]) {
OWSTableSection *contactsSection = [OWSTableSection new]; OWSTableSection *contactsSection = [OWSTableSection new];
contactsSection.headerTitle = [self.delegate contactsSectionTitle]; contactsSection.headerTitle = [self.delegate contactsSectionTitle];
NSArray<ContactAccount *> *allRecipientContactAccounts = helper.allRecipientContactAccounts; NSArray<SignalAccount *> *signalAccounts = helper.signalAccounts;
if (allRecipientContactAccounts.count == 0) { if (signalAccounts.count == 0) {
// No Contacts // No Contacts
[contactsSection addItem:[OWSTableItem itemWithCustomCellBlock:^{ [contactsSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
@ -473,7 +473,7 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien
} else { } else {
// Contacts // Contacts
for (ContactAccount *contactAccount in allRecipientContactAccounts) { for (SignalAccount *signalAccount in signalAccounts) {
[contactsSection addItem:[OWSTableItem itemWithCustomCellBlock:^{ [contactsSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
SelectRecipientViewController *strongSelf = weakSelf; SelectRecipientViewController *strongSelf = weakSelf;
if (!strongSelf) { if (!strongSelf) {
@ -481,19 +481,19 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien
} }
ContactTableViewCell *cell = [ContactTableViewCell new]; ContactTableViewCell *cell = [ContactTableViewCell new];
BOOL isBlocked = [helper isRecipientIdBlocked:contactAccount.recipientId]; BOOL isBlocked = [helper isRecipientIdBlocked:signalAccount.recipientId];
if (isBlocked) { if (isBlocked) {
cell.accessoryMessage = NSLocalizedString( cell.accessoryMessage = NSLocalizedString(
@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked."); @"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked.");
} else { } else {
OWSAssert(cell.accessoryMessage == nil); OWSAssert(cell.accessoryMessage == nil);
} }
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; [cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
return cell; return cell;
} }
customRowHeight:[ContactTableViewCell rowHeight] customRowHeight:[ContactTableViewCell rowHeight]
actionBlock:^{ actionBlock:^{
[weakSelf.delegate contactAccountWasSelected:contactAccount]; [weakSelf.delegate signalAccountWasSelected:signalAccount];
}]]; }]];
} }
} }

View file

@ -4,7 +4,6 @@
#import "SelectThreadViewController.h" #import "SelectThreadViewController.h"
#import "BlockListUIUtils.h" #import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h" #import "ContactTableViewCell.h"
#import "ContactsViewHelper.h" #import "ContactsViewHelper.h"
#import "Environment.h" #import "Environment.h"
@ -12,6 +11,7 @@
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "OWSContactsSearcher.h" #import "OWSContactsSearcher.h"
#import "OWSTableViewController.h" #import "OWSTableViewController.h"
#import "SignalAccount.h"
#import "ThreadViewHelper.h" #import "ThreadViewHelper.h"
#import "UIColor+OWS.h" #import "UIColor+OWS.h"
#import "UIFont+OWS.h" #import "UIFont+OWS.h"
@ -153,8 +153,8 @@ NS_ASSUME_NONNULL_BEGIN
} }
// Contacts // Contacts
NSArray<ContactAccount *> *filteredContactAccounts = [self filteredContactAccountsWithSearchText]; NSArray<SignalAccount *> *filteredSignalAccounts = [self filteredSignalAccountsWithSearchText];
for (ContactAccount *contactAccount in filteredContactAccounts) { for (SignalAccount *signalAccount in filteredSignalAccounts) {
[section addItem:[OWSTableItem itemWithCustomCellBlock:^{ [section addItem:[OWSTableItem itemWithCustomCellBlock:^{
SelectThreadViewController *strongSelf = weakSelf; SelectThreadViewController *strongSelf = weakSelf;
if (!strongSelf) { if (!strongSelf) {
@ -162,19 +162,19 @@ NS_ASSUME_NONNULL_BEGIN
} }
ContactTableViewCell *cell = [ContactTableViewCell new]; ContactTableViewCell *cell = [ContactTableViewCell new];
BOOL isBlocked = [helper isRecipientIdBlocked:contactAccount.recipientId]; BOOL isBlocked = [helper isRecipientIdBlocked:signalAccount.recipientId];
if (isBlocked) { if (isBlocked) {
cell.accessoryMessage cell.accessoryMessage
= NSLocalizedString(@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked."); = NSLocalizedString(@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked.");
} else { } else {
OWSAssert(cell.accessoryMessage == nil); OWSAssert(cell.accessoryMessage == nil);
} }
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; [cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
return cell; return cell;
} }
customRowHeight:[ContactTableViewCell rowHeight] customRowHeight:[ContactTableViewCell rowHeight]
actionBlock:^{ actionBlock:^{
[weakSelf contactAccountWasSelected:contactAccount]; [weakSelf signalAccountWasSelected:signalAccount];
}]]; }]];
} }
@ -195,31 +195,31 @@ NS_ASSUME_NONNULL_BEGIN
self.tableViewController.contents = contents; self.tableViewController.contents = contents;
} }
- (void)contactAccountWasSelected:(ContactAccount *)contactAccount - (void)signalAccountWasSelected:(SignalAccount *)signalAccount
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
OWSAssert(self.delegate); OWSAssert(self.delegate);
ContactsViewHelper *helper = self.contactsViewHelper; ContactsViewHelper *helper = self.contactsViewHelper;
if ([helper isRecipientIdBlocked:contactAccount.recipientId] && ![self.delegate canSelectBlockedContact]) { if ([helper isRecipientIdBlocked:signalAccount.recipientId] && ![self.delegate canSelectBlockedContact]) {
__weak SelectThreadViewController *weakSelf = self; __weak SelectThreadViewController *weakSelf = self;
[BlockListUIUtils showUnblockContactAccountActionSheet:contactAccount [BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self fromViewController:self
blockingManager:helper.blockingManager blockingManager:helper.blockingManager
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) { completionBlock:^(BOOL isBlocked) {
if (!isBlocked) { if (!isBlocked) {
[weakSelf contactAccountWasSelected:contactAccount]; [weakSelf signalAccountWasSelected:signalAccount];
} }
}]; }];
return; return;
} }
__block TSThread *thread = nil; __block TSThread *thread = nil;
[[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
thread = [TSContactThread getOrCreateThreadWithContactId:contactAccount.recipientId transaction:transaction]; thread = [TSContactThread getOrCreateThreadWithContactId:signalAccount.recipientId transaction:transaction];
}]; }];
OWSAssert(thread); OWSAssert(thread);
@ -255,8 +255,7 @@ NS_ASSUME_NONNULL_BEGIN
return result; return result;
} }
// TODO: Move this to contacts view helper. - (NSArray<SignalAccount *> *)filteredSignalAccountsWithSearchText
- (NSArray<ContactAccount *> *)filteredContactAccountsWithSearchText
{ {
// We don't want to show a 1:1 thread with Alice and Alice's contact, // We don't want to show a 1:1 thread with Alice and Alice's contact,
// so we de-duplicate by recipientId. // so we de-duplicate by recipientId.
@ -272,10 +271,10 @@ NS_ASSUME_NONNULL_BEGIN
NSString *searchString = [self.searchBar text]; NSString *searchString = [self.searchBar text];
ContactsViewHelper *helper = self.contactsViewHelper; ContactsViewHelper *helper = self.contactsViewHelper;
return [[helper contactAccountsMatchingSearchString:searchString] return [[helper signalAccountsMatchingSearchString:searchString]
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(ContactAccount *contactAccount, filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SignalAccount *signalAccount,
NSDictionary<NSString *, id> *_Nullable bindings) { NSDictionary<NSString *, id> *_Nullable bindings) {
return ![contactIdsToIgnore containsObject:contactAccount.recipientId]; return ![contactIdsToIgnore containsObject:signalAccount.recipientId];
}]]; }]];
} }

View file

@ -4,11 +4,11 @@
#import "ShowGroupMembersViewController.h" #import "ShowGroupMembersViewController.h"
#import "BlockListUIUtils.h" #import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h" #import "ContactTableViewCell.h"
#import "ContactsViewHelper.h" #import "ContactsViewHelper.h"
#import "Environment.h" #import "Environment.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "SignalAccount.h"
#import "SignalsViewController.h" #import "SignalsViewController.h"
#import "UIUtil.h" #import "UIUtil.h"
#import <AddressBookUI/AddressBookUI.h> #import <AddressBookUI/AddressBookUI.h>
@ -108,15 +108,15 @@ NS_ASSUME_NONNULL_BEGIN
} }
ContactTableViewCell *cell = [ContactTableViewCell new]; ContactTableViewCell *cell = [ContactTableViewCell new];
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId]; SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:recipientId]; BOOL isBlocked = [helper isRecipientIdBlocked:recipientId];
if (isBlocked) { if (isBlocked) {
cell.accessoryMessage cell.accessoryMessage
= NSLocalizedString(@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked."); = NSLocalizedString(@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked.");
} }
if (contactAccount) { if (signalAccount) {
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; [cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
} else { } else {
[cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager]; [cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager];
} }
@ -138,7 +138,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(recipientId.length > 0); OWSAssert(recipientId.length > 0);
ContactsViewHelper *helper = self.contactsViewHelper; ContactsViewHelper *helper = self.contactsViewHelper;
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId]; SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
UIAlertController *actionSheetController = UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
@ -152,8 +152,8 @@ NS_ASSUME_NONNULL_BEGIN
}]]; }]];
BOOL isBlocked; BOOL isBlocked;
if (contactAccount) { if (signalAccount) {
isBlocked = [helper isRecipientIdBlocked:contactAccount.recipientId]; isBlocked = [helper isRecipientIdBlocked:signalAccount.recipientId];
if (isBlocked) { if (isBlocked) {
[actionSheetController [actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BLOCK_LIST_UNBLOCK_BUTTON", addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BLOCK_LIST_UNBLOCK_BUTTON",
@ -161,11 +161,11 @@ NS_ASSUME_NONNULL_BEGIN
style:UIAlertActionStyleDefault style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) { handler:^(UIAlertAction *_Nonnull action) {
[BlockListUIUtils [BlockListUIUtils
showUnblockContactAccountActionSheet:contactAccount showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self fromViewController:self
blockingManager:helper.blockingManager blockingManager:helper.blockingManager
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
completionBlock:nil]; completionBlock:nil];
}]]; }]];
} else { } else {
[actionSheetController [actionSheetController
@ -174,11 +174,11 @@ NS_ASSUME_NONNULL_BEGIN
style:UIAlertActionStyleDestructive style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) { handler:^(UIAlertAction *_Nonnull action) {
[BlockListUIUtils [BlockListUIUtils
showBlockContactAccountActionSheet:contactAccount showBlockSignalAccountActionSheet:signalAccount
fromViewController:self fromViewController:self
blockingManager:helper.blockingManager blockingManager:helper.blockingManager
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
completionBlock:nil]; completionBlock:nil];
}]]; }]];
} }
} else { } else {
@ -242,14 +242,14 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(recipientId.length > 0); OWSAssert(recipientId.length > 0);
ContactsViewHelper *helper = self.contactsViewHelper; ContactsViewHelper *helper = self.contactsViewHelper;
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId]; SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
if (contactAccount) { if (signalAccount) {
ABPersonViewController *view = [[ABPersonViewController alloc] init]; ABPersonViewController *view = [[ABPersonViewController alloc] init];
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil); ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil);
// Assume person is already defined. // Assume person is already defined.
view.displayedPerson = ABAddressBookGetPersonWithRecordID(addressBookRef, contactAccount.contact.recordID); view.displayedPerson = ABAddressBookGetPersonWithRecordID(addressBookRef, signalAccount.contact.recordID);
view.allowsActions = NO; view.allowsActions = NO;
view.allowsEditing = YES; view.allowsEditing = YES;

View file

@ -0,0 +1,38 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
@class Contact;
@class SignalRecipient;
// This class represents a single valid Signal account.
//
// * Contacts with multiple signal accounts will correspond to
// multiple instances of SignalAccount.
// * For non-contacts, the contact property will be nil.
//
// New instances of SignalAccount for active accounts are
// created every time we do a contacts intersection (e.g.
// in response to a
@interface SignalAccount : NSObject
@property (nonatomic) SignalRecipient *signalRecipient;
// An E164 value identifying the signal account.
@property (nonatomic, readonly) NSString *recipientId;
// This property is optional and will not be set for
// non-contact account.
@property (nonatomic, nullable) Contact *contact;
@property (nonatomic) BOOL isMultipleAccountContact;
// For contacts with more than one signal account,
// this is a label for the account.
@property (nonatomic) NSString *multipleAccountLabel;
@end
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,21 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "SignalAccount.h"
#import <SignalServiceKit/SignalRecipient.h>
NS_ASSUME_NONNULL_BEGIN
@implementation SignalAccount
- (NSString *)recipientId
{
OWSAssert(self.signalRecipient);
return self.signalRecipient.uniqueId;
}
@end
NS_ASSUME_NONNULL_END

View file

@ -5,7 +5,6 @@
#import "UpdateGroupViewController.h" #import "UpdateGroupViewController.h"
#import "AddToGroupViewController.h" #import "AddToGroupViewController.h"
#import "BlockListUIUtils.h" #import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h" #import "ContactTableViewCell.h"
#import "ContactsViewHelper.h" #import "ContactsViewHelper.h"
#import "Environment.h" #import "Environment.h"
@ -14,6 +13,7 @@
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "OWSTableViewController.h" #import "OWSTableViewController.h"
#import "SecurityUtils.h" #import "SecurityUtils.h"
#import "SignalAccount.h"
#import "SignalKeyingStorage.h" #import "SignalKeyingStorage.h"
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
#import "UIUtil.h" #import "UIUtil.h"
@ -245,7 +245,7 @@ NS_ASSUME_NONNULL_BEGIN
} }
ContactTableViewCell *cell = [ContactTableViewCell new]; ContactTableViewCell *cell = [ContactTableViewCell new];
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId]; SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
BOOL isPreviousMember = [strongSelf.previousMemberRecipientIds containsObject:recipientId]; BOOL isPreviousMember = [strongSelf.previousMemberRecipientIds containsObject:recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:recipientId]; BOOL isBlocked = [helper isRecipientIdBlocked:recipientId];
if (isPreviousMember) { if (isPreviousMember) {
@ -264,8 +264,8 @@ NS_ASSUME_NONNULL_BEGIN
@"EDIT_GROUP_NEW_MEMBER_LABEL", @"An indicator that a user is a new member of the group."); @"EDIT_GROUP_NEW_MEMBER_LABEL", @"An indicator that a user is a new member of the group.");
} }
if (contactAccount) { if (signalAccount) {
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager]; [cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
} else { } else {
[cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager]; [cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager];
} }
@ -274,26 +274,26 @@ NS_ASSUME_NONNULL_BEGIN
} }
customRowHeight:[ContactTableViewCell rowHeight] customRowHeight:[ContactTableViewCell rowHeight]
actionBlock:^{ actionBlock:^{
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId]; SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
BOOL isPreviousMember = [weakSelf.previousMemberRecipientIds containsObject:recipientId]; BOOL isPreviousMember = [weakSelf.previousMemberRecipientIds containsObject:recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:recipientId]; BOOL isBlocked = [helper isRecipientIdBlocked:recipientId];
if (isPreviousMember) { if (isPreviousMember) {
if (isBlocked) { if (isBlocked) {
if (contactAccount) { if (signalAccount) {
[weakSelf showUnblockAlertForContactAccount:contactAccount]; [weakSelf showUnblockAlertForSignalAccount:signalAccount];
} else { } else {
[weakSelf showUnblockAlertForRecipientId:recipientId]; [weakSelf showUnblockAlertForRecipientId:recipientId];
} }
} }
} else { } else {
if (contactAccount) { if (signalAccount) {
[weakSelf.groupViewHelper [weakSelf.groupViewHelper
showRemoveFromGroupAlertForContactAccount:contactAccount showRemoveFromGroupAlertForSignalAccount:signalAccount
fromViewController:weakSelf fromViewController:weakSelf
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
successBlock:^{ successBlock:^{
[weakSelf removeContactAccount:contactAccount]; [weakSelf removeSignalAccount:signalAccount];
}]; }];
} else { } else {
[weakSelf.groupViewHelper [weakSelf.groupViewHelper
showRemoveFromGroupAlertForRecipientId:recipientId showRemoveFromGroupAlertForRecipientId:recipientId
@ -311,21 +311,21 @@ NS_ASSUME_NONNULL_BEGIN
self.tableViewController.contents = contents; self.tableViewController.contents = contents;
} }
- (void)showUnblockAlertForContactAccount:(ContactAccount *)contactAccount - (void)showUnblockAlertForSignalAccount:(SignalAccount *)signalAccount
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
__weak UpdateGroupViewController *weakSelf = self; __weak UpdateGroupViewController *weakSelf = self;
ContactsViewHelper *helper = self.contactsViewHelper; ContactsViewHelper *helper = self.contactsViewHelper;
[BlockListUIUtils showUnblockContactAccountActionSheet:contactAccount [BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self fromViewController:self
blockingManager:helper.blockingManager blockingManager:helper.blockingManager
contactsManager:helper.contactsManager contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) { completionBlock:^(BOOL isBlocked) {
if (!isBlocked) { if (!isBlocked) {
[weakSelf updateTableContents]; [weakSelf updateTableContents];
} }
}]; }];
} }
- (void)showUnblockAlertForRecipientId:(NSString *)recipientId - (void)showUnblockAlertForRecipientId:(NSString *)recipientId
@ -345,11 +345,11 @@ NS_ASSUME_NONNULL_BEGIN
}]; }];
} }
- (void)removeContactAccount:(ContactAccount *)contactAccount - (void)removeSignalAccount:(SignalAccount *)signalAccount
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
[self.memberRecipientIds removeObject:contactAccount.recipientId]; [self.memberRecipientIds removeObject:signalAccount.recipientId];
[self updateTableContents]; [self updateTableContents];
} }

View file

@ -498,7 +498,7 @@ protocol CallServiceObserver: class {
// For contacts not stored in our system contacts, we assume they are an unknown caller, and we force // For contacts not stored in our system contacts, we assume they are an unknown caller, and we force
// a TURN connection, so as not to reveal any connectivity information (IP/port) to the caller. // a TURN connection, so as not to reveal any connectivity information (IP/port) to the caller.
let unknownCaller = self.contactsManager.contact(forPhoneIdentifier: thread.contactIdentifier()) == nil let unknownCaller = self.contactsManager.signalAccount(forRecipientId: thread.contactIdentifier()) == nil
let useTurnOnly = unknownCaller || Environment.getCurrent().preferences.doCallsHideIPAddress() let useTurnOnly = unknownCaller || Environment.getCurrent().preferences.doCallsHideIPAddress()

View file

@ -1,24 +0,0 @@
//
// GroupContactsResult.h
// Signal
//
// Created by Frederic Jacobs on 17/02/15.
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
@class Contact;
@interface GroupContactsResult : NSObject
- (instancetype)initWithMembersId:(NSArray *)memberIdentifiers without:(NSArray *)removeIds;
- (NSUInteger)numberOfMembers;
- (BOOL)isContactAtIndexPath:(NSIndexPath *)indexPath;
- (Contact *)contactForIndexPath:(NSIndexPath *)indexPath;
- (NSString *)identifierForIndexPath:(NSIndexPath *)indexPath;
@end

View file

@ -1,133 +0,0 @@
//
// GroupContactsResult.m
// Signal
//
// Created by Frederic Jacobs on 17/02/15.
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
//
#import "GroupContactsResult.h"
#import <SignalServiceKit/TSAccountManager.h>
#import "Contact.h"
#import "OWSContactsManager.h"
#import "Environment.h"
#import "SignalKeyingStorage.h"
@interface GroupContactsResult ()
@property NSMutableArray *unknownNumbers;
@property NSMutableArray *knownNumbers;
@property NSMutableDictionary *associatedContactDict;
@end
@implementation GroupContactsResult
- (instancetype)initWithMembersId:(NSArray *)memberIdentifiers without:(NSArray *)removeIds {
self = [super init];
OWSContactsManager *manager = [Environment.getCurrent contactsManager];
NSMutableSet *remainingNumbers = [NSMutableSet setWithArray:memberIdentifiers];
NSMutableArray *knownNumbers = [NSMutableArray array];
NSMutableArray *associatedContacts = [NSMutableArray array];
for (NSString *identifier in memberIdentifiers) {
if ([identifier isEqualToString:[TSAccountManager localNumber]]) {
// remove local number
[remainingNumbers removeObject:identifier];
continue;
}
if (removeIds && [removeIds containsObject:identifier]) {
// Remove ids
[remainingNumbers removeObject:identifier];
continue;
}
PhoneNumber *number = [PhoneNumber phoneNumberFromE164:identifier];
if (!number) {
continue;
}
Contact *contact = [manager latestContactForPhoneNumber:number];
if (!contact) {
continue;
}
[knownNumbers addObject:identifier];
[associatedContacts addObject:contact];
[remainingNumbers removeObject:identifier];
}
_unknownNumbers = [NSMutableArray arrayWithArray:[remainingNumbers allObjects]];
[_unknownNumbers sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:0];
}];
// Populate mapping dictionary.
_associatedContactDict = [NSMutableDictionary dictionary];
for (NSUInteger i = 0; i < [knownNumbers count]; i++) {
NSString *identifier = [knownNumbers objectAtIndex:i];
Contact *contact = [associatedContacts objectAtIndex:i];
[_associatedContactDict setObject:contact forKey:identifier];
}
// Known Numbers
_knownNumbers = [NSMutableArray arrayWithArray:knownNumbers];
[_knownNumbers sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
Contact *contact1 = [_associatedContactDict objectForKey:obj1];
Contact *contact2 = [_associatedContactDict objectForKey:obj2];
return [[manager class] contactComparator](contact1, contact2);
}];
return self;
}
- (NSUInteger)numberOfMembers {
return [self.knownNumbers count] + [self.unknownNumbers count];
}
- (BOOL)isContactAtIndexPath:(NSIndexPath *)indexPath {
if ((NSUInteger)indexPath.row < [self.unknownNumbers count]) {
return NO;
} else {
return YES;
}
}
- (Contact *)contactForIndexPath:(NSIndexPath *)indexPath {
if ([self isContactAtIndexPath:indexPath]) {
NSString *identifier = [_knownNumbers objectAtIndex:[self knownNumbersIndexForIndexPath:indexPath]];
return [_associatedContactDict objectForKey:identifier];
} else {
NSAssert(NO, @"Trying to retrieve contact from array at an index that is not a contact.");
return nil;
}
}
- (NSString *)identifierForIndexPath:(NSIndexPath *)indexPath {
if ([self isContactAtIndexPath:indexPath]) {
return [_knownNumbers objectAtIndex:[self knownNumbersIndexForIndexPath:indexPath]];
} else {
return [_unknownNumbers objectAtIndex:(NSUInteger)indexPath.row];
}
}
- (NSUInteger)knownNumbersIndexForIndexPath:(NSIndexPath *)indexPath {
NSAssert(((NSUInteger)indexPath.row >= [_unknownNumbers count]), @"Wrong index for known number");
return (NSUInteger)indexPath.row - [_unknownNumbers count];
}
@end

View file

@ -12,38 +12,46 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification;
// TODO: Remove this.
// TODO: Remove observableContactsController.
extern NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification; extern NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification;
@class UIFont; @class UIFont;
@class ContactAccount; @class SignalAccount;
/** /**
* Get latest Signal contacts, and be notified when they change. * Get latest Signal contacts, and be notified when they change.
*/ */
@interface OWSContactsManager : NSObject <ContactsManagerProtocol> @interface OWSContactsManager : NSObject <ContactsManagerProtocol>
@property (nullable, strong) CNContactStore *contactStore; @property (nonnull, readonly) NSCache<NSString *, UIImage *> *avatarCache;
@property (nonnull, readonly, strong) NSCache<NSString *, UIImage *> *avatarCache;
// signalAccountMap and signalAccounts hold the same data.
// signalAccountMap is for lookup. signalAccounts contains the accounts
// ordered by display order.
@property (atomic, readonly) NSDictionary<NSString *, SignalAccount *> *signalAccountMap;
@property (atomic, readonly) NSArray<SignalAccount *> *signalAccounts;
- (nonnull ObservableValue *)getObservableContacts; - (nonnull ObservableValue *)getObservableContacts;
- (nullable Contact *)latestContactForPhoneNumber:(nullable PhoneNumber *)phoneNumber; - (nullable SignalAccount *)signalAccountForRecipientId:(nullable NSString *)recipientId;
- (nullable Contact *)contactForPhoneIdentifier:(nullable NSString *)identifier;
- (Contact *)getOrBuildContactForPhoneIdentifier:(NSString *)identifier; - (Contact *)getOrBuildContactForPhoneIdentifier:(NSString *)identifier;
- (void)verifyABPermission; - (void)verifyABPermission;
- (NSArray<Contact *> *)allContacts; // TODO: Remove this method.
- (NSArray<Contact *> *)signalContacts; - (NSArray<Contact *> *)signalContacts;
- (void)doAfterEnvironmentInitSetup; - (void)doAfterEnvironmentInitSetup;
- (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)identifier; - (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)identifier;
- (NSString *)displayNameForContact:(Contact *)contact; - (NSString *)displayNameForContact:(Contact *)contact;
- (NSString *_Nonnull)displayNameForContactAccount:(ContactAccount *)contactAccount; - (NSString *_Nonnull)displayNameForSignalAccount:(SignalAccount *)signalAccount;
- (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier; - (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier;
- (NSAttributedString *_Nonnull)formattedDisplayNameForContactAccount:(ContactAccount *)contactAccount - (NSAttributedString *_Nonnull)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount
font:(UIFont *_Nonnull)font; font:(UIFont *_Nonnull)font;
- (NSAttributedString *)formattedFullNameForContact:(Contact *)contact font:(UIFont *)font; - (NSAttributedString *)formattedFullNameForContact:(Contact *)contact font:(UIFont *)font;
- (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font; - (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font;

View file

@ -3,8 +3,8 @@
// //
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "ContactAccount.h"
#import "Environment.h" #import "Environment.h"
#import "SignalAccount.h"
#import "Util.h" #import "Util.h"
#import <SignalServiceKit/ContactsUpdater.h> #import <SignalServiceKit/ContactsUpdater.h>
#import <SignalServiceKit/OWSError.h> #import <SignalServiceKit/OWSError.h>
@ -13,25 +13,30 @@
typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL *); typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL *);
NSString *const OWSContactsManagerSignalAccountsDidChangeNotification =
@"OWSContactsManagerSignalAccountsDidChangeNotification";
NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification = NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification =
@"OWSContactsManagerSignalRecipientsDidChangeNotification"; @"OWSContactsManagerSignalRecipientsDidChangeNotification";
@interface OWSContactsManager () @interface OWSContactsManager ()
@property (atomic, nullable) CNContactStore *contactStore;
@property (atomic) id addressBookReference; @property (atomic) id addressBookReference;
@property (atomic) TOCFuture *futureAddressBook; @property (atomic) TOCFuture *futureAddressBook;
@property (atomic) ObservableValueController *observableContactsController; @property (atomic) ObservableValueController *observableContactsController;
@property (atomic) TOCCancelTokenSource *life; @property (atomic) TOCCancelTokenSource *life;
@property (atomic) NSDictionary *latestContactsById;
@property (atomic) NSDictionary<NSString *, Contact *> *contactMap;
@property (nonatomic) BOOL isContactsUpdateInFlight; @property (nonatomic) BOOL isContactsUpdateInFlight;
// This reflects the contents of the device phone book and includes
// contacts that do not correspond to any signal account.
@property (atomic) NSArray<Contact *> *allContacts;
@property (atomic) NSDictionary<NSString *, Contact *> *allContactsMap;
@property (atomic) NSArray<SignalAccount *> *signalAccounts;
@property (atomic) NSDictionary<NSString *, SignalAccount *> *signalAccountMap;
@end @end
@implementation OWSContactsManager @implementation OWSContactsManager
@synthesize latestContactsById = _latestContactsById;
- (void)dealloc { - (void)dealloc {
[_life cancel]; [_life cancel];
} }
@ -44,49 +49,16 @@ NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification =
_life = [TOCCancelTokenSource new]; _life = [TOCCancelTokenSource new];
_observableContactsController = [ObservableValueController observableValueControllerWithInitialValue:nil]; _observableContactsController = [ObservableValueController observableValueControllerWithInitialValue:nil];
_latestContactsById = @{};
_avatarCache = [NSCache new]; _avatarCache = [NSCache new];
_allContacts = @[];
_signalAccountMap = @{};
_signalAccounts = @[];
OWSSingletonAssert(); OWSSingletonAssert();
return self; return self;
} }
- (NSDictionary *)latestContactsById
{
@synchronized(self)
{
return _latestContactsById;
}
}
- (void)setLatestContactsById:(NSDictionary *)latestContactsById
{
@synchronized(self)
{
_latestContactsById = [latestContactsById copy];
NSMutableDictionary<NSString *, Contact *> *contactMap = [NSMutableDictionary new];
for (Contact *contact in _latestContactsById.allValues) {
// The allContacts method seems to protect against non-contact instances
// in latestContactsById, so I've done the same here. I'm not sure if
// this is a real issue.
OWSAssert([contact isKindOfClass:[Contact class]]);
if (![contact isKindOfClass:[Contact class]]) {
continue;
}
for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) {
NSString *phoneNumberE164 = phoneNumber.toE164;
if (phoneNumberE164.length > 0) {
contactMap[phoneNumberE164] = contact;
}
}
}
self.contactMap = contactMap;
}
}
- (void)doAfterEnvironmentInitSetup { - (void)doAfterEnvironmentInitSetup {
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(9, 0) && if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(9, 0) &&
!self.contactStore) { !self.contactStore) {
@ -106,7 +78,7 @@ NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification =
__weak OWSContactsManager *weakSelf = self; __weak OWSContactsManager *weakSelf = self;
[self.observableContactsController watchLatestValueOnArbitraryThread:^(NSArray *latestContacts) { [self.observableContactsController watchLatestValueOnArbitraryThread:^(NSArray *latestContacts) {
@synchronized(self) { @synchronized(self) {
[weakSelf setupLatestContacts:latestContacts]; [weakSelf updateSignalAccounts:latestContacts];
} }
} }
untilCancelled:_life.token]; untilCancelled:_life.token];
@ -227,10 +199,120 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
[self.observableContactsController updateValue:[self getContactsFromAddressBook:addressBookRef]]; [self.observableContactsController updateValue:[self getContactsFromAddressBook:addressBookRef]];
} }
- (void)setupLatestContacts:(NSArray *)contacts { - (void)updateSignalAccounts:(NSArray<Contact *> *)contacts
if (contacts) { {
self.latestContactsById = [OWSContactsManager keyContactsById:contacts]; // This will happen off of the main thread.
NSMutableDictionary<NSString *, SignalAccount *> *signalAccountMap = [NSMutableDictionary new];
NSMutableArray<SignalAccount *> *signalAccounts = [NSMutableArray new];
NSMutableDictionary<NSString *, Contact *> *allContactsMap = [NSMutableDictionary new];
for (Contact *contact in contacts) {
for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) {
NSString *phoneNumberE164 = phoneNumber.toE164;
if (phoneNumberE164.length > 0) {
allContactsMap[phoneNumberE164] = contact;
}
}
NSArray<SignalRecipient *> *signalRecipients = contact.signalRecipients;
for (SignalRecipient *signalRecipient in contact.signalRecipients) {
if (signalRecipients.count == 1) {
SignalAccount *signalAccount = [SignalAccount new];
signalAccount.signalRecipient = signalRecipient;
signalAccount.contact = contact;
signalAccountMap[signalAccount.recipientId] = signalAccount;
[signalAccounts addObject:signalAccount];
} else if (contact.textSecureIdentifiers.count > 1) {
for (NSString *recipientId in
[contact.textSecureIdentifiers sortedArrayUsingSelector:@selector(compare:)]) {
SignalAccount *signalAccount = [SignalAccount new];
signalAccount.signalRecipient = signalRecipient;
signalAccount.contact = contact;
signalAccount.isMultipleAccountContact = YES;
signalAccount.multipleAccountLabel =
[[self class] accountLabelForContact:contact recipientId:recipientId];
signalAccountMap[signalAccount.recipientId] = signalAccount;
[signalAccounts addObject:signalAccount];
}
}
}
} }
dispatch_async(dispatch_get_main_queue(), ^{
self.allContacts = contacts;
self.signalAccountMap = [signalAccountMap copy];
self.signalAccounts = [signalAccounts copy];
self.allContactsMap = [allContactsMap copy];
[[NSNotificationCenter defaultCenter] postNotificationName:OWSContactsManagerSignalAccountsDidChangeNotification
object:nil];
});
}
+ (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;
} }
+ (void)blockingContactDialog { + (void)blockingContactDialog {
@ -394,28 +476,6 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
andContactID:recordID]; andContactID:recordID];
} }
- (Contact * _Nullable)latestContactForPhoneNumber:(PhoneNumber *)phoneNumber {
NSArray *allContacts = [self allContacts];
ContactSearchBlock searchBlock = ^BOOL(Contact *contact, NSUInteger idx, BOOL *stop) {
for (PhoneNumber *number in contact.parsedPhoneNumbers) {
if ([self phoneNumber:number matchesNumber:phoneNumber]) {
*stop = YES;
return YES;
}
}
return NO;
};
NSUInteger contactIndex = [allContacts indexOfObjectPassingTest:searchBlock];
if (contactIndex != NSNotFound) {
return allContacts[contactIndex];
} else {
return nil;
}
}
- (BOOL)phoneNumber:(PhoneNumber *)phoneNumber1 matchesNumber:(PhoneNumber *)phoneNumber2 { - (BOOL)phoneNumber:(PhoneNumber *)phoneNumber1 matchesNumber:(PhoneNumber *)phoneNumber2 {
return [phoneNumber1.toE164 isEqualToString:phoneNumber2.toE164]; return [phoneNumber1.toE164 isEqualToString:phoneNumber2.toE164];
} }
@ -459,25 +519,6 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
} }
} }
+ (NSDictionary *)keyContactsById:(NSArray *)contacts {
return [contacts keyedBy:^id(Contact *contact) {
return @((int)contact.recordID);
}];
}
- (NSArray<Contact *> *_Nonnull)allContacts {
NSMutableArray *allContacts = [NSMutableArray array];
for (NSString *key in self.latestContactsById.allKeys) {
Contact *contact = [self.latestContactsById objectForKey:key];
if ([contact isKindOfClass:[Contact class]]) {
[allContacts addObject:contact];
}
}
return allContacts;
}
#pragma mark - Whisper User Management #pragma mark - Whisper User Management
- (NSArray *)getSignalUsersFromContactsArray:(NSArray *)contacts { - (NSArray *)getSignalUsersFromContactsArray:(NSArray *)contacts {
@ -511,10 +552,12 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
if (!identifier) { if (!identifier) {
return self.unknownContactName; return self.unknownContactName;
} }
Contact *contact = [self contactForPhoneIdentifier:identifier];
// TODO: There's some overlap here with displayNameForSignalAccount.
NSString *displayName = (contact.fullName.length > 0) ? contact.fullName : identifier; SignalAccount *signalAccount = [self signalAccountForRecipientId:identifier];
NSString *displayName = (signalAccount.contact.fullName.length > 0) ? signalAccount.contact.fullName : identifier;
return displayName; return displayName;
} }
@ -527,36 +570,36 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
return displayName; return displayName;
} }
- (NSString *_Nonnull)displayNameForContactAccount:(ContactAccount *)contactAccount - (NSString *_Nonnull)displayNameForSignalAccount:(SignalAccount *)signalAccount
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
NSString *baseName = (contactAccount.contact ? [self displayNameForContact:contactAccount.contact] NSString *baseName = (signalAccount.contact ? [self displayNameForContact:signalAccount.contact]
: [self displayNameForPhoneIdentifier:contactAccount.recipientId]); : [self displayNameForPhoneIdentifier:signalAccount.recipientId]);
OWSAssert(contactAccount.isMultipleAccountContact == (contactAccount.multipleAccountLabel != nil)); OWSAssert(signalAccount.isMultipleAccountContact == (signalAccount.multipleAccountLabel != nil));
if (contactAccount.multipleAccountLabel) { if (signalAccount.multipleAccountLabel) {
return [NSString stringWithFormat:@"%@ (%@)", baseName, contactAccount.multipleAccountLabel]; return [NSString stringWithFormat:@"%@ (%@)", baseName, signalAccount.multipleAccountLabel];
} else { } else {
return baseName; return baseName;
} }
} }
- (NSAttributedString *_Nonnull)formattedDisplayNameForContactAccount:(ContactAccount *)contactAccount - (NSAttributedString *_Nonnull)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount
font:(UIFont *_Nonnull)font font:(UIFont *_Nonnull)font
{ {
OWSAssert(contactAccount); OWSAssert(signalAccount);
OWSAssert(font); OWSAssert(font);
NSAttributedString *baseName = [self formattedFullNameForContact:contactAccount.contact font:font]; NSAttributedString *baseName = [self formattedFullNameForContact:signalAccount.contact font:font];
OWSAssert(contactAccount.isMultipleAccountContact == (contactAccount.multipleAccountLabel != nil)); OWSAssert(signalAccount.isMultipleAccountContact == (signalAccount.multipleAccountLabel != nil));
if (contactAccount.multipleAccountLabel) { if (signalAccount.multipleAccountLabel) {
NSMutableAttributedString *result = [NSMutableAttributedString new]; NSMutableAttributedString *result = [NSMutableAttributedString new];
[result appendAttributedString:baseName]; [result appendAttributedString:baseName];
[result appendAttributedString:[[NSAttributedString alloc] initWithString:@" (" [result appendAttributedString:[[NSAttributedString alloc] initWithString:@" ("
attributes:@{ attributes:@{
NSFontAttributeName : font, NSFontAttributeName : font,
}]]; }]];
[result appendAttributedString:[[NSAttributedString alloc] initWithString:contactAccount.multipleAccountLabel]]; [result appendAttributedString:[[NSAttributedString alloc] initWithString:signalAccount.multipleAccountLabel]];
[result appendAttributedString:[[NSAttributedString alloc] initWithString:@")" [result appendAttributedString:[[NSAttributedString alloc] initWithString:@")"
attributes:@{ attributes:@{
NSFontAttributeName : font, NSFontAttributeName : font,
@ -627,16 +670,16 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
attributes:normalFontAttributes]; attributes:normalFontAttributes];
} }
- (Contact * _Nullable)contactForPhoneIdentifier:(NSString * _Nullable)identifier { - (nullable SignalAccount *)signalAccountForRecipientId:(nullable NSString *)recipientId
if (!identifier) { {
return nil; OWSAssert(recipientId.length > 0);
}
return self.contactMap[identifier]; return self.signalAccountMap[recipientId];
} }
- (Contact *)getOrBuildContactForPhoneIdentifier:(NSString *)identifier - (Contact *)getOrBuildContactForPhoneIdentifier:(NSString *)identifier
{ {
Contact *savedContact = [self contactForPhoneIdentifier:identifier]; Contact *savedContact = self.allContactsMap[identifier];
if (savedContact) { if (savedContact) {
return savedContact; return savedContact;
} else { } else {
@ -649,9 +692,8 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
} }
} }
- (UIImage * _Nullable)imageForPhoneIdentifier:(NSString * _Nullable)identifier { - (UIImage * _Nullable)imageForPhoneIdentifier:(NSString * _Nullable)identifier {
Contact *contact = [self contactForPhoneIdentifier:identifier]; Contact *contact = self.allContactsMap[identifier];
return contact.image; return contact.image;
} }

View file

@ -89,8 +89,8 @@ NS_ASSUME_NONNULL_BEGIN
return; return;
} }
Contact *contact = [contactsManager contactForPhoneIdentifier:contactThread.contactIdentifier]; SignalAccount *signalAccount = [contactsManager signalAccountForRecipientId:contactThread.contactIdentifier];
if (contact) { if (signalAccount) {
// Only create block offers for non-contacts. // Only create block offers for non-contacts.
return; return;
} }

View file

@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
extern NSString *const kContactsTable_CellReuseIdentifier; extern NSString *const kContactsTable_CellReuseIdentifier;
@class OWSContactsManager; @class OWSContactsManager;
@class ContactAccount; @class SignalAccount;
@class TSThread; @class TSThread;
@interface ContactTableViewCell : UITableViewCell @interface ContactTableViewCell : UITableViewCell
@ -27,11 +27,10 @@ extern NSString *const kContactsTable_CellReuseIdentifier;
+ (CGFloat)rowHeight; + (CGFloat)rowHeight;
// TODO: Remove this method once "new 1:1 conversation" view is converted to use ContactAccounts. // TODO: Remove this method once "new 1:1 conversation" view is converted to use SignalAccounts.
- (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager; - (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager;
- (void)configureWithContactAccount:(ContactAccount *)contactAccount - (void)configureWithSignalAccount:(SignalAccount *)signalAccount contactsManager:(OWSContactsManager *)contactsManager;
contactsManager:(OWSContactsManager *)contactsManager;
- (void)configureWithRecipientId:(NSString *)recipientId contactsManager:(OWSContactsManager *)contactsManager; - (void)configureWithRecipientId:(NSString *)recipientId contactsManager:(OWSContactsManager *)contactsManager;

View file

@ -3,10 +3,10 @@
// //
#import "ContactTableViewCell.h" #import "ContactTableViewCell.h"
#import "ContactAccount.h"
#import "Environment.h" #import "Environment.h"
#import "OWSContactAvatarBuilder.h" #import "OWSContactAvatarBuilder.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "SignalAccount.h"
#import "UIFont+OWS.h" #import "UIFont+OWS.h"
#import "UIUtil.h" #import "UIUtil.h"
#import "UIView+OWS.h" #import "UIView+OWS.h"
@ -90,13 +90,12 @@ NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseI
contactsManager:contactsManager]; contactsManager:contactsManager];
} }
- (void)configureWithContactAccount:(ContactAccount *)contactAccount - (void)configureWithSignalAccount:(SignalAccount *)signalAccount contactsManager:(OWSContactsManager *)contactsManager
contactsManager:(OWSContactsManager *)contactsManager
{ {
[self configureWithRecipientId:contactAccount.recipientId [self configureWithRecipientId:signalAccount.recipientId
avatarName:contactAccount.contact.fullName avatarName:signalAccount.contact.fullName
displayName:[contactsManager formattedDisplayNameForContactAccount:contactAccount displayName:[contactsManager formattedDisplayNameForSignalAccount:signalAccount
font:self.nameLabel.font] font:self.nameLabel.font]
contactsManager:contactsManager]; contactsManager:contactsManager];
} }