Merge branch 'charlesmchen/improveGroupMembersView'

pull/1/head
Matthew Chen 8 years ago
commit 4045d3bda1

@ -22,8 +22,6 @@ NS_ASSUME_NONNULL_BEGIN
NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockListViewControllerCellIdentifier"; NSString * const kAddToBlockListViewControllerCellIdentifier = @"kAddToBlockListViewControllerCellIdentifier";
NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseIdentifier";
#pragma mark - #pragma mark -
@interface AddToBlockListViewController () <CountryCodeViewControllerDelegate, @interface AddToBlockListViewController () <CountryCodeViewControllerDelegate,

@ -41,7 +41,9 @@ extern NSString *const OWSMessagesViewControllerDidAppearNotification;
@property (nonatomic, strong) AVAudioPlayer *audioPlayer; @property (nonatomic, strong) AVAudioPlayer *audioPlayer;
@property (nonatomic, strong) AVAudioRecorder *audioRecorder; @property (nonatomic, strong) AVAudioRecorder *audioRecorder;
- (void)configureForThread:(TSThread *)thread keyboardOnViewAppearing:(BOOL)keyboardAppearing; - (void)configureForThread:(TSThread *)thread
keyboardOnViewAppearing:(BOOL)keyboardAppearing
callOnViewAppearing:(BOOL)callOnViewAppearing;
- (void)popKeyBoard; - (void)popKeyBoard;
#pragma mark 3D Touch Methods #pragma mark 3D Touch Methods

@ -219,6 +219,7 @@ typedef enum : NSUInteger {
@property (nonatomic) NSUInteger page; @property (nonatomic) NSUInteger page;
@property (nonatomic) BOOL composeOnOpen; @property (nonatomic) BOOL composeOnOpen;
@property (nonatomic) BOOL callOnOpen;
@property (nonatomic) BOOL peek; @property (nonatomic) BOOL peek;
@property (nonatomic, readonly) OWSContactsManager *contactsManager; @property (nonatomic, readonly) OWSContactsManager *contactsManager;
@ -318,10 +319,18 @@ typedef enum : NSUInteger {
[self hideInputIfNeeded]; [self hideInputIfNeeded];
} }
- (void)configureForThread:(TSThread *)thread keyboardOnViewAppearing:(BOOL)keyboardAppearing { - (void)configureForThread:(TSThread *)thread
keyboardOnViewAppearing:(BOOL)keyboardOnViewAppearing
callOnViewAppearing:(BOOL)callOnViewAppearing
{
if (callOnViewAppearing) {
keyboardOnViewAppearing = NO;
}
_thread = thread; _thread = thread;
isGroupConversation = [self.thread isKindOfClass:[TSGroupThread class]]; isGroupConversation = [self.thread isKindOfClass:[TSGroupThread class]];
_composeOnOpen = keyboardAppearing; _composeOnOpen = keyboardOnViewAppearing;
_callOnOpen = callOnViewAppearing;
[self markAllMessagesAsRead]; [self markAllMessagesAsRead];
@ -719,6 +728,11 @@ typedef enum : NSUInteger {
self.inputToolbar.contentView.textView.editable = YES; self.inputToolbar.contentView.textView.editable = YES;
if (_composeOnOpen && !self.inputToolbar.hidden) { if (_composeOnOpen && !self.inputToolbar.hidden) {
[self popKeyBoard]; [self popKeyBoard];
_composeOnOpen = NO;
}
if (_callOnOpen) {
[self callAction:nil];
_callOnOpen = NO;
} }
[self updateNavigationBarSubtitleLabel]; [self updateNavigationBarSubtitleLabel];
} }

@ -3,12 +3,15 @@
// //
#import "ShowGroupMembersViewController.h" #import "ShowGroupMembersViewController.h"
#import "SignalsViewController.h" #import "BlockListUIUtils.h"
#import "OWSContactsManager.h" #import "ContactTableViewCell.h"
#import "Environment.h" #import "Environment.h"
#import "GroupContactsResult.h" #import "GroupContactsResult.h"
#import "OWSContactsManager.h"
#import "SignalsViewController.h"
#import "UIUtil.h" #import "UIUtil.h"
#import <AddressBookUI/AddressBookUI.h> #import <AddressBookUI/AddressBookUI.h>
#import <SignalServiceKit/OWSBlockingManager.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -20,6 +23,9 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
@property TSGroupThread *thread; @property TSGroupThread *thread;
@property (nonatomic, readonly) OWSContactsManager *_Nonnull contactsManager; @property (nonatomic, readonly) OWSContactsManager *_Nonnull contactsManager;
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
@property (nonatomic, readonly) NSArray<NSString *> *blockedPhoneNumbers;
@end @end
@implementation ShowGroupMembersViewController @implementation ShowGroupMembersViewController
@ -31,7 +37,7 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return self; return self;
} }
_contactsManager = [Environment getCurrent].contactsManager; [self commonInit];
return self; return self;
} }
@ -43,11 +49,43 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return self; return self;
} }
_contactsManager = [Environment getCurrent].contactsManager; [self commonInit];
return self; return self;
} }
- (void)commonInit
{
_blockingManager = [OWSBlockingManager sharedManager];
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
_contactsManager = [Environment getCurrent].contactsManager;
[self addNotificationListeners];
}
- (void)addNotificationListeners
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(blockedPhoneNumbersDidChange:)
name:kNSNotificationName_BlockedPhoneNumbersDidChange
object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)blockedPhoneNumbersDidChange:(id)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
_blockedPhoneNumbers = [_blockingManager blockedPhoneNumbers];
[self.tableView reloadData];
});
}
- (void)configWithThread:(TSGroupThread *)gThread { - (void)configWithThread:(TSGroupThread *)gThread {
_thread = gThread; _thread = gThread;
} }
@ -62,11 +100,15 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
self.groupContacts = self.groupContacts =
[[GroupContactsResult alloc] initWithMembersId:self.thread.groupModel.groupMemberIds without:nil]; [[GroupContactsResult alloc] initWithMembersId:self.thread.groupModel.groupMemberIds without:nil];
__weak ShowGroupMembersViewController *weakSelf = self;
[self.contactsManager.getObservableContacts watchLatestValue:^(id latestValue) { [self.contactsManager.getObservableContacts watchLatestValue:^(id latestValue) {
self.groupContacts = ShowGroupMembersViewController *strongSelf = weakSelf;
[[GroupContactsResult alloc] initWithMembersId:self.thread.groupModel.groupMemberIds without:nil]; if (!strongSelf) {
[self.tableView reloadData]; return;
}
strongSelf.groupContacts =
[[GroupContactsResult alloc] initWithMembersId:strongSelf.thread.groupModel.groupMemberIds without:nil];
[strongSelf.tableView reloadData];
} }
onThread:[NSThread mainThread] onThread:[NSThread mainThread]
untilCancelled:nil]; untilCancelled:nil];
@ -76,6 +118,8 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
- (void)initializeTableView { - (void)initializeTableView {
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
[self.tableView registerClass:[ContactTableViewCell class]
forCellReuseIdentifier:kContactsTable_CellReuseIdentifier];
} }
#pragma mark - Actions #pragma mark - Actions
@ -90,44 +134,176 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return (NSInteger)[self.groupContacts numberOfMembers] + 1; return (NSInteger)[self.groupContacts numberOfMembers] + 1;
} }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SearchCell"]; {
if (cell == nil) { if (indexPath.row == 0) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault UITableViewCell *cell = [UITableViewCell new];
reuseIdentifier:indexPath.row == 0 ? @"HeaderCell" : @"GroupSearchCell"];
}
if (indexPath.row > 0) {
NSIndexPath *relativeIndexPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
if ([self.groupContacts isContactAtIndexPath:relativeIndexPath]) {
Contact *contact = [self contactForIndexPath:relativeIndexPath];
cell.textLabel.attributedText =
[self.contactsManager formattedFullNameForContact:contact font:cell.textLabel.font];
} else {
cell.textLabel.text = [self.groupContacts identifierForIndexPath:relativeIndexPath];
}
} else {
cell.textLabel.text = NSLocalizedString(@"GROUP_MEMBERS_HEADER", @"header for table which lists the members of this group thread"); cell.textLabel.text = NSLocalizedString(@"GROUP_MEMBERS_HEADER", @"header for table which lists the members of this group thread");
cell.textLabel.textColor = [UIColor lightGrayColor]; cell.textLabel.textColor = [UIColor lightGrayColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.userInteractionEnabled = NO; cell.userInteractionEnabled = NO;
return cell;
} }
tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; // Adjust index path for the header row.
indexPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
ContactTableViewCell *cell = [ContactTableViewCell new];
if ([self.groupContacts isContactAtIndexPath:indexPath]) {
Contact *contact = [self contactForIndexPath:indexPath];
BOOL isBlocked = [self isContactBlocked:contact];
if (isBlocked) {
cell.accessoryMessage
= NSLocalizedString(@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked.");
} else {
OWSAssert(cell.accessoryMessage == nil);
}
[cell configureWithContact:contact contactsManager:self.contactsManager];
} else {
NSString *recipientId = [self.groupContacts identifierForIndexPath:indexPath];
BOOL isBlocked = [self isRecipientIdBlocked:recipientId];
if (isBlocked) {
cell.accessoryMessage
= NSLocalizedString(@"CONTACT_CELL_IS_BLOCKED", @"An indicator that a contact has been blocked.");
} else {
OWSAssert(cell.accessoryMessage == nil);
}
[cell configureWithRecipientId:recipientId contactsManager:self.contactsManager];
}
return cell; return cell;
} }
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
return 45.f;
} else {
return [ContactTableViewCell rowHeight];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *relativeIndexPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section]; if (indexPath.row == 0) {
OWSAssert(0);
return;
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Adjust index path for the header row.
indexPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"GROUP_MEMBERS_VIEW_CONTACT_INFO",
@"Button label for the 'show contact info' button")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[self showContactInfoViewForMember:indexPath];
}]];
BOOL isBlocked;
if ([self.groupContacts isContactAtIndexPath:indexPath]) {
Contact *contact = [self contactForIndexPath:indexPath];
isBlocked = [self isContactBlocked:contact];
if (isBlocked) {
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BLOCK_LIST_UNBLOCK_BUTTON",
@"Button label for the 'unblock' button")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[BlockListUIUtils
showUnblockContactActionSheet:contact
fromViewController:self
blockingManager:self.blockingManager
contactsManager:self.contactsManager
completionBlock:nil];
}]];
} else {
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BLOCK_LIST_BLOCK_BUTTON",
@"Button label for the 'block' button")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
[BlockListUIUtils showBlockContactActionSheet:contact
fromViewController:self
blockingManager:self.blockingManager
contactsManager:self.contactsManager
completionBlock:nil];
}]];
}
} else {
NSString *recipientId = [self.groupContacts identifierForIndexPath:indexPath];
isBlocked = [self isRecipientIdBlocked:recipientId];
if (isBlocked) {
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BLOCK_LIST_UNBLOCK_BUTTON",
@"Button label for the 'unblock' button")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[BlockListUIUtils
showUnblockPhoneNumberActionSheet:recipientId
fromViewController:self
blockingManager:self.blockingManager
contactsManager:self.contactsManager
completionBlock:nil];
}]];
} else {
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"BLOCK_LIST_BLOCK_BUTTON",
@"Button label for the 'block' button")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
[BlockListUIUtils
showBlockPhoneNumberActionSheet:recipientId
fromViewController:self
blockingManager:self.blockingManager
contactsManager:self.contactsManager
completionBlock:nil];
}]];
}
}
if (!isBlocked) {
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"GROUP_MEMBERS_SEND_MESSAGE",
@"Button label for the 'send message to group member' button")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[self showConversationViewForMember:indexPath];
}]];
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"GROUP_MEMBERS_CALL",
@"Button label for the 'call group member' button")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[self callMember:indexPath];
}]];
}
UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"")
style:UIAlertActionStyleCancel
handler:nil];
[actionSheetController addAction:dismissAction];
if (indexPath.row > 0 && [self.groupContacts isContactAtIndexPath:relativeIndexPath]) { [self presentViewController:actionSheetController animated:YES completion:nil];
}
- (void)showContactInfoViewForMember:(NSIndexPath *)indexPath
{
if ([self.groupContacts isContactAtIndexPath:indexPath]) {
ABPersonViewController *view = [[ABPersonViewController alloc] init]; ABPersonViewController *view = [[ABPersonViewController alloc] init];
Contact *contact = [self.groupContacts contactForIndexPath:relativeIndexPath]; Contact *contact = [self.groupContacts contactForIndexPath:indexPath];
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil); ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil);
view.displayedPerson = view.displayedPerson
ABAddressBookGetPersonWithRecordID(addressBookRef, contact.recordID); // Assume person is already defined. = ABAddressBookGetPersonWithRecordID(addressBookRef, contact.recordID); // Assume person is already defined.
view.allowsActions = NO; view.allowsActions = NO;
view.allowsEditing = YES; view.allowsEditing = YES;
@ -139,8 +315,7 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
CFErrorRef anError = NULL; CFErrorRef anError = NULL;
ABMultiValueRef phone = ABMultiValueCreateMutable(kABMultiStringPropertyType); ABMultiValueRef phone = ABMultiValueCreateMutable(kABMultiStringPropertyType);
ABMultiValueAddValueAndLabel( ABMultiValueAddValueAndLabel(phone,
phone,
(__bridge CFTypeRef)[self.tableView cellForRowAtIndexPath:indexPath].textLabel.text, (__bridge CFTypeRef)[self.tableView cellForRowAtIndexPath:indexPath].textLabel.text,
kABPersonPhoneMainLabel, kABPersonPhoneMainLabel,
NULL); NULL);
@ -154,8 +329,30 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
[self.navigationController pushViewController:view animated:YES]; [self.navigationController pushViewController:view animated:YES];
} }
} }
}
- (void)showConversationViewForMember:(NSIndexPath *)indexPath
{
NSString *recipientId;
if ([self.groupContacts isContactAtIndexPath:indexPath]) {
Contact *contact = [self.groupContacts contactForIndexPath:indexPath];
recipientId = [[contact textSecureIdentifiers] firstObject];
} else {
recipientId = [self.groupContacts identifierForIndexPath:indexPath];
}
[Environment messageIdentifier:recipientId withCompose:YES];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES]; - (void)callMember:(NSIndexPath *)indexPath
{
NSString *recipientId;
if ([self.groupContacts isContactAtIndexPath:indexPath]) {
Contact *contact = [self.groupContacts contactForIndexPath:indexPath];
recipientId = [[contact textSecureIdentifiers] firstObject];
} else {
recipientId = [self.groupContacts identifierForIndexPath:indexPath];
}
[Environment callUserWithIdentifier:recipientId];
} }
- (Contact *)contactForIndexPath:(NSIndexPath *)indexPath { - (Contact *)contactForIndexPath:(NSIndexPath *)indexPath {
@ -163,6 +360,27 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return contact; return contact;
} }
- (BOOL)isContactBlocked:(Contact *)contact
{
if (contact.parsedPhoneNumbers.count < 1) {
// Do not consider contacts without any valid phone numbers to be blocked.
return NO;
}
for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) {
if ([_blockedPhoneNumbers containsObject:phoneNumber.toE164]) {
return YES;
}
}
return NO;
}
- (BOOL)isRecipientIdBlocked:(NSString *)recipientId
{
return [_blockedPhoneNumbers containsObject:recipientId];
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -14,7 +14,9 @@
@property (nonatomic, strong) IBOutlet UILabel *emptyBoxLabel; @property (nonatomic, strong) IBOutlet UILabel *emptyBoxLabel;
@property (nonatomic) BOOL newlyRegisteredUser; @property (nonatomic) BOOL newlyRegisteredUser;
- (void)presentThread:(TSThread *)thread keyboardOnViewAppearing:(BOOL)keyboardOnViewAppearing; - (void)presentThread:(TSThread *)thread
keyboardOnViewAppearing:(BOOL)keyboardOnViewAppearing
callOnViewAppearing:(BOOL)callOnViewAppearing;
- (NSNumber *)updateInboxCountLabel; - (NSNumber *)updateInboxCountLabel;
- (void)composeNew; - (void)composeNew;

@ -131,9 +131,9 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
object:nil]; object:nil];
[self selectedInbox:self]; [self selectedInbox:self];
[[[Environment getCurrent] contactsManager] __weak SignalsViewController *weakSelf = self;
.getObservableContacts watchLatestValue:^(id latestValue) { [[[Environment getCurrent] contactsManager].getObservableContacts watchLatestValue:^(id latestValue) {
[self.tableView reloadData]; [weakSelf.tableView reloadData];
} }
onThread:[NSThread mainThread] onThread:[NSThread mainThread]
untilCancelled:nil]; untilCancelled:nil];
@ -210,7 +210,7 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
MessagesViewController *vc = [MessagesViewController new]; MessagesViewController *vc = [MessagesViewController new];
TSThread *thread = [self threadForIndexPath:indexPath]; TSThread *thread = [self threadForIndexPath:indexPath];
[vc configureForThread:thread keyboardOnViewAppearing:NO]; [vc configureForThread:thread keyboardOnViewAppearing:NO callOnViewAppearing:NO];
[vc peekSetup]; [vc peekSetup];
return vc; return vc;
@ -524,12 +524,15 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
TSThread *thread = [self threadForIndexPath:indexPath]; TSThread *thread = [self threadForIndexPath:indexPath];
[self presentThread:thread keyboardOnViewAppearing:NO]; [self presentThread:thread keyboardOnViewAppearing:NO callOnViewAppearing:NO];
[tableView deselectRowAtIndexPath:indexPath animated:YES]; [tableView deselectRowAtIndexPath:indexPath animated:YES];
} }
- (void)presentThread:(TSThread *)thread keyboardOnViewAppearing:(BOOL)keyboardOnViewAppearing { - (void)presentThread:(TSThread *)thread
keyboardOnViewAppearing:(BOOL)keyboardOnViewAppearing
callOnViewAppearing:(BOOL)callOnViewAppearing
{
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
MessagesViewController *mvc = [[MessagesViewController alloc] initWithNibName:@"MessagesViewController" MessagesViewController *mvc = [[MessagesViewController alloc] initWithNibName:@"MessagesViewController"
bundle:nil]; bundle:nil];
@ -539,7 +542,9 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
} }
[self.navigationController popToRootViewControllerAnimated:YES]; [self.navigationController popToRootViewControllerAnimated:YES];
[mvc configureForThread:thread keyboardOnViewAppearing:keyboardOnViewAppearing]; [mvc configureForThread:thread
keyboardOnViewAppearing:keyboardOnViewAppearing
callOnViewAppearing:callOnViewAppearing];
[self.navigationController pushViewController:mvc animated:YES]; [self.navigationController pushViewController:mvc animated:YES];
}); });
} }

@ -42,6 +42,7 @@ extern NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification;
- (NSString *)displayNameForContact:(Contact *)contact; - (NSString *)displayNameForContact:(Contact *)contact;
- (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier; - (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier;
- (NSAttributedString *)formattedFullNameForContact:(Contact *)contact font:(UIFont *)font; - (NSAttributedString *)formattedFullNameForContact:(Contact *)contact font:(UIFont *)font;
- (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font;
- (BOOL)hasAddressBook; - (BOOL)hasAddressBook;

@ -102,9 +102,10 @@ NSString *const OWSContactsManagerSignalRecipientsDidChangeNotification =
[self setupAddressBookIfNecessary]; [self setupAddressBookIfNecessary];
__weak OWSContactsManager *weakSelf = self;
[self.observableContactsController watchLatestValueOnArbitraryThread:^(NSArray *latestContacts) { [self.observableContactsController watchLatestValueOnArbitraryThread:^(NSArray *latestContacts) {
@synchronized(self) { @synchronized(self) {
[self setupLatestContacts:latestContacts]; [weakSelf setupLatestContacts:latestContacts];
} }
} }
untilCancelled:_life.token]; untilCancelled:_life.token];
@ -559,6 +560,16 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
return fullNameString; return fullNameString;
} }
- (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font
{
NSDictionary<NSString *, id> *normalFontAttributes =
@{ NSFontAttributeName : font, NSForegroundColorAttributeName : [UIColor ows_darkGrayColor] };
return [[NSAttributedString alloc]
initWithString:[PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:recipientId]
attributes:normalFontAttributes];
}
- (Contact * _Nullable)contactForPhoneIdentifier:(NSString * _Nullable)identifier { - (Contact * _Nullable)contactForPhoneIdentifier:(NSString * _Nullable)identifier {
if (!identifier) { if (!identifier) {
return nil; return nil;

@ -64,6 +64,7 @@
+ (void)messageThreadId:(NSString *)threadId; + (void)messageThreadId:(NSString *)threadId;
+ (void)messageIdentifier:(NSString *)identifier withCompose:(BOOL)compose; + (void)messageIdentifier:(NSString *)identifier withCompose:(BOOL)compose;
+ (void)callUserWithIdentifier:(NSString *)identifier;
+ (void)messageGroup:(TSGroupThread *)groupThread; + (void)messageGroup:(TSGroupThread *)groupThread;
@end @end

@ -212,8 +212,19 @@ static Environment *environment = nil;
[[TSStorageManager sharedManager] [[TSStorageManager sharedManager]
.dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { .dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
TSThread *thread = [TSContactThread getOrCreateThreadWithContactId:identifier transaction:transaction]; TSThread *thread = [TSContactThread getOrCreateThreadWithContactId:identifier transaction:transaction];
[vc presentThread:thread keyboardOnViewAppearing:YES]; [vc presentThread:thread keyboardOnViewAppearing:YES callOnViewAppearing:NO];
}];
}
+ (void)callUserWithIdentifier:(NSString *)identifier
{
Environment *env = [self getCurrent];
SignalsViewController *vc = env.signalsViewController;
[[TSStorageManager sharedManager].dbConnection
asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
TSThread *thread = [TSContactThread getOrCreateThreadWithContactId:identifier transaction:transaction];
[vc presentThread:thread keyboardOnViewAppearing:NO callOnViewAppearing:YES];
}]; }];
} }
@ -221,7 +232,7 @@ static Environment *environment = nil;
Environment *env = [self getCurrent]; Environment *env = [self getCurrent];
SignalsViewController *vc = env.signalsViewController; SignalsViewController *vc = env.signalsViewController;
[vc presentThread:groupThread keyboardOnViewAppearing:YES]; [vc presentThread:groupThread keyboardOnViewAppearing:YES callOnViewAppearing:NO];
} }
+ (void)resetAppData { + (void)resetAppData {

@ -13,6 +13,8 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
extern NSString *const kContactsTable_CellReuseIdentifier;
@class OWSContactsManager; @class OWSContactsManager;
@interface ContactTableViewCell : UITableViewCell @interface ContactTableViewCell : UITableViewCell
@ -25,6 +27,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager; - (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager;
- (void)configureWithRecipientId:(NSString *)recipientId contactsManager:(OWSContactsManager *)contactsManager;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -12,6 +12,8 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseIdentifier";
@interface ContactTableViewCell () @interface ContactTableViewCell ()
@property (nonatomic) IBOutlet UILabel *nameLabel; @property (nonatomic) IBOutlet UILabel *nameLabel;
@ -53,6 +55,8 @@ NS_ASSUME_NONNULL_BEGIN
// applyRoundedBorderToImageView requires the avatar to have // applyRoundedBorderToImageView requires the avatar to have
// the correct size. // the correct size.
_avatarView.frame = CGRectMake(0, 0, kAvatarSize, kAvatarSize); _avatarView.frame = CGRectMake(0, 0, kAvatarSize, kAvatarSize);
_avatarView.layer.minificationFilter = kCAFilterTrilinear;
_avatarView.layer.magnificationFilter = kCAFilterTrilinear;
[self.contentView addSubview:_avatarView]; [self.contentView addSubview:_avatarView];
_nameLabel = [UILabel new]; _nameLabel = [UILabel new];
@ -77,8 +81,27 @@ NS_ASSUME_NONNULL_BEGIN
- (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager - (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager
{ {
NSMutableAttributedString *attributedText = [self configureWithRecipientId:contact.textSecureIdentifiers.firstObject
[[contactsManager formattedFullNameForContact:contact font:self.nameLabel.font] mutableCopy]; avatarName:contact.fullName
displayName:[contactsManager formattedFullNameForContact:contact font:self.nameLabel.font]
contactsManager:contactsManager];
}
- (void)configureWithRecipientId:(NSString *)recipientId contactsManager:(OWSContactsManager *)contactsManager
{
[self
configureWithRecipientId:recipientId
avatarName:@""
displayName:[contactsManager formattedFullNameForRecipientId:recipientId font:self.nameLabel.font]
contactsManager:contactsManager];
}
- (void)configureWithRecipientId:(NSString *)recipientId
avatarName:(NSString *)avatarName
displayName:(NSAttributedString *)displayName
contactsManager:(OWSContactsManager *)contactsManager
{
NSMutableAttributedString *attributedText = [displayName mutableCopy];
if (self.accessoryMessage) { if (self.accessoryMessage) {
UILabel *blockedLabel = [[UILabel alloc] init]; UILabel *blockedLabel = [[UILabel alloc] init];
blockedLabel.textAlignment = NSTextAlignmentRight; blockedLabel.textAlignment = NSTextAlignmentRight;
@ -91,9 +114,8 @@ NS_ASSUME_NONNULL_BEGIN
} }
self.nameLabel.attributedText = attributedText; self.nameLabel.attributedText = attributedText;
self.avatarView.image = self.avatarView.image =
[[[OWSContactAvatarBuilder alloc] initWithContactId:contact.textSecureIdentifiers.firstObject [[[OWSContactAvatarBuilder alloc] initWithContactId:recipientId name:avatarName contactsManager:contactsManager]
name:contact.fullName build];
contactsManager:contactsManager] build];
// Force layout, since imageView isn't being initally rendered on App Store optimized build. // Force layout, since imageView isn't being initally rendered on App Store optimized build.
[self layoutSubviews]; [self layoutSubviews];

@ -460,9 +460,18 @@
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GROUP_MEMBER_LEFT" = " %@ left the group. "; "GROUP_MEMBER_LEFT" = " %@ left the group. ";
/* Button label for the 'call group member' button */
"GROUP_MEMBERS_CALL" = "Call";
/* header for table which lists the members of this group thread */ /* header for table which lists the members of this group thread */
"GROUP_MEMBERS_HEADER" = "Group Members"; "GROUP_MEMBERS_HEADER" = "Group Members";
/* Button label for the 'send message to group member' button */
"GROUP_MEMBERS_SEND_MESSAGE" = "Send Message";
/* Button label for the 'show contact info' button */
"GROUP_MEMBERS_VIEW_CONTACT_INFO" = "Contact Info";
/* No comment provided by engineer. */ /* No comment provided by engineer. */
"GROUP_REMOVING" = "Leaving group %@"; "GROUP_REMOVING" = "Leaving group %@";

Loading…
Cancel
Save