Merge branch 'mkirk/clarify-profile-name-use'

pull/1/head
Michael Kirk 7 years ago
commit 26f9c7ad00

@ -97,6 +97,8 @@
34F3089F1ECA580B00BB7697 /* OWSUnreadIndicatorCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F3089E1ECA580B00BB7697 /* OWSUnreadIndicatorCell.m */; };
34F308A21ECB469700BB7697 /* OWSBezierPathView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34F308A11ECB469700BB7697 /* OWSBezierPathView.m */; };
34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */; };
450449391F45EE7D002D1ADA /* NSString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 450449381F45EE7D002D1ADA /* NSString+OWS.m */; };
4504493A1F45EE7D002D1ADA /* NSString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 450449381F45EE7D002D1ADA /* NSString+OWS.m */; };
450573FE1E78A06D00615BB4 /* OWS103EnableVideoCalling.m in Sources */ = {isa = PBXBuildFile; fileRef = 450573FD1E78A06D00615BB4 /* OWS103EnableVideoCalling.m */; };
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4505C2BE1E648EA300CEBF41 /* ExperienceUpgrade.swift */; };
4505C2C01E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4505C2BE1E648EA300CEBF41 /* ExperienceUpgrade.swift */; };
@ -548,6 +550,8 @@
34F308A11ECB469700BB7697 /* OWSBezierPathView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBezierPathView.m; sourceTree = "<group>"; };
34FD936E1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSAnyTouchGestureRecognizer.h; path = views/OWSAnyTouchGestureRecognizer.h; sourceTree = "<group>"; };
34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSAnyTouchGestureRecognizer.m; path = views/OWSAnyTouchGestureRecognizer.m; sourceTree = "<group>"; };
450449371F45EE7D002D1ADA /* NSString+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSString+OWS.h"; path = "util/NSString+OWS.h"; sourceTree = "<group>"; };
450449381F45EE7D002D1ADA /* NSString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSString+OWS.m"; path = "util/NSString+OWS.m"; sourceTree = "<group>"; };
450573FC1E78A06D00615BB4 /* OWS103EnableVideoCalling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWS103EnableVideoCalling.h; path = Migrations/OWS103EnableVideoCalling.h; sourceTree = "<group>"; };
450573FD1E78A06D00615BB4 /* OWS103EnableVideoCalling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWS103EnableVideoCalling.m; path = Migrations/OWS103EnableVideoCalling.m; sourceTree = "<group>"; };
4505C2BE1E648EA300CEBF41 /* ExperienceUpgrade.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ExperienceUpgrade.swift; path = ExperienceUpgrades/ExperienceUpgrade.swift; sourceTree = "<group>"; };
@ -1775,6 +1779,8 @@
45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */,
45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */,
45638BDE1F3DDB2200128435 /* MessageSender+Promise.swift */,
450449371F45EE7D002D1ADA /* NSString+OWS.h */,
450449381F45EE7D002D1ADA /* NSString+OWS.m */,
);
name = "UI Categories";
path = ..;
@ -2223,6 +2229,7 @@
45638BDC1F3DD0D400128435 /* DebugUICalling.swift in Sources */,
76EB058218170B33006006FC /* Environment.m in Sources */,
34B3F8921E8DF1710035BE1A /* SignalAttachment.swift in Sources */,
450449391F45EE7D002D1ADA /* NSString+OWS.m in Sources */,
45464DBC1DFA041F001D3FD6 /* DataChannelMessage.swift in Sources */,
34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */,
3448BFCF1EDF0EA7005B2D69 /* OWSMessagesComposerTextView.m in Sources */,
@ -2367,6 +2374,7 @@
45F170AF1E2F0393003FC1F2 /* CallAudioSessionTest.swift in Sources */,
34B3F8991E8DF1B90035BE1A /* TSMessageAdapterTest.m in Sources */,
456F6E231E24133500FD2210 /* Platform.swift in Sources */,
4504493A1F45EE7D002D1ADA /* NSString+OWS.m in Sources */,
45843D201D2236B30013E85A /* OWSContactsSearcher.m in Sources */,
45AE48521E0732D6004D96C2 /* TurnServerInfo.swift in Sources */,
450873C41D9D5149006B54F2 /* OWSExpirationTimerView.m in Sources */,

@ -4,6 +4,7 @@
#import "OWSProfileManager.h"
#import "Environment.h"
#import "NSString+OWS.h"
#import "Signal-Swift.h"
#import <SignalServiceKit/Cryptography.h>
#import <SignalServiceKit/NSData+hexString.h>
@ -59,6 +60,11 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (void)setProfileName:(nullable NSString *)profileName
{
_profileName = [profileName ows_stripped];
}
#pragma mark - NSObject
- (BOOL)isEqual:(UserProfile *)other
@ -1161,7 +1167,6 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
{
OWSAssert(filename.length > 0);
NSString *filePath = [self.profileAvatarsDirPath stringByAppendingPathComponent:filename];
UIImage *_Nullable image = [UIImage imageWithData:[self loadProfileDataWithFilename:filename]];
return image;
}

@ -1932,10 +1932,7 @@ typedef enum : NSUInteger {
}
} else if (message.messageType == TSIncomingMessageAdapter && [self.thread isKindOfClass:[TSGroupThread class]]) {
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)message.interaction;
NSString *_Nonnull name = [self.contactsManager displayNameForPhoneIdentifier:incomingMessage.authorId];
NSAttributedString *senderNameString = [[NSAttributedString alloc] initWithString:name];
return senderNameString;
return [self.contactsManager attributedStringForMessageFooterWithPhoneIdentifier:incomingMessage.authorId];
}
return nil;

@ -51,11 +51,14 @@ extern NSString *const OWSContactsManagerSignalAccountsDidChangeNotification;
#pragma mark - Util
- (BOOL)hasNameInSystemContactsForRecipientId:(NSString *)recipientId;
- (NSString *)displayNameForPhoneIdentifier:(nullable NSString *)identifier;
- (NSString *)displayNameForSignalAccount:(SignalAccount *)signalAccount;
- (nullable NSString *)formattedProfileNameForRecipientId:(NSString *)recipientId;
- (nullable UIImage *)imageForPhoneIdentifier:(nullable NSString *)identifier;
- (NSAttributedString *)formattedDisplayNameForSignalAccount:(SignalAccount *)signalAccount font:(UIFont *_Nonnull)font;
- (NSAttributedString *)formattedFullNameForRecipientId:(NSString *)recipientId font:(UIFont *)font;
- (NSAttributedString *)attributedStringForMessageFooterWithPhoneIdentifier:(NSString *)recipientId;
@end

@ -399,12 +399,30 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account
#pragma mark - Whisper User Management
- (BOOL)hasNameInSystemContactsForRecipientId:(NSString *)recipientId
{
return [self cachedDisplayNameForRecipientId:recipientId] != nil;
}
- (NSString *)unknownContactName
{
return NSLocalizedString(@"UNKNOWN_CONTACT_NAME",
@"Displayed if for some reason we can't determine a contacts phone number *or* name");
}
- (nullable NSString *)formattedProfileNameForRecipientId:(NSString *)recipientId
{
NSString *_Nullable profileName = [self.profileManager profileNameForRecipientId:recipientId];
if (profileName.length == 0) {
return nil;
}
NSString *profileNameFormatString = NSLocalizedString(@"PROFILE_NAME_LABEL_FORMAT",
@"Prepend a simple marker to differentiate the profile name, embeds the contact's {{profile name}}.");
return [NSString stringWithFormat:profileNameFormatString, profileName];
}
- (NSString *_Nonnull)displayNameForPhoneIdentifier:(NSString *_Nullable)recipientId
{
if (!recipientId) {
@ -414,11 +432,6 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account
// 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;
@ -490,21 +503,13 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account
[formattedName appendAttributedString:[[NSAttributedString alloc] initWithString:cachedLastName
attributes:lastNameAttributes]];
} else {
// 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]];
// Else, fall back to using just their recipientId
NSString *phoneString =
[PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:recipientId];
return [[NSAttributedString alloc] initWithString:phoneString attributes:normalFontAttributes];
}
// Append unique label for contacts with multiple Signal accounts
SignalAccount *signalAccount = [self signalAccountForRecipientId:recipientId];
if (signalAccount && signalAccount.multipleAccountLabelText) {
OWSAssert(signalAccount.multipleAccountLabelText.length > 0);
@ -521,6 +526,30 @@ NSString *const kTSStorageManager_AccountLastNames = @"kTSStorageManager_Account
return formattedName;
}
- (NSAttributedString *)attributedStringForMessageFooterWithPhoneIdentifier:(NSString *)recipientId
{
// Prefer a saved name from system contacts, if available
NSString *_Nullable savedContactName = [self cachedDisplayNameForRecipientId:recipientId];
if (savedContactName.length > 0) {
return [[NSAttributedString alloc] initWithString:savedContactName];
}
NSString *_Nullable profileName = [self.profileManager profileNameForRecipientId:recipientId];
if (profileName.length > 0) {
NSString *numberAndProfileNameFormat = NSLocalizedString(@"PROFILE_NAME_AND_PHONE_NUMBER_LABEL_FORMAT",
@"Label text combining the phone number and profile name separated by a simple demarcation character. "
@"Phone number should be most prominent. '%1$@' is replaced with {{phone number}} and '%2$@' is replaced "
@"with {{profile name}}");
NSString *numberAndProfileName =
[NSString stringWithFormat:numberAndProfileNameFormat, recipientId, profileName];
return [[NSAttributedString alloc] initWithString:numberAndProfileName];
}
// else fall back to recipient id
return [[NSAttributedString alloc] initWithString:recipientId];
}
- (nullable SignalAccount *)signalAccountForRecipientId:(NSString *)recipientId
{
OWSAssert(recipientId.length > 0);

@ -0,0 +1,11 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSString (OWS)
- (NSString *)ows_stripped;
@end

@ -0,0 +1,14 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "NSString+OWS.h"
@implementation NSString (OWS)
- (NSString *)ows_stripped
{
return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
@end

@ -22,6 +22,7 @@ const NSUInteger kContactTableViewCellAvatarSize = 40;
@interface ContactTableViewCell ()
@property (nonatomic) IBOutlet UILabel *nameLabel;
@property (nonatomic) IBOutlet UILabel *profileNameLabel;
@property (nonatomic) IBOutlet UIImageView *avatarView;
@property (nonatomic, nullable) UILabel *subtitle;
@ -60,19 +61,37 @@ const NSUInteger kContactTableViewCellAvatarSize = 40;
_avatarView = [AvatarImageView new];
[self.contentView addSubview:_avatarView];
UIView *nameContainerView = [UIView containerView];
[self.contentView addSubview:nameContainerView];
_nameLabel = [UILabel new];
_nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
_nameLabel.font = [UIFont ows_dynamicTypeBodyFont];
[self.contentView addSubview:_nameLabel];
[nameContainerView addSubview:_nameLabel];
_profileNameLabel = [UILabel new];
_profileNameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
_profileNameLabel.font = [UIFont ows_footnoteFont];
_profileNameLabel.textColor = [UIColor grayColor];
[nameContainerView addSubview:_profileNameLabel];
[_avatarView autoVCenterInSuperview];
[_avatarView autoPinLeadingToSuperView];
[_avatarView autoSetDimension:ALDimensionWidth toSize:kContactTableViewCellAvatarSize];
[_avatarView autoSetDimension:ALDimensionHeight toSize:kContactTableViewCellAvatarSize];
[_nameLabel autoVCenterInSuperview];
[_nameLabel autoPinLeadingToTrailingOfView:_avatarView margin:12.f];
[_nameLabel autoPinTrailingToSuperView];
[_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeTop];
[_nameLabel autoPinWidthToSuperview];
// profileNameLabel can be zero sized, in which case nameLabel essentially occupies the totality of
// nameContainerView's frame.
[_profileNameLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_nameLabel];
[_profileNameLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[_profileNameLabel autoPinWidthToSuperview];
[nameContainerView autoVCenterInSuperview];
[nameContainerView autoPinLeadingToTrailingOfView:_avatarView margin:12.f];
[nameContainerView autoPinTrailingToSuperView];
// Force layout, since imageView isn't being initally rendered on App Store optimized build.
[self layoutSubviews];
@ -87,8 +106,17 @@ const NSUInteger kContactTableViewCellAvatarSize = 40;
- (void)configureWithRecipientId:(NSString *)recipientId
contactsManager:(OWSContactsManager *)contactsManager
{
NSAttributedString *displayName = [contactsManager formattedFullNameForRecipientId:recipientId font:self.nameLabel.font];
NSMutableAttributedString *attributedText = [displayName mutableCopy];
self.nameLabel.attributedText =
[contactsManager formattedFullNameForRecipientId:recipientId font:self.nameLabel.font];
if ([contactsManager hasNameInSystemContactsForRecipientId:recipientId]) {
// Don't display profile name when we have a veritas name in system Contacts
self.profileNameLabel.text = nil;
} else {
// Use profile name, if any is available
self.profileNameLabel.text = [contactsManager formattedProfileNameForRecipientId:recipientId];
}
if (self.accessoryMessage) {
UILabel *blockedLabel = [[UILabel alloc] init];
blockedLabel.textAlignment = NSTextAlignmentRight;
@ -99,7 +127,7 @@ const NSUInteger kContactTableViewCellAvatarSize = 40;
self.accessoryView = blockedLabel;
}
self.nameLabel.attributedText = attributedText;
self.avatarView.image = [[[OWSContactAvatarBuilder alloc] initWithSignalId:recipientId
diameter:kContactTableViewCellAvatarSize
contactsManager:contactsManager] build];

@ -1060,6 +1060,12 @@
/* No comment provided by engineer. */
"PROCEED_BUTTON" = "Proceed";
/* Label text combining the phone number and profile name separated by a simple demarcation character. Phone number should be most prominent. '%1$@' is replaced with {{phone number}} and '%2$@' is replaced with {{profile name}} */
"PROFILE_NAME_AND_PHONE_NUMBER_LABEL_FORMAT" = "%1$@ ~%2$@";
/* Prepend a simple marker to differentiate the profile name, embeds the contact's {{profile name}}. */
"PROFILE_NAME_LABEL_FORMAT" = "~%@";
/* Action Sheet title prompting the user for a profile avatar */
"PROFILE_VIEW_AVATAR_ACTIONSHEET_TITLE" = "Set Profile Avatar";

Loading…
Cancel
Save