Fix crash in group listing / new group views

The broken code addressed in 8211d4584f
was duplicated a couple of places. This commit ferrets out the rest of
them and centralizes the logic in the ContactsManager.

// FREEBIE
pull/1/head
Michael Kirk 9 years ago
parent a8f37ef5ce
commit 243ff190bc

@ -6,32 +6,36 @@
#import "Contact.h"
#import "ObservableValue.h"
/**
Get latest Signal contacts, and be notified when they change.
*/
NS_ASSUME_NONNULL_BEGIN
#define SIGNAL_LIST_UPDATED @"Signal_AB_UPDATED"
@class UIFont;
/**
* Get latest Signal contacts, and be notified when they change.
*/
@interface OWSContactsManager : NSObject <ContactsManagerProtocol>
@property CNContactStore * _Nullable contactStore;
@property NSCache<NSString *, UIImage *> * _Nonnull avatarCache;
@property (nullable, strong) CNContactStore *contactStore;
@property (nonnull, readonly, strong) NSCache<NSString *, UIImage *> *avatarCache;
- (ObservableValue * _Nonnull)getObservableContacts;
- (nonnull ObservableValue *)getObservableContacts;
- (NSArray * _Nonnull)getContactsFromAddressBook:(ABAddressBookRef _Nonnull)addressBook;
- (Contact * _Nullable)latestContactForPhoneNumber:(PhoneNumber * _Nullable)phoneNumber;
- (nonnull NSArray *)getContactsFromAddressBook:(nonnull ABAddressBookRef)addressBook;
- (nullable Contact *)latestContactForPhoneNumber:(nullable PhoneNumber *)phoneNumber;
- (void)verifyABPermission;
- (NSArray<Contact *> * _Nonnull)allContacts;
- (NSArray<Contact *> * _Nonnull)signalContacts;
- (NSArray<Contact *> *)allContacts;
- (NSArray<Contact *> *)signalContacts;
- (void)doAfterEnvironmentInitSetup;
- (NSString * _Nonnull)displayNameForPhoneIdentifier:(NSString * _Nullable)identifier;
- (UIImage * _Nullable)imageForPhoneIdentifier:(NSString * _Nullable)identifier;
- (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)identifier;
- (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier;
- (NSAttributedString *)formattedFullNameForContact:(Contact *)contact font:(UIFont *)font;
+ (NSComparator _Nonnull)contactComparator;
@end
NS_ASSUME_NONNULL_END

@ -411,6 +411,56 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
return displayName;
}
- (NSAttributedString *_Nonnull)formattedFullNameForContact:(Contact *)contact font:(UIFont *_Nonnull)font
{
UIFont *boldFont = [UIFont ows_mediumFontWithSize:font.pointSize];
NSDictionary<NSString *, id> *boldFontAttributes =
@{ NSFontAttributeName : boldFont, NSForegroundColorAttributeName : [UIColor blackColor] };
NSDictionary<NSString *, id> *normalFontAttributes =
@{ NSFontAttributeName : font, NSForegroundColorAttributeName : [UIColor ows_darkGrayColor] };
NSAttributedString *_Nullable firstName, *_Nullable lastName;
if (ABPersonGetSortOrdering() == kABPersonSortByFirstName) {
if (contact.firstName) {
firstName = [[NSAttributedString alloc] initWithString:contact.firstName attributes:boldFontAttributes];
}
if (contact.lastName) {
lastName = [[NSAttributedString alloc] initWithString:contact.lastName attributes:normalFontAttributes];
}
} else {
if (contact.firstName) {
firstName = [[NSAttributedString alloc] initWithString:contact.firstName attributes:normalFontAttributes];
}
if (contact.lastName) {
lastName = [[NSAttributedString alloc] initWithString:contact.lastName attributes:boldFontAttributes];
}
}
NSAttributedString *_Nullable leftName, *_Nullable rightName;
if (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst) {
leftName = firstName;
rightName = lastName;
} else {
leftName = lastName;
rightName = firstName;
}
NSMutableAttributedString *fullNameString = [NSMutableAttributedString new];
if (leftName) {
[fullNameString appendAttributedString:leftName];
}
if (leftName && rightName) {
[fullNameString appendAttributedString:[[NSAttributedString alloc] initWithString:@" "]];
}
if (rightName) {
[fullNameString appendAttributedString:rightName];
}
return fullNameString;
}
- (Contact * _Nullable)contactForPhoneIdentifier:(NSString * _Nullable)identifier {
if (!identifier) {
return nil;

@ -29,7 +29,8 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
}
@property TSGroupThread *thread;
@property (nonatomic, readonly) OWSMessageSender *messageSender;
@property (nonatomic, readonly, strong) OWSMessageSender *messageSender;
@property (nonatomic, readonly, strong) OWSContactsManager *contactsManager;
@end
@ -42,10 +43,8 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return self;
}
_messageSender = [[OWSMessageSender alloc] initWithNetworkManager:[Environment getCurrent].networkManager
storageManager:[TSStorageManager sharedManager]
contactsManager:[Environment getCurrent].contactsManager
contactsUpdater:[Environment getCurrent].contactsUpdater];
[self commonInit];
return self;
}
@ -56,11 +55,19 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return self;
}
[self commonInit];
return self;
}
- (void)commonInit
{
_messageSender = [[OWSMessageSender alloc] initWithNetworkManager:[Environment getCurrent].networkManager
storageManager:[TSStorageManager sharedManager]
contactsManager:[Environment getCurrent].contactsManager
contactsUpdater:[Environment getCurrent].contactsUpdater];
return self;
_contactsManager = [Environment getCurrent].contactsManager;
}
- (void)configWithThread:(TSGroupThread *)gThread {
@ -339,7 +346,7 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
NSUInteger row = (NSUInteger)indexPath.row;
Contact *contact = contacts[row];
cell.textLabel.attributedText = [self attributedStringForContact:contact inCell:cell];
cell.textLabel.attributedText = [self.contactsManager formattedFullNameForContact:contact font:cell.textLabel.font];
tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
@ -372,44 +379,4 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return NO;
}
#pragma mark - Cell Utility
- (NSAttributedString *)attributedStringForContact:(Contact *)contact inCell:(UITableViewCell *)cell {
NSMutableAttributedString *fullNameAttributedString =
[[NSMutableAttributedString alloc] initWithString:contact.fullName];
UIFont *firstNameFont;
UIFont *lastNameFont;
if (ABPersonGetSortOrdering() == kABPersonCompositeNameFormatFirstNameFirst) {
firstNameFont = [UIFont ows_mediumFontWithSize:cell.textLabel.font.pointSize];
lastNameFont = [UIFont ows_regularFontWithSize:cell.textLabel.font.pointSize];
} else {
firstNameFont = [UIFont ows_regularFontWithSize:cell.textLabel.font.pointSize];
lastNameFont = [UIFont ows_mediumFontWithSize:cell.textLabel.font.pointSize];
}
[fullNameAttributedString addAttribute:NSFontAttributeName
value:firstNameFont
range:NSMakeRange(0, contact.firstName.length)];
[fullNameAttributedString addAttribute:NSFontAttributeName
value:lastNameFont
range:NSMakeRange(contact.firstName.length + 1, contact.lastName.length)];
[fullNameAttributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor blackColor]
range:NSMakeRange(0, contact.fullName.length)];
if (ABPersonGetSortOrdering() == kABPersonCompositeNameFormatFirstNameFirst) {
[fullNameAttributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor ows_darkGrayColor]
range:NSMakeRange(contact.firstName.length + 1, contact.lastName.length)];
} else {
[fullNameAttributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor ows_darkGrayColor]
range:NSMakeRange(0, contact.firstName.length)];
}
return fullNameAttributedString;
}
@end

@ -19,17 +19,44 @@
#import <AddressBookUI/AddressBookUI.h>
NS_ASSUME_NONNULL_BEGIN
static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue";
@interface ShowGroupMembersViewController ()
@property GroupContactsResult *groupContacts;
@property TSGroupThread *thread;
@property (nonatomic, readonly, strong) OWSContactsManager *_Nonnull contactsManager;
@end
@implementation ShowGroupMembersViewController
- (instancetype)init
{
self = [super init];
if (!self) {
return self;
}
_contactsManager = [Environment getCurrent].contactsManager;
return self;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (!self) {
return self;
}
_contactsManager = [Environment getCurrent].contactsManager;
return self;
}
- (void)configWithThread:(TSGroupThread *)gThread {
_thread = gThread;
}
@ -45,19 +72,17 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
self.groupContacts =
[[GroupContactsResult alloc] initWithMembersId:self.thread.groupModel.groupMemberIds without:nil];
[[Environment.getCurrent contactsManager]
.getObservableContacts watchLatestValue:^(id latestValue) {
self.groupContacts =
[[GroupContactsResult alloc] initWithMembersId:self.thread.groupModel.groupMemberIds without:nil];
[self.tableView reloadData];
[self.contactsManager.getObservableContacts watchLatestValue:^(id latestValue) {
self.groupContacts =
[[GroupContactsResult alloc] initWithMembersId:self.thread.groupModel.groupMemberIds without:nil];
[self.tableView reloadData];
}
onThread:[NSThread mainThread]
untilCancelled:nil];
onThread:[NSThread mainThread]
untilCancelled:nil];
}
#pragma mark - Initializers
- (void)initializeTableView {
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
}
@ -85,7 +110,8 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
NSIndexPath *relativeIndexPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
if ([self.groupContacts isContactAtIndexPath:relativeIndexPath]) {
Contact *contact = [self contactForIndexPath:relativeIndexPath];
cell.textLabel.attributedText = [self attributedStringForContact:contact inCell:cell];
cell.textLabel.attributedText =
[self.contactsManager formattedFullNameForContact:contact font:cell.textLabel.font];
} else {
cell.textLabel.text = [self.groupContacts identifierForIndexPath:relativeIndexPath];
}
@ -101,7 +127,6 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *relativeIndexPath = [NSIndexPath indexPathForRow:indexPath.row - 1 inSection:indexPath.section];
@ -147,43 +172,6 @@ static NSString *const kUnwindToMessagesViewSegue = @"UnwindToMessagesViewSegue"
return contact;
}
#pragma mark - Cell Utility
- (NSAttributedString *)attributedStringForContact:(Contact *)contact inCell:(UITableViewCell *)cell {
NSMutableAttributedString *fullNameAttributedString =
[[NSMutableAttributedString alloc] initWithString:contact.fullName];
UIFont *firstNameFont;
UIFont *lastNameFont;
if (ABPersonGetSortOrdering() == kABPersonCompositeNameFormatFirstNameFirst) {
firstNameFont = [UIFont ows_mediumFontWithSize:cell.textLabel.font.pointSize];
lastNameFont = [UIFont ows_regularFontWithSize:cell.textLabel.font.pointSize];
} else {
firstNameFont = [UIFont ows_regularFontWithSize:cell.textLabel.font.pointSize];
lastNameFont = [UIFont ows_mediumFontWithSize:cell.textLabel.font.pointSize];
}
[fullNameAttributedString addAttribute:NSFontAttributeName
value:firstNameFont
range:NSMakeRange(0, contact.firstName.length)];
[fullNameAttributedString addAttribute:NSFontAttributeName
value:lastNameFont
range:NSMakeRange(contact.firstName.length + 1, contact.lastName.length)];
[fullNameAttributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor blackColor]
range:NSMakeRange(0, contact.fullName.length)];
if (ABPersonGetSortOrdering() == kABPersonCompositeNameFormatFirstNameFirst) {
[fullNameAttributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor ows_darkGrayColor]
range:NSMakeRange(contact.firstName.length + 1, contact.lastName.length)];
} else {
[fullNameAttributedString addAttribute:NSForegroundColorAttributeName
value:[UIColor ows_darkGrayColor]
range:NSMakeRange(0, contact.firstName.length)];
}
return fullNameAttributedString;
}
@end
NS_ASSUME_NONNULL_END

@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)configureWithContact:(Contact *)contact contactsManager:(OWSContactsManager *)contactsManager
{
self.nameLabel.attributedText = [self attributedStringForContact:contact];
self.nameLabel.attributedText = [contactsManager formattedFullNameForContact:contact font:self.nameLabel.font];
self.avatarView.image =
[[[OWSContactAvatarBuilder alloc] initWithContactId:contact.textSecureIdentifiers.firstObject
name:contact.fullName
@ -39,58 +39,6 @@ NS_ASSUME_NONNULL_BEGIN
[UIUtil applyRoundedBorderToImageView:self.avatarView];
}
- (NSAttributedString *)attributedStringForContact:(Contact *)contact {
NSDictionary<NSString *, id> *boldFontAttributes = @{
NSFontAttributeName : [UIFont ows_mediumFontWithSize:self.nameLabel.font.pointSize],
NSForegroundColorAttributeName : [UIColor blackColor]
};
NSDictionary<NSString *, id> *normalFontAttributes = @{
NSFontAttributeName : [UIFont ows_regularFontWithSize:self.nameLabel.font.pointSize],
NSForegroundColorAttributeName : [UIColor ows_darkGrayColor]
};
NSAttributedString *_Nullable firstName, *_Nullable lastName;
if (ABPersonGetSortOrdering() == kABPersonSortByFirstName) {
if (contact.firstName) {
firstName = [[NSAttributedString alloc] initWithString:contact.firstName attributes:boldFontAttributes];
}
if (contact.lastName) {
lastName = [[NSAttributedString alloc] initWithString:contact.lastName attributes:normalFontAttributes];
}
} else {
if (contact.firstName) {
firstName = [[NSAttributedString alloc] initWithString:contact.firstName attributes:normalFontAttributes];
}
if (contact.lastName) {
lastName = [[NSAttributedString alloc] initWithString:contact.lastName attributes:boldFontAttributes];
}
}
NSAttributedString *_Nullable leftName, *_Nullable rightName;
if (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst) {
leftName = firstName;
rightName = lastName;
} else {
leftName = lastName;
rightName = firstName;
}
NSMutableAttributedString *fullNameString = [NSMutableAttributedString new];
if (leftName) {
[fullNameString appendAttributedString:leftName];
}
if (leftName && rightName) {
[fullNameString appendAttributedString:[[NSAttributedString alloc] initWithString:@" "]];
}
if (rightName) {
[fullNameString appendAttributedString:rightName];
}
return fullNameString;
}
@end
NS_ASSUME_NONNULL_END

Loading…
Cancel
Save