mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Add SignalAccount class.
// FREEBIE
This commit is contained in:
parent
93700f1044
commit
6801963a1b
30 changed files with 552 additions and 823 deletions
|
@ -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 */,
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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,7 +88,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[self presentViewController:controller animated:YES completion:nil];
|
||||
return;
|
||||
}
|
||||
[BlockListUIUtils showBlockContactAccountActionSheet:contactAccount
|
||||
[BlockListUIUtils showBlockSignalAccountActionSheet:signalAccount
|
||||
fromViewController:self
|
||||
blockingManager:helper.blockingManager
|
||||
contactsManager:helper.contactsManager
|
||||
|
|
|
@ -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
|
||||
if ([helper isRecipientIdBlocked:signalAccount.recipientId]) {
|
||||
[BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
|
||||
fromViewController:self
|
||||
blockingManager:helper.blockingManager
|
||||
contactsManager:helper.contactsManager
|
||||
completionBlock:^(BOOL isBlocked) {
|
||||
if (isBlocked) {
|
||||
[weakSelf addToGroup:contactAccount.recipientId];
|
||||
[weakSelf addToGroup:signalAccount.recipientId];
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
[self addToGroup:contactAccount.recipientId];
|
||||
[self addToGroup:signalAccount.recipientId];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class Contact;
|
||||
@class ContactAccount;
|
||||
@class SignalAccount;
|
||||
@class OWSBlockingManager;
|
||||
@class OWSContactsManager;
|
||||
|
||||
|
@ -25,7 +25,7 @@ typedef void (^BlockActionCompletionBlock)(BOOL isBlocked);
|
|||
contactsManager:(OWSContactsManager *)contactsManager
|
||||
completionBlock:(nullable BlockActionCompletionBlock)completionBlock;
|
||||
|
||||
+ (void)showBlockContactAccountActionSheet:(ContactAccount *)contactAccount
|
||||
+ (void)showBlockSignalAccountActionSheet:(SignalAccount *)signalAccount
|
||||
fromViewController:(UIViewController *)fromViewController
|
||||
blockingManager:(OWSBlockingManager *)blockingManager
|
||||
contactsManager:(OWSContactsManager *)contactsManager
|
||||
|
@ -39,7 +39,7 @@ typedef void (^BlockActionCompletionBlock)(BOOL isBlocked);
|
|||
contactsManager:(OWSContactsManager *)contactsManager
|
||||
completionBlock:(nullable BlockActionCompletionBlock)completionBlock;
|
||||
|
||||
+ (void)showUnblockContactAccountActionSheet:(ContactAccount *)contactAccount
|
||||
+ (void)showUnblockSignalAccountActionSheet:(SignalAccount *)signalAccount
|
||||
fromViewController:(UIViewController *)fromViewController
|
||||
blockingManager:(OWSBlockingManager *)blockingManager
|
||||
contactsManager:(OWSContactsManager *)contactsManager
|
||||
|
|
|
@ -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
|
||||
+ (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
|
||||
+ (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
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface BlockListViewController : UITableViewController
|
||||
@interface BlockListViewController : UIViewController
|
||||
|
||||
@end
|
||||
|
|
|
@ -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;
|
||||
|
||||
- (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;
|
||||
}
|
||||
}
|
||||
// Add section
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
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];
|
||||
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.textLabel.textColor = [UIColor blackColor];
|
||||
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
|
||||
break;
|
||||
case BlockListViewControllerSection_BlockList: {
|
||||
NSString *displayName = [self displayNameForIndexPath:indexPath];
|
||||
cell.textLabel.text = displayName;
|
||||
cell.textLabel.font = [UIFont ows_regularFontWithSize:18.f];
|
||||
cell.accessoryType = UITableViewCellAccessoryCheckmark;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
OWSAssert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
- (NSString *)displayNameForIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
NSString *phoneNumber = _blockedPhoneNumbers[(NSUInteger)indexPath.item];
|
||||
NSString *displayName = [_contactsManager displayNameForPhoneIdentifier:phoneNumber];
|
||||
return displayName;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
switch (indexPath.section) {
|
||||
case BlockListViewControllerSection_Add:
|
||||
{
|
||||
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");
|
||||
[self.navigationController pushViewController:vc animated:YES];
|
||||
break;
|
||||
[weakSelf.navigationController pushViewController:vc animated:YES];
|
||||
}]];
|
||||
[contents addSection:addSection];
|
||||
|
||||
// Blocklist section
|
||||
|
||||
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;
|
||||
cell.textLabel.textColor = [UIColor blackColor];
|
||||
return cell;
|
||||
}
|
||||
case BlockListViewControllerSection_BlockList: {
|
||||
NSString *phoneNumber = _blockedPhoneNumbers[(NSUInteger)indexPath.item];
|
||||
actionBlock:^{
|
||||
[BlockListUIUtils showUnblockPhoneNumberActionSheet:phoneNumber
|
||||
fromViewController:self
|
||||
blockingManager:_blockingManager
|
||||
contactsManager:_contactsManager
|
||||
fromViewController:weakSelf
|
||||
blockingManager:helper.blockingManager
|
||||
contactsManager:helper.contactsManager
|
||||
completionBlock:nil];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
OWSAssert(0);
|
||||
}]];
|
||||
}
|
||||
[contents addSection:blocklistSection];
|
||||
|
||||
self.tableViewController.contents = contents;
|
||||
}
|
||||
|
||||
#pragma mark - Actions
|
||||
#pragma mark - ContactsViewHelperDelegate
|
||||
|
||||
- (void)blockedPhoneNumbersDidChange:(id)notification
|
||||
- (void)contactsViewHelperDidUpdateContacts
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
|
||||
|
||||
[self.tableView reloadData];
|
||||
});
|
||||
[self updateTableContents];
|
||||
}
|
||||
|
||||
- (void)signalRecipientsDidChange:(NSNotification *)notification
|
||||
- (BOOL)shouldHideLocalNumber
|
||||
{
|
||||
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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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];
|
||||
}]];
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ContactAccount;
|
||||
@class SignalAccount;
|
||||
@class GroupViewHelper;
|
||||
@class OWSContactsManager;
|
||||
@class TSThread;
|
||||
|
@ -27,7 +27,7 @@ typedef void (^GroupViewSuccessBlock)();
|
|||
|
||||
@property (nonatomic, weak) id<GroupViewHelperDelegate> delegate;
|
||||
|
||||
- (void)showRemoveFromGroupAlertForContactAccount:(ContactAccount *)contactAccount
|
||||
- (void)showRemoveFromGroupAlertForSignalAccount:(SignalAccount *)signalAccount
|
||||
fromViewController:(UIViewController *)fromViewController
|
||||
contactsManager:(OWSContactsManager *)contactsManager
|
||||
successBlock:(GroupViewSuccessBlock)successBlock;
|
||||
|
|
|
@ -23,17 +23,17 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
#pragma mark - Alerts
|
||||
|
||||
- (void)showRemoveFromGroupAlertForContactAccount:(ContactAccount *)contactAccount
|
||||
- (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",
|
||||
|
|
|
@ -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,14 +236,14 @@ 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
|
||||
showRemoveFromGroupAlertForSignalAccount:signalAccount
|
||||
fromViewController:weakSelf
|
||||
contactsManager:helper.contactsManager
|
||||
successBlock:^{
|
||||
[weakSelf removeContactAccount:contactAccount];
|
||||
[weakSelf removeSignalAccount:signalAccount];
|
||||
}];
|
||||
} else {
|
||||
[weakSelf.groupViewHelper
|
||||
|
@ -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,21 +295,21 @@ 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
|
||||
showRemoveFromGroupAlertForSignalAccount:signalAccount
|
||||
fromViewController:weakSelf
|
||||
contactsManager:helper.contactsManager
|
||||
successBlock:^{
|
||||
[weakSelf removeContactAccount:contactAccount];
|
||||
[weakSelf removeSignalAccount:signalAccount];
|
||||
}];
|
||||
} else {
|
||||
[weakSelf addRecipientId:recipientId];
|
||||
|
@ -317,7 +317,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}]];
|
||||
}
|
||||
} 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.");
|
||||
|
@ -328,7 +328,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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];
|
||||
}]];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,23 +195,23 @@ 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
|
||||
[BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
|
||||
fromViewController:self
|
||||
blockingManager:helper.blockingManager
|
||||
contactsManager:helper.contactsManager
|
||||
completionBlock:^(BOOL isBlocked) {
|
||||
if (!isBlocked) {
|
||||
[weakSelf contactAccountWasSelected:contactAccount];
|
||||
[weakSelf signalAccountWasSelected:signalAccount];
|
||||
}
|
||||
}];
|
||||
return;
|
||||
|
@ -219,7 +219,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
__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];
|
||||
}]];
|
||||
}
|
||||
|
||||
|
|
|
@ -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,7 +161,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
style:UIAlertActionStyleDefault
|
||||
handler:^(UIAlertAction *_Nonnull action) {
|
||||
[BlockListUIUtils
|
||||
showUnblockContactAccountActionSheet:contactAccount
|
||||
showUnblockSignalAccountActionSheet:signalAccount
|
||||
fromViewController:self
|
||||
blockingManager:helper.blockingManager
|
||||
contactsManager:helper.contactsManager
|
||||
|
@ -174,7 +174,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
style:UIAlertActionStyleDestructive
|
||||
handler:^(UIAlertAction *_Nonnull action) {
|
||||
[BlockListUIUtils
|
||||
showBlockContactAccountActionSheet:contactAccount
|
||||
showBlockSignalAccountActionSheet:signalAccount
|
||||
fromViewController:self
|
||||
blockingManager:helper.blockingManager
|
||||
contactsManager:helper.contactsManager
|
||||
|
@ -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;
|
||||
|
||||
|
|
38
Signal/src/ViewControllers/SignalAccount.h
Normal file
38
Signal/src/ViewControllers/SignalAccount.h
Normal 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
|
21
Signal/src/ViewControllers/SignalAccount.m
Normal file
21
Signal/src/ViewControllers/SignalAccount.m
Normal 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
|
|
@ -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,25 +274,25 @@ 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
|
||||
showRemoveFromGroupAlertForSignalAccount:signalAccount
|
||||
fromViewController:weakSelf
|
||||
contactsManager:helper.contactsManager
|
||||
successBlock:^{
|
||||
[weakSelf removeContactAccount:contactAccount];
|
||||
[weakSelf removeSignalAccount:signalAccount];
|
||||
}];
|
||||
} else {
|
||||
[weakSelf.groupViewHelper
|
||||
|
@ -311,13 +311,13 @@ 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
|
||||
[BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
|
||||
fromViewController:self
|
||||
blockingManager:helper.blockingManager
|
||||
contactsManager:helper.contactsManager
|
||||
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -12,37 +12,45 @@
|
|||
|
||||
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
|
||||
- (NSAttributedString *_Nonnull)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount
|
||||
font:(UIFont *_Nonnull)font;
|
||||
- (NSAttributedString *)formattedFullNameForContact:(Contact *)contact font:(UIFont *)font;
|
||||
- (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font;
|
||||
|
|
|
@ -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,12 +199,122 @@ 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 {
|
||||
switch (ABAddressBookGetAuthorizationStatus()) {
|
||||
case kABAuthorizationStatusRestricted: {
|
||||
|
@ -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,9 +552,11 @@ 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
|
||||
- (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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,12 +90,11 @@ 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
|
||||
[self configureWithRecipientId:signalAccount.recipientId
|
||||
avatarName:signalAccount.contact.fullName
|
||||
displayName:[contactsManager formattedDisplayNameForSignalAccount:signalAccount
|
||||
font:self.nameLabel.font]
|
||||
contactsManager:contactsManager];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue