Use profile name/image when available.

Refactored the ContactAvatarBuilder to clarify intent of the two
methods. One is only used for non-signal contacts in the Invite flow.
The other should be used for any signal contacts so we have a single
consistent way of generating the avatar initials.

// FREEBIE
This commit is contained in:
Michael Kirk 2017-08-07 15:46:18 -04:00
parent 8f54df0ff9
commit 16c646a939
6 changed files with 83 additions and 42 deletions

View file

@ -20,7 +20,8 @@ NS_ASSUME_NONNULL_BEGIN
{
OWSAvatarBuilder *avatarBuilder;
if ([thread isKindOfClass:[TSContactThread class]]) {
avatarBuilder = [[OWSContactAvatarBuilder alloc] initWithThread:(TSContactThread *)thread contactsManager:contactsManager diameter:diameter];
TSContactThread *contactThread = (TSContactThread *)thread;
avatarBuilder = [[OWSContactAvatarBuilder alloc] initWithSignalId:contactThread.contactIdentifier diameter:diameter contactsManager:contactsManager];
} else if ([thread isKindOfClass:[TSGroupThread class]]) {
avatarBuilder = [[OWSGroupAvatarBuilder alloc] initWithThread:(TSGroupThread *)thread];
} else {

View file

@ -11,14 +11,21 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSContactAvatarBuilder : OWSAvatarBuilder
- (instancetype)initWithContactId:(NSString *)contactId
name:(NSString *)name
contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter;
/**
* Build an avatar for a Signal recipient
*/
- (instancetype)initWithSignalId:(NSString *)signalId
diameter:(NSUInteger)diameter
contactsManager:(OWSContactsManager *)contactsManager;
/**
* Build an avatar for a non-Signal recipient
*/
- (instancetype)initWithNonSignalName:(NSString *)nonSignalName
colorSeed:(NSString *)colorSeed
diameter:(NSUInteger)diameter
contactsManager:(OWSContactsManager *)contactsManager;
- (instancetype)initWithThread:(TSContactThread *)thread
contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter;
@end

View file

@ -24,10 +24,12 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSContactAvatarBuilder
#pragma mark - Initializers
- (instancetype)initWithContactId:(NSString *)contactId
name:(NSString *)name
contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter
contactsManager:(OWSContactsManager *)contactsManager
{
self = [super init];
if (!self) {
@ -36,19 +38,30 @@ NS_ASSUME_NONNULL_BEGIN
_signalId = contactId;
_contactName = name;
_contactsManager = contactsManager;
_diameter = diameter;
_contactsManager = contactsManager;
return self;
}
- (instancetype)initWithThread:(TSContactThread *)thread
contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter
- (instancetype)initWithSignalId:(NSString *)signalId
diameter:(NSUInteger)diameter
contactsManager:(OWSContactsManager *)contactsManager
{
return [self initWithContactId:thread.contactIdentifier name:thread.name contactsManager:contactsManager diameter:diameter];
NSString *name = [contactsManager displayNameForPhoneIdentifier:signalId];
return [self initWithContactId:signalId name:name diameter:diameter contactsManager:contactsManager];
}
- (instancetype)initWithNonSignalName:(NSString *)nonSignalName
colorSeed:(NSString *)colorSeed
diameter:(NSUInteger)diameter
contactsManager:(OWSContactsManager *)contactsManager
{
return [self initWithContactId:colorSeed name:nonSignalName diameter:diameter contactsManager:contactsManager];
}
#pragma mark - Instance methods
- (nullable UIImage *)buildSavedImage
{
return [self.contactsManager imageForPhoneIdentifier:self.signalId];

View file

@ -206,13 +206,19 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account
self.signalAccountMap = [signalAccountMap copy];
self.signalAccounts = [signalAccounts copy];
[OWSProfileManager.sharedManager setContactRecipientIds:signalAccountMap.allKeys];
[self.profileManager setContactRecipientIds:signalAccountMap.allKeys];
[self updateCachedDisplayNames];
});
});
}
// TODO dependency inject, avoid circular dependencies.
- (OWSProfileManager *)profileManager
{
return [OWSProfileManager sharedManager];
}
- (void)updateCachedDisplayNames
{
OWSAssert([NSThread isMainThread]);
@ -405,10 +411,19 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account
return self.unknownContactName;
}
NSString *displayName = [self cachedDisplayNameForRecipientId:recipientId];
// Prefer a saved name from system contacts, if available
NSString *_Nullable displayName = [self cachedDisplayNameForRecipientId:recipientId];
// Else try to use their profile name
if (displayName.length < 1) {
displayName = [self.profileManager profileNameForRecipientId:recipientId];
}
// Else fall back to just using their recipientId
if (displayName.length < 1) {
displayName = recipientId;
}
return displayName;
}
@ -475,9 +490,19 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account
[formattedName appendAttributedString:[[NSAttributedString alloc] initWithString:cachedLastName
attributes:lastNameAttributes]];
} else {
return [[NSAttributedString alloc]
initWithString:[PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:recipientId]
attributes:normalFontAttributes];
// If there's no name saved in our contacts, try their profile.
// TODO we might want to format this specially.
NSString *_Nullable profileName = [self.profileManager profileNameForRecipientId:recipientId];
if (profileName.length < 1) {
// Else, fall back to using just their recipientId
NSString *phoneString = [PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:recipientId];
return [[NSAttributedString alloc] initWithString:phoneString
attributes:normalFontAttributes];
}
[formattedName appendAttributedString:[[NSAttributedString alloc] initWithString:profileName
attributes:lastNameAttributes]];
}
SignalAccount *signalAccount = [self signalAccountForRecipientId:recipientId];
@ -520,7 +545,15 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account
- (UIImage * _Nullable)imageForPhoneIdentifier:(NSString * _Nullable)identifier {
Contact *contact = self.allContactsMap[identifier];
return contact.image;
// Prefer the contact image from the local address book if available
UIImage *_Nullable image = contact.image;
// Else try to use the image from their profile
if (image == nil) {
image = [self.profileManager profileAvatarForRecipientId:identifier];
}
return image;
}
#pragma mark - Logging

View file

@ -61,10 +61,11 @@ class ContactCell: UITableViewCell {
}
let kAvatarWidth: UInt = 40
let avatarBuilder = OWSContactAvatarBuilder(contactId:contactIdForDeterminingBackgroundColor,
name:contact.fullName,
contactsManager:contactsManager,
diameter: kAvatarWidth)
let avatarBuilder = OWSContactAvatarBuilder(nonSignalName: contact.fullName,
colorSeed: contactIdForDeterminingBackgroundColor,
diameter: kAvatarWidth,
contactsManager:contactsManager)
self.contactImageView?.image = avatarBuilder.buildDefaultImage()
} else {
self.contactImageView?.image = contact.image

View file

@ -81,26 +81,13 @@ const NSUInteger kContactTableViewCellAvatarSize = 40;
- (void)configureWithSignalAccount:(SignalAccount *)signalAccount contactsManager:(OWSContactsManager *)contactsManager
{
[self configureWithRecipientId:signalAccount.recipientId
avatarName:signalAccount.contact.fullName
displayName:[contactsManager formattedDisplayNameForSignalAccount:signalAccount
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
{
NSAttributedString *displayName = [contactsManager formattedFullNameForRecipientId:recipientId font:self.nameLabel.font];
NSMutableAttributedString *attributedText = [displayName mutableCopy];
if (self.accessoryMessage) {
UILabel *blockedLabel = [[UILabel alloc] init];
@ -113,10 +100,9 @@ const NSUInteger kContactTableViewCellAvatarSize = 40;
self.accessoryView = blockedLabel;
}
self.nameLabel.attributedText = attributedText;
self.avatarView.image = [[[OWSContactAvatarBuilder alloc] initWithContactId:recipientId
name:avatarName
contactsManager:contactsManager
diameter:kContactTableViewCellAvatarSize] build];
self.avatarView.image = [[[OWSContactAvatarBuilder alloc] initWithSignalId:recipientId
diameter:kContactTableViewCellAvatarSize
contactsManager:contactsManager] build];
// Force layout, since imageView isn't being initally rendered on App Store optimized build.
[self layoutSubviews];