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 */; };
3456710A1E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.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 */; };
34B3F8721E8DF1700035BE1A /* AdvancedSettingsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34B3F8371E8DF1700035BE1A /* AdvancedSettingsTableViewController.m */; };
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 */; };
34D5CCA91EAE3D30005515DB /* GroupViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 34D5CCA81EAE3D30005515DB /* GroupViewHelper.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 */; };
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.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>"; };
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>"; };
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>"; };
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>"; };
@ -467,8 +464,8 @@
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>"; };
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>"; };
34D5CCB31EAEA225005515DB /* ContactAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactAccount.m; sourceTree = "<group>"; };
34D5CCB21EAEA225005515DB /* SignalAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SignalAccount.h; 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>"; };
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>"; };
@ -878,8 +875,6 @@
34B3F83B1E8DF1700035BE1A /* CallViewController.swift */,
34B3F83C1E8DF1700035BE1A /* CodeVerificationViewController.h */,
34B3F83D1E8DF1700035BE1A /* CodeVerificationViewController.m */,
34D5CCB21EAEA225005515DB /* ContactAccount.h */,
34D5CCB31EAEA225005515DB /* ContactAccount.m */,
34B3F83E1E8DF1700035BE1A /* ContactsPicker.swift */,
34B3F83F1E8DF1700035BE1A /* ContactsPicker.xib */,
340CB2221EAC155C0001CAA1 /* ContactsViewHelper.h */,
@ -941,6 +936,8 @@
34B3F8691E8DF1700035BE1A /* SettingsTableViewController.m */,
34B3F86A1E8DF1700035BE1A /* ShowGroupMembersViewController.h */,
34B3F86B1E8DF1700035BE1A /* ShowGroupMembersViewController.m */,
34D5CCB21EAEA225005515DB /* SignalAccount.h */,
34D5CCB31EAEA225005515DB /* SignalAccount.m */,
34B3F86C1E8DF1700035BE1A /* SignalAttachment.swift */,
34B3F86D1E8DF1700035BE1A /* SignalsNavigationController.h */,
34B3F86E1E8DF1700035BE1A /* SignalsNavigationController.m */,
@ -1193,8 +1190,6 @@
76EB040318170B33006006FC /* contact */ = {
isa = PBXGroup;
children = (
34B3F8301E8DF11D0035BE1A /* GroupContactsResult.h */,
34B3F8311E8DF11D0035BE1A /* GroupContactsResult.m */,
76EB040818170B33006006FC /* OWSContactsManager.h */,
76EB040918170B33006006FC /* OWSContactsManager.m */,
45843D1D1D2236B30013E85A /* OWSContactsSearcher.h */,
@ -2040,7 +2035,7 @@
34D5CCB11EAE7E7F005515DB /* SelectRecipientViewController.m in Sources */,
34B3F88F1E8DF1710035BE1A /* RegistrationViewController.m in Sources */,
34B3F8901E8DF1710035BE1A /* SettingsTableViewController.m in Sources */,
34D5CCB41EAEA225005515DB /* ContactAccount.m in Sources */,
34D5CCB41EAEA225005515DB /* SignalAccount.m in Sources */,
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */,
343D3D9B1E9283F100165CA4 /* BlockListUIUtils.m in Sources */,
34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */,
@ -2076,7 +2071,6 @@
452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */,
452EA0971EA662330078744B /* AttachmentPointerAdapter.swift in Sources */,
34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */,
34B3F8321E8DF11D0035BE1A /* GroupContactsResult.m in Sources */,
45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */,
45666EC61D99483D008FE134 /* OWSAvatarBuilder.m in Sources */,
45E615161E8C590B0018AD52 /* DisplayableTextFilter.swift in Sources */,

View File

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

View File

@ -4,9 +4,9 @@
#import "AddToBlockListViewController.h"
#import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactsViewHelper.h"
#import "OWSContactsManager.h"
#import "SignalAccount.h"
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;
ContactsViewHelper *helper = self.contactsViewHelper;
if ([helper isRecipientIdBlocked:contactAccount.recipientId]) {
NSString *displayName = [helper.contactsManager displayNameForContactAccount:contactAccount];
if ([helper isRecipientIdBlocked:signalAccount.recipientId]) {
NSString *displayName = [helper.contactsManager displayNameForSignalAccount:signalAccount];
UIAlertController *controller = [UIAlertController
alertControllerWithTitle:NSLocalizedString(@"BLOCK_LIST_VIEW_ALREADY_BLOCKED_ALERT_TITLE",
@"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];
return;
}
[BlockListUIUtils showBlockContactAccountActionSheet:contactAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) {
if (isBlocked) {
[weakSelf.navigationController popViewControllerAnimated:YES];
}
}];
[BlockListUIUtils showBlockSignalAccountActionSheet:signalAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) {
if (isBlocked) {
[weakSelf.navigationController popViewControllerAnimated:YES];
}
}];
}
- (BOOL)shouldHideLocalNumber

View File

@ -4,9 +4,9 @@
#import "AddToGroupViewController.h"
#import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactsViewHelper.h"
#import "OWSContactsManager.h"
#import "SignalAccount.h"
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;
ContactsViewHelper *helper = self.contactsViewHelper;
if ([helper isRecipientIdBlocked:contactAccount.recipientId]) {
[BlockListUIUtils showUnblockContactAccountActionSheet:contactAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) {
if (isBlocked) {
[weakSelf addToGroup:contactAccount.recipientId];
}
}];
if ([helper isRecipientIdBlocked:signalAccount.recipientId]) {
[BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) {
if (isBlocked) {
[weakSelf addToGroup:signalAccount.recipientId];
}
}];
} else {
[self addToGroup:contactAccount.recipientId];
[self addToGroup:signalAccount.recipientId];
}
}

View File

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

View File

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

View File

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

View File

@ -5,69 +5,46 @@
#import "BlockListViewController.h"
#import "AddToBlockListViewController.h"
#import "BlockListUIUtils.h"
#import "ContactsViewHelper.h"
#import "Environment.h"
#import "OWSContactsManager.h"
#import "OWSTableViewController.h"
#import "PhoneNumber.h"
#import "UIFont+OWS.h"
#import "UIView+OWS.h"
#import <SignalServiceKit/OWSBlockingManager.h>
NS_ASSUME_NONNULL_BEGIN
@interface BlockListViewController ()
@interface BlockListViewController () <ContactsViewHelperDelegate>
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
@property (nonatomic, readonly) NSArray<NSString *> *blockedPhoneNumbers;
@property (nonatomic, readonly) ContactsViewHelper *contactsViewHelper;
@property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic) NSArray<Contact *> *contacts;
@property (nonatomic, readonly) OWSTableViewController *tableViewController;
@end
#pragma mark -
typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
BlockListViewControllerSection_Add,
BlockListViewControllerSection_BlockList,
BlockListViewControllerSection_Count // meta section
};
@implementation BlockListViewController
- (instancetype)init
{
return [super initWithStyle:UITableViewStyleGrouped];
}
- (void)loadView
{
[super loadView];
_blockingManager = [OWSBlockingManager sharedManager];
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
_contactsManager = [Environment getCurrent].contactsManager;
self.contacts = [self.contactsManager.signalContacts copy];
_contactsViewHelper = [ContactsViewHelper new];
_contactsViewHelper.delegate = self;
self.title
= 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
{
[[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];
[self updateTableContents];
}
- (void)viewDidLoad
@ -78,120 +55,75 @@ typedef NS_ENUM(NSInteger, BlockListViewControllerSection) {
#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
{
switch (section) {
case BlockListViewControllerSection_Add:
return 1;
case BlockListViewControllerSection_BlockList:
return (NSInteger) _blockedPhoneNumbers.count;
default:
OWSAssert(0);
return 0;
__weak BlockListViewController *weakSelf = self;
ContactsViewHelper *helper = self.contactsViewHelper;
// Add section
OWSTableSection *addSection = [OWSTableSection new];
addSection.footerTitle = NSLocalizedString(
@"BLOCK_BEHAVIOR_EXPLANATION", @"An explanation of the consequences of blocking another user.");
[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
{
switch (section) {
case BlockListViewControllerSection_Add:
return NSLocalizedString(@"BLOCK_BEHAVIOR_EXPLANATION",
@"An explanation of the consequences of blocking another user.");
default:
return nil;
}
}
// Blocklist section
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [UITableViewCell new];
OWSAssert(cell);
switch (indexPath.section) {
case BlockListViewControllerSection_Add:
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.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
break;
case BlockListViewControllerSection_BlockList: {
NSString *displayName = [self displayNameForIndexPath:indexPath];
OWSTableSection *blocklistSection = [OWSTableSection new];
NSArray<NSString *> *blockedPhoneNumbers =
[helper.blockedPhoneNumbers sortedArrayUsingSelector:@selector(compare:)];
for (NSString *phoneNumber in blockedPhoneNumbers) {
[blocklistSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
// TODO: Use ContactTableViewCell.
UITableViewCell *cell = [UITableViewCell new];
NSString *displayName = [helper.contactsManager displayNameForPhoneIdentifier:phoneNumber];
cell.textLabel.text = displayName;
cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
break;
cell.textLabel.textColor = [UIColor blackColor];
return cell;
}
default:
OWSAssert(0);
return 0;
actionBlock:^{
[BlockListUIUtils showUnblockPhoneNumberActionSheet:phoneNumber
fromViewController:weakSelf
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:nil];
}]];
}
return cell;
[contents addSection:blocklistSection];
self.tableViewController.contents = contents;
}
- (NSString *)displayNameForIndexPath:(NSIndexPath *)indexPath
#pragma mark - ContactsViewHelperDelegate
- (void)contactsViewHelperDidUpdateContacts
{
NSString *phoneNumber = _blockedPhoneNumbers[(NSUInteger)indexPath.item];
NSString *displayName = [_contactsManager displayNameForPhoneIdentifier:phoneNumber];
return displayName;
[self updateTableContents];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- (BOOL)shouldHideLocalNumber
{
[tableView deselectRowAtIndexPath:indexPath animated: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];
return YES;
}
#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 Contact;
@class ContactAccount;
@class SignalAccount;
@protocol ContactsViewHelperDelegate <NSObject>
@ -28,18 +28,12 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
// A list of all of the current user's contacts which have
// at least one signal account.
- (nullable NSArray<Contact *> *)allRecipientContacts;
@property (nonatomic, readonly) NSDictionary<NSString *, SignalAccount *> *signalAccountMap;
@property (nonatomic, readonly) NSArray<SignalAccount *> *signalAccounts;
// A list of all of the current user's ContactAccounts.
// 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;
@property (nonatomic, readonly) NSArray<NSString *> *blockedPhoneNumbers;
- (nullable ContactAccount *)contactAccountForRecipientId:(NSString *)recipientId;
- (nullable SignalAccount *)signalAccountForRecipientId:(NSString *)recipientId;
- (nullable NSArray<NSString *> *)blockedPhoneNumbers;
@ -48,6 +42,8 @@ NS_ASSUME_NONNULL_BEGIN
//
// Returns true if _any_ number associated with this contact
// is blocked.
//
// TODO: Is this obsolete?
- (BOOL)isContactBlocked:(Contact *)contact;
// This method is faster than OWSBlockingManager but
@ -56,7 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSString *)localNumber;
- (NSArray<ContactAccount *> *)contactAccountsMatchingSearchString:(NSString *)searchText;
- (NSArray<SignalAccount *> *)signalAccountsMatchingSearchString:(NSString *)searchText;
@end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,6 @@
#import "SelectThreadViewController.h"
#import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h"
#import "ContactsViewHelper.h"
#import "Environment.h"
@ -12,6 +11,7 @@
#import "OWSContactsManager.h"
#import "OWSContactsSearcher.h"
#import "OWSTableViewController.h"
#import "SignalAccount.h"
#import "ThreadViewHelper.h"
#import "UIColor+OWS.h"
#import "UIFont+OWS.h"
@ -153,8 +153,8 @@ NS_ASSUME_NONNULL_BEGIN
}
// Contacts
NSArray<ContactAccount *> *filteredContactAccounts = [self filteredContactAccountsWithSearchText];
for (ContactAccount *contactAccount in filteredContactAccounts) {
NSArray<SignalAccount *> *filteredSignalAccounts = [self filteredSignalAccountsWithSearchText];
for (SignalAccount *signalAccount in filteredSignalAccounts) {
[section addItem:[OWSTableItem itemWithCustomCellBlock:^{
SelectThreadViewController *strongSelf = weakSelf;
if (!strongSelf) {
@ -162,19 +162,19 @@ NS_ASSUME_NONNULL_BEGIN
}
ContactTableViewCell *cell = [ContactTableViewCell new];
BOOL isBlocked = [helper isRecipientIdBlocked:contactAccount.recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:signalAccount.recipientId];
if (isBlocked) {
cell.accessoryMessage
= NSLocalizedString(@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked.");
} else {
OWSAssert(cell.accessoryMessage == nil);
}
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager];
[cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
return cell;
}
customRowHeight:[ContactTableViewCell rowHeight]
actionBlock:^{
[weakSelf contactAccountWasSelected:contactAccount];
[weakSelf signalAccountWasSelected:signalAccount];
}]];
}
@ -195,31 +195,31 @@ NS_ASSUME_NONNULL_BEGIN
self.tableViewController.contents = contents;
}
- (void)contactAccountWasSelected:(ContactAccount *)contactAccount
- (void)signalAccountWasSelected:(SignalAccount *)signalAccount
{
OWSAssert(contactAccount);
OWSAssert(signalAccount);
OWSAssert(self.delegate);
ContactsViewHelper *helper = self.contactsViewHelper;
if ([helper isRecipientIdBlocked:contactAccount.recipientId] && ![self.delegate canSelectBlockedContact]) {
if ([helper isRecipientIdBlocked:signalAccount.recipientId] && ![self.delegate canSelectBlockedContact]) {
__weak SelectThreadViewController *weakSelf = self;
[BlockListUIUtils showUnblockContactAccountActionSheet:contactAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) {
if (!isBlocked) {
[weakSelf contactAccountWasSelected:contactAccount];
}
}];
[BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) {
if (!isBlocked) {
[weakSelf signalAccountWasSelected:signalAccount];
}
}];
return;
}
__block TSThread *thread = nil;
[[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
thread = [TSContactThread getOrCreateThreadWithContactId:contactAccount.recipientId transaction:transaction];
thread = [TSContactThread getOrCreateThreadWithContactId:signalAccount.recipientId transaction:transaction];
}];
OWSAssert(thread);
@ -255,8 +255,7 @@ NS_ASSUME_NONNULL_BEGIN
return result;
}
// TODO: Move this to contacts view helper.
- (NSArray<ContactAccount *> *)filteredContactAccountsWithSearchText
- (NSArray<SignalAccount *> *)filteredSignalAccountsWithSearchText
{
// We don't want to show a 1:1 thread with Alice and Alice's contact,
// so we de-duplicate by recipientId.
@ -272,10 +271,10 @@ NS_ASSUME_NONNULL_BEGIN
NSString *searchString = [self.searchBar text];
ContactsViewHelper *helper = self.contactsViewHelper;
return [[helper contactAccountsMatchingSearchString:searchString]
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(ContactAccount *contactAccount,
return [[helper signalAccountsMatchingSearchString:searchString]
filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SignalAccount *signalAccount,
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 "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h"
#import "ContactsViewHelper.h"
#import "Environment.h"
#import "OWSContactsManager.h"
#import "SignalAccount.h"
#import "SignalsViewController.h"
#import "UIUtil.h"
#import <AddressBookUI/AddressBookUI.h>
@ -108,15 +108,15 @@ NS_ASSUME_NONNULL_BEGIN
}
ContactTableViewCell *cell = [ContactTableViewCell new];
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId];
SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:recipientId];
if (isBlocked) {
cell.accessoryMessage
= NSLocalizedString(@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked.");
}
if (contactAccount) {
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager];
if (signalAccount) {
[cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
} else {
[cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager];
}
@ -138,7 +138,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(recipientId.length > 0);
ContactsViewHelper *helper = self.contactsViewHelper;
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId];
SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
@ -152,8 +152,8 @@ NS_ASSUME_NONNULL_BEGIN
}]];
BOOL isBlocked;
if (contactAccount) {
isBlocked = [helper isRecipientIdBlocked:contactAccount.recipientId];
if (signalAccount) {
isBlocked = [helper isRecipientIdBlocked:signalAccount.recipientId];
if (isBlocked) {
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BLOCK_LIST_UNBLOCK_BUTTON",
@ -161,11 +161,11 @@ NS_ASSUME_NONNULL_BEGIN
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[BlockListUIUtils
showUnblockContactAccountActionSheet:contactAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:nil];
showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:nil];
}]];
} else {
[actionSheetController
@ -174,11 +174,11 @@ NS_ASSUME_NONNULL_BEGIN
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
[BlockListUIUtils
showBlockContactAccountActionSheet:contactAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:nil];
showBlockSignalAccountActionSheet:signalAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:nil];
}]];
}
} else {
@ -242,14 +242,14 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(recipientId.length > 0);
ContactsViewHelper *helper = self.contactsViewHelper;
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId];
SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
if (contactAccount) {
if (signalAccount) {
ABPersonViewController *view = [[ABPersonViewController alloc] init];
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil);
// Assume person is already defined.
view.displayedPerson = ABAddressBookGetPersonWithRecordID(addressBookRef, contactAccount.contact.recordID);
view.displayedPerson = ABAddressBookGetPersonWithRecordID(addressBookRef, signalAccount.contact.recordID);
view.allowsActions = NO;
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 "AddToGroupViewController.h"
#import "BlockListUIUtils.h"
#import "ContactAccount.h"
#import "ContactTableViewCell.h"
#import "ContactsViewHelper.h"
#import "Environment.h"
@ -14,6 +13,7 @@
#import "OWSContactsManager.h"
#import "OWSTableViewController.h"
#import "SecurityUtils.h"
#import "SignalAccount.h"
#import "SignalKeyingStorage.h"
#import "TSOutgoingMessage.h"
#import "UIUtil.h"
@ -245,7 +245,7 @@ NS_ASSUME_NONNULL_BEGIN
}
ContactTableViewCell *cell = [ContactTableViewCell new];
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId];
SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
BOOL isPreviousMember = [strongSelf.previousMemberRecipientIds containsObject:recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:recipientId];
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.");
}
if (contactAccount) {
[cell configureWithContactAccount:contactAccount contactsManager:helper.contactsManager];
if (signalAccount) {
[cell configureWithSignalAccount:signalAccount contactsManager:helper.contactsManager];
} else {
[cell configureWithRecipientId:recipientId contactsManager:helper.contactsManager];
}
@ -274,26 +274,26 @@ NS_ASSUME_NONNULL_BEGIN
}
customRowHeight:[ContactTableViewCell rowHeight]
actionBlock:^{
ContactAccount *contactAccount = [helper contactAccountForRecipientId:recipientId];
SignalAccount *signalAccount = [helper signalAccountForRecipientId:recipientId];
BOOL isPreviousMember = [weakSelf.previousMemberRecipientIds containsObject:recipientId];
BOOL isBlocked = [helper isRecipientIdBlocked:recipientId];
if (isPreviousMember) {
if (isBlocked) {
if (contactAccount) {
[weakSelf showUnblockAlertForContactAccount:contactAccount];
if (signalAccount) {
[weakSelf showUnblockAlertForSignalAccount:signalAccount];
} else {
[weakSelf showUnblockAlertForRecipientId:recipientId];
}
}
} else {
if (contactAccount) {
if (signalAccount) {
[weakSelf.groupViewHelper
showRemoveFromGroupAlertForContactAccount:contactAccount
fromViewController:weakSelf
contactsManager:helper.contactsManager
successBlock:^{
[weakSelf removeContactAccount:contactAccount];
}];
showRemoveFromGroupAlertForSignalAccount:signalAccount
fromViewController:weakSelf
contactsManager:helper.contactsManager
successBlock:^{
[weakSelf removeSignalAccount:signalAccount];
}];
} else {
[weakSelf.groupViewHelper
showRemoveFromGroupAlertForRecipientId:recipientId
@ -311,21 +311,21 @@ NS_ASSUME_NONNULL_BEGIN
self.tableViewController.contents = contents;
}
- (void)showUnblockAlertForContactAccount:(ContactAccount *)contactAccount
- (void)showUnblockAlertForSignalAccount:(SignalAccount *)signalAccount
{
OWSAssert(contactAccount);
OWSAssert(signalAccount);
__weak UpdateGroupViewController *weakSelf = self;
ContactsViewHelper *helper = self.contactsViewHelper;
[BlockListUIUtils showUnblockContactAccountActionSheet:contactAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) {
if (!isBlocked) {
[weakSelf updateTableContents];
}
}];
[BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self
blockingManager:helper.blockingManager
contactsManager:helper.contactsManager
completionBlock:^(BOOL isBlocked) {
if (!isBlocked) {
[weakSelf updateTableContents];
}
}];
}
- (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];
}

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
// 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()

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
extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification;
// TODO: Remove this.
// TODO: Remove observableContactsController.
extern NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification;
@class UIFont;
@class ContactAccount;
@class SignalAccount;
/**
* Get latest Signal contacts, and be notified when they change.
*/
@interface OWSContactsManager : NSObject <ContactsManagerProtocol>
@property (nullable, strong) CNContactStore *contactStore;
@property (nonnull, readonly, strong) NSCache<NSString *, UIImage *> *avatarCache;
@property (nonnull, readonly) 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;
- (nullable Contact *)latestContactForPhoneNumber:(nullable PhoneNumber *)phoneNumber;
- (nullable Contact *)contactForPhoneIdentifier:(nullable NSString *)identifier;
- (nullable SignalAccount *)signalAccountForRecipientId:(nullable NSString *)recipientId;
- (Contact *)getOrBuildContactForPhoneIdentifier:(NSString *)identifier;
- (void)verifyABPermission;
- (NSArray<Contact *> *)allContacts;
// TODO: Remove this method.
- (NSArray<Contact *> *)signalContacts;
- (void)doAfterEnvironmentInitSetup;
- (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)identifier;
- (NSString *)displayNameForContact:(Contact *)contact;
- (NSString *_Nonnull)displayNameForContactAccount:(ContactAccount *)contactAccount;
- (NSString *_Nonnull)displayNameForSignalAccount:(SignalAccount *)signalAccount;
- (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier;
- (NSAttributedString *_Nonnull)formattedDisplayNameForContactAccount:(ContactAccount *)contactAccount
font:(UIFont *_Nonnull)font;
- (NSAttributedString *_Nonnull)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount
font:(UIFont *_Nonnull)font;
- (NSAttributedString *)formattedFullNameForContact:(Contact *)contact font:(UIFont *)font;
- (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font;

View File

@ -3,8 +3,8 @@
//
#import "OWSContactsManager.h"
#import "ContactAccount.h"
#import "Environment.h"
#import "SignalAccount.h"
#import "Util.h"
#import <SignalServiceKit/ContactsUpdater.h>
#import <SignalServiceKit/OWSError.h>
@ -13,25 +13,30 @@
typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL *);
NSString *const OWSContactsManagerSignalAccountsDidChangeNotification =
@"OWSContactsManagerSignalAccountsDidChangeNotification";
NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification =
@"OWSContactsManagerSignalRecipientsDidChangeNotification";
@interface OWSContactsManager ()
@property (atomic, nullable) CNContactStore *contactStore;
@property (atomic) id addressBookReference;
@property (atomic) TOCFuture *futureAddressBook;
@property (atomic) ObservableValueController *observableContactsController;
@property (atomic) TOCCancelTokenSource *life;
@property (atomic) NSDictionary *latestContactsById;
@property (atomic) NSDictionary<NSString *, Contact *> *contactMap;
@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
@implementation OWSContactsManager
@synthesize latestContactsById = _latestContactsById;
- (void)dealloc {
[_life cancel];
}
@ -44,49 +49,16 @@ NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification =
_life = [TOCCancelTokenSource new];
_observableContactsController = [ObservableValueController observableValueControllerWithInitialValue:nil];
_latestContactsById = @{};
_avatarCache = [NSCache new];
_allContacts = @[];
_signalAccountMap = @{};
_signalAccounts = @[];
OWSSingletonAssert();
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 {
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(9, 0) &&
!self.contactStore) {
@ -106,7 +78,7 @@ NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification =
__weak OWSContactsManager *weakSelf = self;
[self.observableContactsController watchLatestValueOnArbitraryThread:^(NSArray *latestContacts) {
@synchronized(self) {
[weakSelf setupLatestContacts:latestContacts];
[weakSelf updateSignalAccounts:latestContacts];
}
}
untilCancelled:_life.token];
@ -227,10 +199,120 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
[self.observableContactsController updateValue:[self getContactsFromAddressBook:addressBookRef]];
}
- (void)setupLatestContacts:(NSArray *)contacts {
if (contacts) {
self.latestContactsById = [OWSContactsManager keyContactsById:contacts];
- (void)updateSignalAccounts:(NSArray<Contact *> *)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 {
@ -394,28 +476,6 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
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 {
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
- (NSArray *)getSignalUsersFromContactsArray:(NSArray *)contacts {
@ -511,10 +552,12 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
if (!identifier) {
return self.unknownContactName;
}
Contact *contact = [self contactForPhoneIdentifier:identifier];
NSString *displayName = (contact.fullName.length > 0) ? contact.fullName : identifier;
// TODO: There's some overlap here with displayNameForSignalAccount.
SignalAccount *signalAccount = [self signalAccountForRecipientId:identifier];
NSString *displayName = (signalAccount.contact.fullName.length > 0) ? signalAccount.contact.fullName : identifier;
return displayName;
}
@ -527,36 +570,36 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
return displayName;
}
- (NSString *_Nonnull)displayNameForContactAccount:(ContactAccount *)contactAccount
- (NSString *_Nonnull)displayNameForSignalAccount:(SignalAccount *)signalAccount
{
OWSAssert(contactAccount);
OWSAssert(signalAccount);
NSString *baseName = (contactAccount.contact ? [self displayNameForContact:contactAccount.contact]
: [self displayNameForPhoneIdentifier:contactAccount.recipientId]);
OWSAssert(contactAccount.isMultipleAccountContact == (contactAccount.multipleAccountLabel != nil));
if (contactAccount.multipleAccountLabel) {
return [NSString stringWithFormat:@"%@ (%@)", baseName, contactAccount.multipleAccountLabel];
NSString *baseName = (signalAccount.contact ? [self displayNameForContact:signalAccount.contact]
: [self displayNameForPhoneIdentifier:signalAccount.recipientId]);
OWSAssert(signalAccount.isMultipleAccountContact == (signalAccount.multipleAccountLabel != nil));
if (signalAccount.multipleAccountLabel) {
return [NSString stringWithFormat:@"%@ (%@)", baseName, signalAccount.multipleAccountLabel];
} else {
return baseName;
}
}
- (NSAttributedString *_Nonnull)formattedDisplayNameForContactAccount:(ContactAccount *)contactAccount
font:(UIFont *_Nonnull)font
- (NSAttributedString *_Nonnull)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount
font:(UIFont *_Nonnull)font
{
OWSAssert(contactAccount);
OWSAssert(signalAccount);
OWSAssert(font);
NSAttributedString *baseName = [self formattedFullNameForContact:contactAccount.contact font:font];
OWSAssert(contactAccount.isMultipleAccountContact == (contactAccount.multipleAccountLabel != nil));
if (contactAccount.multipleAccountLabel) {
NSAttributedString *baseName = [self formattedFullNameForContact:signalAccount.contact font:font];
OWSAssert(signalAccount.isMultipleAccountContact == (signalAccount.multipleAccountLabel != nil));
if (signalAccount.multipleAccountLabel) {
NSMutableAttributedString *result = [NSMutableAttributedString new];
[result appendAttributedString:baseName];
[result appendAttributedString:[[NSAttributedString alloc] initWithString:@" ("
attributes:@{
NSFontAttributeName : font,
}]];
[result appendAttributedString:[[NSAttributedString alloc] initWithString:contactAccount.multipleAccountLabel]];
[result appendAttributedString:[[NSAttributedString alloc] initWithString:signalAccount.multipleAccountLabel]];
[result appendAttributedString:[[NSAttributedString alloc] initWithString:@")"
attributes:@{
NSFontAttributeName : font,
@ -627,16 +670,16 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
attributes:normalFontAttributes];
}
- (Contact * _Nullable)contactForPhoneIdentifier:(NSString * _Nullable)identifier {
if (!identifier) {
return nil;
}
return self.contactMap[identifier];
- (nullable SignalAccount *)signalAccountForRecipientId:(nullable NSString *)recipientId
{
OWSAssert(recipientId.length > 0);
return self.signalAccountMap[recipientId];
}
- (Contact *)getOrBuildContactForPhoneIdentifier:(NSString *)identifier
{
Contact *savedContact = [self contactForPhoneIdentifier:identifier];
Contact *savedContact = self.allContactsMap[identifier];
if (savedContact) {
return savedContact;
} else {
@ -649,9 +692,8 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
}
}
- (UIImage * _Nullable)imageForPhoneIdentifier:(NSString * _Nullable)identifier {
Contact *contact = [self contactForPhoneIdentifier:identifier];
Contact *contact = self.allContactsMap[identifier];
return contact.image;
}

View File

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

View File

@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
extern NSString *const kContactsTable_CellReuseIdentifier;
@class OWSContactsManager;
@class ContactAccount;
@class SignalAccount;
@class TSThread;
@interface ContactTableViewCell : UITableViewCell
@ -27,11 +27,10 @@ extern NSString *const kContactsTable_CellReuseIdentifier;
+ (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)configureWithContactAccount:(ContactAccount *)contactAccount
contactsManager:(OWSContactsManager *)contactsManager;
- (void)configureWithSignalAccount:(SignalAccount *)signalAccount contactsManager:(OWSContactsManager *)contactsManager;
- (void)configureWithRecipientId:(NSString *)recipientId contactsManager:(OWSContactsManager *)contactsManager;

View File

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