diff --git a/Podfile b/Podfile index 55d7dcd08..624665393 100644 --- a/Podfile +++ b/Podfile @@ -5,8 +5,8 @@ target 'Signal' do pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git' pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git' #pod 'AxolotlKit', path: '../SignalProtocolKit' - pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git' - #pod 'SignalServiceKit', path: '../SignalServiceKit' + #pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git' + pod 'SignalServiceKit', path: '../SignalServiceKit' pod 'OpenSSL' pod 'JSQMessagesViewController', git: 'https://github.com/WhisperSystems/JSQMessagesViewController.git', branch: 'mkirk/position-edit-menu' #pod 'JSQMessagesViewController' path: '../JSQMessagesViewController' diff --git a/Podfile.lock b/Podfile.lock index a8256922a..4b8ae2071 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -114,7 +114,7 @@ DEPENDENCIES: - OpenSSL - PureLayout - Reachability - - SignalServiceKit (from `https://github.com/WhisperSystems/SignalServiceKit.git`) + - SignalServiceKit (from `../SignalServiceKit`) - SocketRocket (from `https://github.com/facebook/SocketRocket.git`) EXTERNAL SOURCES: @@ -124,7 +124,7 @@ EXTERNAL SOURCES: :branch: mkirk/position-edit-menu :git: https://github.com/WhisperSystems/JSQMessagesViewController.git SignalServiceKit: - :git: https://github.com/WhisperSystems/SignalServiceKit.git + :path: ../SignalServiceKit SocketRocket: :git: https://github.com/facebook/SocketRocket.git @@ -135,9 +135,6 @@ CHECKOUT OPTIONS: JSQMessagesViewController: :commit: 7054e4b13ee5bcd6d524adb6dc9a726e8c466308 :git: https://github.com/WhisperSystems/JSQMessagesViewController.git - SignalServiceKit: - :commit: 33a2b05dcaa0ccfe94db12f0e7f0cdf6e861bddf - :git: https://github.com/WhisperSystems/SignalServiceKit.git SocketRocket: :commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf :git: https://github.com/facebook/SocketRocket.git @@ -164,6 +161,6 @@ SPEC CHECKSUMS: UnionFind: c33be5adb12983981d6e827ea94fc7f9e370f52d YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266 -PODFILE CHECKSUM: 48e80d7f1e049bbf544a689fdfdf33e8196c640a +PODFILE CHECKSUM: 6f9ef5d9fa17469569e127a9f5719dafa11631b9 COCOAPODS: 1.2.1 diff --git a/Signal/src/contact/OWSContactsManager.m b/Signal/src/contact/OWSContactsManager.m index 7636db0c3..0659a4672 100644 --- a/Signal/src/contact/OWSContactsManager.m +++ b/Signal/src/contact/OWSContactsManager.m @@ -9,12 +9,15 @@ #import #import #import +#import @import Contacts; NSString *const OWSContactsManagerSignalAccountsDidChangeNotification = @"OWSContactsManagerSignalAccountsDidChangeNotification"; +NSString *const kTSStorageManager_ContactNames = @"kTSStorageManager_ContactNames"; + @interface OWSContactsManager () @property (atomic) id addressBookReference; @@ -191,11 +194,44 @@ NSString *const OWSContactsManagerSignalAccountsDidChangeNotification = [[NSNotificationCenter defaultCenter] postNotificationName:OWSContactsManagerSignalAccountsDidChangeNotification object:nil]; + + [self updateCachedDisplayNames]; }); }); } +- (void)updateCachedDisplayNames +{ + OWSAssert([NSThread isMainThread]); + + NSMutableDictionary *accountNameMap = [NSMutableDictionary new]; + for (SignalAccount *signalAccount in self.signalAccounts) { + NSString *displayName = [self displayNameForSignalAccount:signalAccount]; + if (![displayName isEqualToString:signalAccount.recipientId]) { + accountNameMap[signalAccount.recipientId] = displayName; + } + } + + dispatch_async(dispatch_get_main_queue(), ^{ + [TSStorageManager.sharedManager.newDatabaseConnection + readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + for (NSString *recipientId in accountNameMap) { + NSString *displayName = accountNameMap[recipientId]; + [transaction setObject:displayName forKey:recipientId inCollection:kTSStorageManager_ContactNames]; + } + }]; + }); +} + +- (NSString *_Nullable)cachedDisplayNameForRecipientId:(NSString *)recipientId +{ + OWSAssert(recipientId.lastPathComponent > 0); + + return [[TSStorageManager sharedManager] objectForKey:recipientId inCollection:kTSStorageManager_ContactNames]; +} + #pragma mark - View Helpers + // TODO move into Contact class. + (NSString *)accountLabelForContact:(Contact *)contact recipientId:(NSString *)recipientId { @@ -245,16 +281,23 @@ NSString *const OWSContactsManagerSignalAccountsDidChangeNotification = @"Displayed if for some reason we can't determine a contacts phone number *or* name"); } -- (NSString * _Nonnull)displayNameForPhoneIdentifier:(NSString * _Nullable)identifier { - if (!identifier) { +- (NSString *_Nonnull)displayNameForPhoneIdentifier:(NSString *_Nullable)recipientId +{ + if (!recipientId) { return self.unknownContactName; } // When viewing an old thread with someone who is no longer a Signal user, they won't have a SignalAccount // so we get the name from `allContactsMap` as opposed to `signalAccountForRecipientId`. - Contact *contact = self.allContactsMap[identifier]; + Contact *contact = self.allContactsMap[recipientId]; - NSString *displayName = (contact.fullName.length > 0) ? contact.fullName : identifier; + NSString *displayName = contact.fullName; + if (displayName.length < 1) { + displayName = [self cachedDisplayNameForRecipientId:recipientId]; + } + if (displayName.length < 1) { + displayName = recipientId; + } return displayName; } diff --git a/Signal/src/environment/NotificationsManager.m b/Signal/src/environment/NotificationsManager.m index f7de7f453..08133db67 100644 --- a/Signal/src/environment/NotificationsManager.m +++ b/Signal/src/environment/NotificationsManager.m @@ -146,7 +146,6 @@ } - (void)notifyUserForIncomingMessage:(TSIncomingMessage *)message - from:(NSString *)name inThread:(TSThread *)thread contactsManager:(id)contactsManager { @@ -155,6 +154,11 @@ } NSString *messageDescription = message.description; + NSString *senderName = [contactsManager displayNameForPhoneIdentifier:message.authorId]; + NSString *groupName = [thread.name stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + if (groupName.length < 1) { + groupName = NSLocalizedString(@"UNNAMED_GROUP_NAME", @"Named used for groups without a name."); + } if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive && messageDescription) { UILocalNotification *notification = [[UILocalNotification alloc] init]; @@ -167,25 +171,25 @@ @{Signal_Thread_UserInfo_Key : thread.uniqueId, Signal_Message_UserInfo_Key : message.uniqueId}; if ([thread isGroupThread]) { - NSString *sender = [contactsManager displayNameForPhoneIdentifier:message.authorId]; - NSString *threadName = [NSString stringWithFormat:@"\"%@\"", name]; + NSString *threadName = [NSString stringWithFormat:@"\"%@\"", groupName]; + // TODO: Format parameters might change order in l10n. We should use named parameters. notification.alertBody = [NSString stringWithFormat:NSLocalizedString(@"APN_MESSAGE_IN_GROUP_DETAILED", nil), - sender, - threadName, - messageDescription]; + senderName, + threadName, + messageDescription]; } else { - notification.alertBody = [NSString stringWithFormat:@"%@: %@", name, messageDescription]; + notification.alertBody = [NSString stringWithFormat:@"%@: %@", senderName, messageDescription]; } break; case NotificationNameNoPreview: { notification.userInfo = @{Signal_Thread_UserInfo_Key : thread.uniqueId}; if ([thread isGroupThread]) { - notification.alertBody = - [NSString stringWithFormat:@"%@ \"%@\"", NSLocalizedString(@"APN_MESSAGE_IN_GROUP", nil), name]; + notification.alertBody = [NSString + stringWithFormat:@"%@ \"%@\"", NSLocalizedString(@"APN_MESSAGE_IN_GROUP", nil), groupName]; } else { notification.alertBody = - [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"APN_MESSAGE_FROM", nil), name]; + [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"APN_MESSAGE_FROM", nil), senderName]; } break; } diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 1d9df0ede..a4a3c10b6 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1297,6 +1297,9 @@ /* Label text in device manager for a device with no name */ "UNNAMED_DEVICE" = "Unnamed Device"; +/* Named used for groups without a name. */ +"UNNAMED_GROUP_NAME" = "Unnamed Group"; + /* No comment provided by engineer. */ "UNREGISTER_SIGNAL_FAIL" = "Failed to unregister from Signal.";