Merge pull request #1238 from WhisperSystems/missing-call-button

Fix: No Call icon for registered Signal contact
pull/1/head
Michael Kirk 8 years ago committed by GitHub
commit e3d94db17c

@ -43,7 +43,7 @@ PODS:
- ProtocolBuffers (1.9.10)
- Reachability (3.2)
- SCWaveformView (1.0.0)
- SignalServiceKit (0.0.4):
- SignalServiceKit (0.0.5):
- '25519'
- AFNetworking
- AxolotlKit
@ -137,7 +137,7 @@ CHECKOUT OPTIONS:
:commit: 225b1baa11125ea84d4b960d700834b5b0a40ee1
:git: https://github.com/WhisperSystems/JSQMessagesViewController
SignalServiceKit:
:commit: 8058951b08a9fb0c610c56bdb50c403132da2089
:commit: 80671b247f616c3bd6264eccce5f806a4a538e68
:git: https://github.com/WhisperSystems/SignalServiceKit.git
SocketRocket:
:commit: 587ad297eb63eb0d64d4caeb32a7da646ad1132b
@ -160,7 +160,7 @@ SPEC CHECKSUMS:
ProtocolBuffers: d088180c10072b3d24a9939a6314b7b9bcc2340b
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SCWaveformView: 52a96750255d817e300565a80c81fb643e233e07
SignalServiceKit: e27a3025c2d5c61696386e44a50ac8d2fe83151e
SignalServiceKit: f52bc6e17f717540d93b4247a93246648bf4085e
SocketRocket: 3f77ec2104cc113add553f817ad90a77114f5d43
SQLCipher: 4c768761421736a247ed6cf412d9045615d53dff
SSKeychain: c71293fa57216a40ab06c23f4085387583293de4

@ -9,6 +9,9 @@
/* Begin PBXBuildFile section */
0DD55B166906AF3368995978 /* libPods-Signal.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 80CD5E19DD23200E7926EEA7 /* libPods-Signal.a */; };
30209C98DABCE82064B4EAF5 /* libPods-SignalTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A33D3C7EB4B17BDBD47F0FCC /* libPods-SignalTests.a */; };
45843D1F1D2236B30013E85A /* OWSContactsSearcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 45843D1E1D2236B30013E85A /* OWSContactsSearcher.m */; };
45843D201D2236B30013E85A /* OWSContactsSearcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 45843D1E1D2236B30013E85A /* OWSContactsSearcher.m */; };
45843D221D223BA10013E85A /* OWSContactsSearcherTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 45843D211D223BA10013E85A /* OWSContactsSearcherTest.m */; };
45CB2FA81CB7146C00E1B343 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 45CB2FA71CB7146C00E1B343 /* Launch Screen.storyboard */; };
4CE0E3771B954546007210CF /* TSAnimatedAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CE0E3761B954546007210CF /* TSAnimatedAdapter.m */; };
701231B518ECAA4500D456C4 /* EvpMessageDigest.m in Sources */ = {isa = PBXBuildFile; fileRef = 701231B418ECAA4500D456C4 /* EvpMessageDigest.m */; };
@ -24,7 +27,7 @@
76EB054018170B33006006FC /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB03C318170B33006006FC /* AppDelegate.m */; };
76EB057218170B33006006FC /* RecentCall.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040018170B33006006FC /* RecentCall.m */; };
76EB057418170B33006006FC /* RecentCallManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040218170B33006006FC /* RecentCallManager.m */; };
76EB057A18170B33006006FC /* ContactsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040918170B33006006FC /* ContactsManager.m */; };
76EB057A18170B33006006FC /* OWSContactsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040918170B33006006FC /* OWSContactsManager.m */; };
76EB058218170B33006006FC /* Environment.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB041318170B33006006FC /* Environment.m */; };
76EB058418170B33006006FC /* LocalizableText.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB041518170B33006006FC /* LocalizableText.m */; };
76EB058618170B33006006FC /* PreferencesUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB041718170B33006006FC /* PreferencesUtil.m */; };
@ -172,7 +175,7 @@
B660F6B81C29868000687D6E /* JitterQueueTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6711C29867F00687D6E /* JitterQueueTest.m */; };
B660F6B91C29868000687D6E /* SpeexCodecTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6721C29867F00687D6E /* SpeexCodecTest.m */; };
B660F6BA1C29868000687D6E /* RecentCallTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6741C29867F00687D6E /* RecentCallTest.m */; };
B660F6BB1C29868000687D6E /* ContactManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6761C29867F00687D6E /* ContactManagerTest.m */; };
B660F6BB1C29868000687D6E /* OWSContactsManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6761C29867F00687D6E /* OWSContactsManagerTest.m */; };
B660F6BC1C29868000687D6E /* DnsManagerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F6791C29867F00687D6E /* DnsManagerTest.m */; };
B660F6BD1C29868000687D6E /* HttpRequestResponseTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F67B1C29867F00687D6E /* HttpRequestResponseTest.m */; };
B660F6BE1C29868000687D6E /* IpAddressTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B660F67C1C29867F00687D6E /* IpAddressTest.m */; };
@ -232,7 +235,7 @@
B660F7141C29988E00687D6E /* RecentCall.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040018170B33006006FC /* RecentCall.m */; };
B660F7151C29988E00687D6E /* RecentCallManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040218170B33006006FC /* RecentCallManager.m */; };
B660F7161C29988E00687D6E /* GroupContactsResult.m in Sources */ = {isa = PBXBuildFile; fileRef = B671B2451A93B238002BBD9D /* GroupContactsResult.m */; };
B660F7171C29988E00687D6E /* ContactsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040918170B33006006FC /* ContactsManager.m */; };
B660F7171C29988E00687D6E /* OWSContactsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 76EB040918170B33006006FC /* OWSContactsManager.m */; };
B660F7181C29988E00687D6E /* CryptoTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 7038632418F70C0700D4A43F /* CryptoTools.m */; };
B660F7191C29988E00687D6E /* EvpMessageDigest.m in Sources */ = {isa = PBXBuildFile; fileRef = 701231B418ECAA4500D456C4 /* EvpMessageDigest.m */; };
B660F71A1C29988E00687D6E /* EvpSymetricUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 7038632618F70C0700D4A43F /* EvpSymetricUtil.m */; };
@ -489,6 +492,9 @@
/* Begin PBXFileReference section */
453CC0361D08E1A60040EBA3 /* sn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sn; path = translations/sn.lproj/Localizable.strings; sourceTree = "<group>"; };
454B35071D08EED80026D658 /* mk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = mk; path = translations/mk.lproj/Localizable.strings; sourceTree = "<group>"; };
45843D1D1D2236B30013E85A /* OWSContactsSearcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactsSearcher.h; sourceTree = "<group>"; };
45843D1E1D2236B30013E85A /* OWSContactsSearcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsSearcher.m; sourceTree = "<group>"; };
45843D211D223BA10013E85A /* OWSContactsSearcherTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsSearcherTest.m; sourceTree = "<group>"; };
45CB2FA71CB7146C00E1B343 /* Launch Screen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = "Launch Screen.storyboard"; path = "Signal/src/util/Launch Screen.storyboard"; sourceTree = SOURCE_ROOT; };
45E282DE1D08E67800ADD4C8 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = translations/gl.lproj/Localizable.strings; sourceTree = "<group>"; };
45E282DF1D08E6CC00ADD4C8 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = translations/id.lproj/Localizable.strings; sourceTree = "<group>"; };
@ -515,8 +521,8 @@
76EB040018170B33006006FC /* RecentCall.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecentCall.m; sourceTree = "<group>"; };
76EB040118170B33006006FC /* RecentCallManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecentCallManager.h; sourceTree = "<group>"; };
76EB040218170B33006006FC /* RecentCallManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecentCallManager.m; sourceTree = "<group>"; };
76EB040818170B33006006FC /* ContactsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactsManager.h; sourceTree = "<group>"; };
76EB040918170B33006006FC /* ContactsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsManager.m; sourceTree = "<group>"; };
76EB040818170B33006006FC /* OWSContactsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSContactsManager.h; sourceTree = "<group>"; };
76EB040918170B33006006FC /* OWSContactsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsManager.m; sourceTree = "<group>"; };
76EB041218170B33006006FC /* Environment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Environment.h; sourceTree = "<group>"; };
76EB041318170B33006006FC /* Environment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Environment.m; sourceTree = "<group>"; };
76EB041418170B33006006FC /* LocalizableText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocalizableText.h; sourceTree = "<group>"; };
@ -786,7 +792,7 @@
B660F6711C29867F00687D6E /* JitterQueueTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JitterQueueTest.m; sourceTree = "<group>"; };
B660F6721C29867F00687D6E /* SpeexCodecTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SpeexCodecTest.m; sourceTree = "<group>"; };
B660F6741C29867F00687D6E /* RecentCallTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RecentCallTest.m; sourceTree = "<group>"; };
B660F6761C29867F00687D6E /* ContactManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactManagerTest.m; sourceTree = "<group>"; };
B660F6761C29867F00687D6E /* OWSContactsManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSContactsManagerTest.m; sourceTree = "<group>"; };
B660F6791C29867F00687D6E /* DnsManagerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DnsManagerTest.m; sourceTree = "<group>"; };
B660F67B1C29867F00687D6E /* HttpRequestResponseTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HttpRequestResponseTest.m; sourceTree = "<group>"; };
B660F67C1C29867F00687D6E /* IpAddressTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IpAddressTest.m; sourceTree = "<group>"; };
@ -1180,8 +1186,10 @@
isa = PBXGroup;
children = (
76EB04A818170B33006006FC /* number directory */,
76EB040818170B33006006FC /* ContactsManager.h */,
76EB040918170B33006006FC /* ContactsManager.m */,
76EB040818170B33006006FC /* OWSContactsManager.h */,
76EB040918170B33006006FC /* OWSContactsManager.m */,
45843D1D1D2236B30013E85A /* OWSContactsSearcher.h */,
45843D1E1D2236B30013E85A /* OWSContactsSearcher.m */,
);
path = contact;
sourceTree = "<group>";
@ -1781,7 +1789,8 @@
B660F6751C29867F00687D6E /* contact */ = {
isa = PBXGroup;
children = (
B660F6761C29867F00687D6E /* ContactManagerTest.m */,
B660F6761C29867F00687D6E /* OWSContactsManagerTest.m */,
45843D211D223BA10013E85A /* OWSContactsSearcherTest.m */,
);
path = contact;
sourceTree = "<group>";
@ -2587,13 +2596,14 @@
76EB061018170B33006006FC /* EventWindow.m in Sources */,
E197B62718BBF63B00F073E5 /* SoundBoard.m in Sources */,
76EB058418170B33006006FC /* LocalizableText.m in Sources */,
76EB057A18170B33006006FC /* ContactsManager.m in Sources */,
76EB057A18170B33006006FC /* OWSContactsManager.m in Sources */,
E197B61918BBEC1A00F073E5 /* RemoteIOBufferListWrapper.m in Sources */,
76EB05A618170B33006006FC /* RtpPacket.m in Sources */,
76EB064218170B33006006FC /* StringUtil.m in Sources */,
A547DD741A70A87800103EC7 /* DJWActionSheet+OWS.m in Sources */,
76EB062618170B33006006FC /* Queue.m in Sources */,
D221A09A169C9E5E00537ABF /* main.m in Sources */,
45843D1F1D2236B30013E85A /* OWSContactsSearcher.m in Sources */,
76EB061618170B33006006FC /* AnonymousOccurrenceLogger.m in Sources */,
B6258B331C29E2E60014138E /* NotificationsManager.m in Sources */,
76EB063018170B33006006FC /* Conversions.m in Sources */,
@ -2743,7 +2753,7 @@
B660F7141C29988E00687D6E /* RecentCall.m in Sources */,
B660F7151C29988E00687D6E /* RecentCallManager.m in Sources */,
B660F7161C29988E00687D6E /* GroupContactsResult.m in Sources */,
B660F7171C29988E00687D6E /* ContactsManager.m in Sources */,
B660F7171C29988E00687D6E /* OWSContactsManager.m in Sources */,
B660F7181C29988E00687D6E /* CryptoTools.m in Sources */,
B660F7191C29988E00687D6E /* EvpMessageDigest.m in Sources */,
B660F71A1C29988E00687D6E /* EvpSymetricUtil.m in Sources */,
@ -2793,6 +2803,7 @@
B660F7461C29988E00687D6E /* HelloAckPacket.m in Sources */,
B660F7471C29988E00687D6E /* HelloPacket.m in Sources */,
B660F7481C29988E00687D6E /* RecipientUnavailable.m in Sources */,
45843D201D2236B30013E85A /* OWSContactsSearcher.m in Sources */,
B660F7491C29988E00687D6E /* ShortAuthenticationStringGenerator.m in Sources */,
B660F74A1C29988E00687D6E /* ZrtpHandshakeResult.m in Sources */,
B660F74B1C29988E00687D6E /* ZrtpHandshakeSocket.m in Sources */,
@ -2806,6 +2817,7 @@
B660F7531C29988E00687D6E /* NetworkStream.m in Sources */,
B660F7541C29988E00687D6E /* SecureEndPoint.m in Sources */,
B660F7551C29988E00687D6E /* UdpSocket.m in Sources */,
45843D221D223BA10013E85A /* OWSContactsSearcherTest.m in Sources */,
B660F7561C29988E00687D6E /* PushManager.m in Sources */,
B660F7571C29988E00687D6E /* NotificationTracker.m in Sources */,
B660F7581C29988E00687D6E /* RPAccountManager.m in Sources */,
@ -2893,7 +2905,7 @@
B660F6D51C29868000687D6E /* TestUtil.m in Sources */,
B660F6B81C29868000687D6E /* JitterQueueTest.m in Sources */,
B660F6DF1C29868000687D6E /* QueueTest.m in Sources */,
B660F6BB1C29868000687D6E /* ContactManagerTest.m in Sources */,
B660F6BB1C29868000687D6E /* OWSContactsManagerTest.m in Sources */,
B660F6CE1C29868000687D6E /* PhoneNumberTest.m in Sources */,
B660F6C41C29868000687D6E /* HandshakePacketTest.m in Sources */,
B660F6CD1C29868000687D6E /* UdpSocketTest.m in Sources */,

@ -2,7 +2,7 @@
#import "AppStoreRating.h"
#import "CategorizingLogger.h"
#import "CodeVerificationViewController.h"
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "DebugLogger.h"
#import "Environment.h"
#import "NotificationsManager.h"

@ -2,7 +2,7 @@
#import <Foundation/Foundation.h>
#import <SignalServiceKit/TSCall.h>
#import "Contact.h"
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "PhoneNumber.h"
/**

@ -7,13 +7,7 @@
#import "ObservableValue.h"
/**
*
* ContactsManager provides access to an updated list of contacts with optional categorizations -
* such as searching and favourite-attributed contacts (favourites are also managed through this class)
* Others can subscribe for contact and/or favourite updates
* Contacts can be grouped by first letter into an NSDictionary in order to display in individual sections-
* in the ContactBrowseViewController.
*
Get latest Signal contacts, and be notified when they change.
*/
#define SIGNAL_LIST_UPDATED @"Signal_AB_UPDATED"
@ -21,7 +15,7 @@
typedef void (^ABAccessRequestCompletionBlock)(BOOL hasAccess);
typedef void (^ABReloadRequestCompletionBlock)(NSArray *contacts);
@interface ContactsManager : NSObject <ContactsManagerProtocol>
@interface OWSContactsManager : NSObject <ContactsManagerProtocol>
@property CNContactStore *contactStore;
@ -29,14 +23,11 @@ typedef void (^ABReloadRequestCompletionBlock)(NSArray *contacts);
- (NSArray *)getContactsFromAddressBook:(ABAddressBookRef)addressBook;
- (Contact *)latestContactForPhoneNumber:(PhoneNumber *)phoneNumber;
- (NSArray *)latestContactsWithSearchString:(NSString *)searchString;
+ (NSDictionary *)groupContactsByFirstLetter:(NSArray *)contacts matchingSearchString:(NSString *)optionalSearchString;
- (void)verifyABPermission;
- (NSArray<Contact *> *)allContacts;
- (NSArray *)signalContacts;
- (NSArray<Contact *> *)signalContacts;
- (NSArray *)textSecureContacts;
- (void)doAfterEnvironmentInitSetup;

@ -1,4 +1,4 @@
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "ContactsUpdater.h"
#import "Environment.h"
#import "Util.h"
@ -7,7 +7,7 @@
typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL *);
@interface ContactsManager ()
@interface OWSContactsManager ()
@property id addressBookReference;
@property TOCFuture *futureAddressBook;
@ -17,7 +17,7 @@ typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL *);
@end
@implementation ContactsManager
@implementation OWSContactsManager
- (void)dealloc {
[_life cancel];
@ -65,7 +65,7 @@ typedef BOOL (^ContactSearchBlock)(id, NSUInteger, BOOL *);
void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef info, void *context);
void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef info, void *context) {
ContactsManager *contactsManager = (__bridge ContactsManager *)context;
OWSContactsManager *contactsManager = (__bridge OWSContactsManager *)context;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[contactsManager pullLatestAddressBook];
[contactsManager intersectContacts];
@ -76,7 +76,7 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
- (void)setupAddressBook {
dispatch_async(ADDRESSBOOK_QUEUE, ^{
[[ContactsManager asyncGetAddressBook] thenDo:^(id addressBook) {
[[OWSContactsManager asyncGetAddressBook] thenDo:^(id addressBook) {
self.addressBookReference = addressBook;
ABAddressBookRef cfAddressBook = (__bridge ABAddressBookRef)addressBook;
ABAddressBookRegisterExternalChangeCallback(cfAddressBook, onAddressBookChanged, (__bridge void *)self);
@ -107,7 +107,7 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
checkOperationDescribe(nil == creationError, [((__bridge NSError *)creationError)localizedDescription]);
ABAddressBookRequestAccessWithCompletion(addressBookRef, ^(bool granted, CFErrorRef error) {
if (!granted) {
[ContactsManager blockingContactDialog];
[OWSContactsManager blockingContactDialog];
}
});
[self.observableContactsController updateValue:[self getContactsFromAddressBook:addressBookRef]];
@ -115,7 +115,7 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
- (void)setupLatestContacts:(NSArray *)contacts {
if (contacts) {
self.latestContactsById = [ContactsManager keyContactsById:contacts];
self.latestContactsById = [OWSContactsManager keyContactsById:contacts];
}
}
@ -248,12 +248,6 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
}];
}
- (NSArray *)latestContactsWithSearchString:(NSString *)searchString {
return [self.latestContactsById.allValues filter:^int(Contact *contact) {
return searchString.length == 0 || [ContactsManager name:contact.fullName matchesQuery:searchString];
}];
}
#pragma mark - Contact/Phone Number util
- (Contact *)contactForRecord:(ABRecordRef)record {
@ -335,58 +329,6 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
}
}
+ (NSArray *)emailsForRecord:(ABRecordRef)record {
ABMultiValueRef emailRefs = ABRecordCopyValue(record, kABPersonEmailProperty);
@try {
NSArray *emails = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(emailRefs);
if (emails == nil)
emails = @[];
return emails;
} @finally {
if (emailRefs) {
CFRelease(emailRefs);
}
}
}
+ (NSDictionary *)groupContactsByFirstLetter:(NSArray *)contacts matchingSearchString:(NSString *)optionalSearchString {
assert(contacts != nil);
NSArray *matchingContacts = [contacts filter:^int(Contact *contact) {
return optionalSearchString.length == 0 || [self name:contact.fullName matchesQuery:optionalSearchString];
}];
return [matchingContacts groupBy:^id(Contact *contact) {
NSString *nameToUse = @"";
BOOL firstNameOrdering = ABPersonGetSortOrdering() == kABPersonCompositeNameFormatFirstNameFirst ? YES : NO;
if (firstNameOrdering && contact.firstName != nil && contact.firstName.length > 0) {
nameToUse = contact.firstName;
} else if (!firstNameOrdering && contact.lastName != nil && contact.lastName.length > 0) {
nameToUse = contact.lastName;
} else if (contact.lastName == nil) {
if (contact.fullName.length > 0) {
nameToUse = contact.fullName;
} else {
return nameToUse;
}
} else {
nameToUse = contact.lastName;
}
if (nameToUse.length >= 1) {
return [[[nameToUse substringToIndex:1] uppercaseString] decomposedStringWithCompatibilityMapping];
} else {
return @" ";
}
}];
}
+ (NSDictionary *)keyContactsById:(NSArray *)contacts {
return [contacts keyedBy:^id(Contact *contact) {
return @((int)contact.recordID);
@ -406,11 +348,6 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
return allContacts;
}
- (NSArray *)recordsForContacts:(NSArray *)contacts {
return [contacts map:^id(Contact *contact) {
return @([contact recordID]);
}];
}
+ (BOOL)name:(NSString *)nameString matchesQuery:(NSString *)queryString {
NSCharacterSet *whitespaceSet = NSCharacterSet.whitespaceCharacterSet;
@ -427,21 +364,11 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
}];
}
+ (BOOL)phoneNumber:(PhoneNumber *)phoneNumber matchesQuery:(NSString *)queryString {
NSString *phoneNumberString = phoneNumber.localizedDescriptionForUser;
NSString *searchString = phoneNumberString.digitsOnly;
if (queryString.length == 0)
return YES;
NSStringCompareOptions searchOpts = NSCaseInsensitiveSearch | NSAnchoredSearch;
return [searchString rangeOfString:queryString options:searchOpts].location != NSNotFound;
}
#pragma mark - Whisper User Management
- (NSArray *)getSignalUsersFromContactsArray:(NSArray *)contacts {
return [[contacts filter:^int(Contact *contact) {
return contact.isRedPhoneContact || contact.isTextSecureContact;
return [contact isSignalContact];
}] sortedArrayUsingComparator:[[self class] contactComparator]];
}
@ -460,25 +387,16 @@ void onAddressBookChanged(ABAddressBookRef notifyAddressBook, CFDictionaryRef in
};
}
- (NSArray *)signalContacts {
return [self getSignalUsersFromContactsArray:self.allContacts];
- (NSArray<Contact *> *)signalContacts {
return [self getSignalUsersFromContactsArray:[self allContacts]];
}
- (NSArray *)textSecureContacts {
return [[self.allContacts filter:^int(Contact *contact) {
return [contact isTextSecureContact];
return [contact isSignalContact];
}] sortedArrayUsingComparator:[[self class] contactComparator]];
}
- (NSArray *)getNewItemsFrom:(NSArray *)newArray comparedTo:(NSArray *)oldArray {
NSMutableSet *newSet = [NSMutableSet setWithArray:newArray];
NSSet *oldSet = [NSSet setWithArray:oldArray];
[newSet minusSet:oldSet];
return newSet.allObjects;
}
- (NSString *)nameStringForPhoneIdentifier:(NSString *)identifier {
for (Contact *contact in self.allContacts) {
for (PhoneNumber *phoneNumber in contact.parsedPhoneNumbers) {

@ -0,0 +1,16 @@
//
// OWSContactsSearcher.h
// Signal
//
// Created by Michael Kirk on 6/27/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
#import "Contact.h"
@interface OWSContactsSearcher : NSObject
- (instancetype)initWithContacts:(NSArray<Contact *> *)contacts;
- (NSArray<Contact *> *)filterWithString:(NSString *)string;
@end

@ -0,0 +1,42 @@
//
// OWSContactsSearcher.m
// Signal
//
// Created by Michael Kirk on 6/27/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
#import "OWSContactsSearcher.h"
#import <SignalServiceKit/PhoneNumber.h>
@interface OWSContactsSearcher ()
@property (copy) NSArray<Contact *> *contacts;
@end
@implementation OWSContactsSearcher
- (instancetype)initWithContacts:(NSArray<Contact *> *)contacts {
self = [super init];
if (!self) return self;
_contacts = contacts;
return self;
}
- (NSArray<Contact *> *)filterWithString:(NSString *)string {
NSString *searchTerm = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([searchTerm isEqualToString:@""]) {
return self.contacts;
}
NSString *formattedNumber = [PhoneNumber removeFormattingCharacters:searchTerm];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(fullName contains[c] %@) OR (ANY parsedPhoneNumbers.toE164 contains[c] %@)", searchTerm, formattedNumber];
return [self.contacts filteredArrayUsingPredicate:predicate];
}
@end

@ -25,7 +25,7 @@ static NSString *const kCallSegue = @"2.0_6.0_Call_Segue";
#define TESTING_OPTION_USE_DH_FOR_HANDSHAKE @"DhKeyAgreementOnly"
@class RecentCallManager;
@class ContactsManager;
@class OWSContactsManager;
@class PhoneManager;
@class SignalsViewController;
@class TSGroupThread;
@ -44,7 +44,7 @@ static NSString *const kCallSegue = @"2.0_6.0_Call_Segue";
@property (nonatomic, readonly) NSArray *testingAndLegacyOptions;
@property (nonatomic, readonly) NSData *zrtpClientId;
@property (nonatomic, readonly) NSData *zrtpVersionId;
@property (nonatomic, readonly) ContactsManager *contactsManager;
@property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic, readonly) SignalsViewController *signalsViewController;
@property (nonatomic, readonly, weak) UINavigationController *signUpFlowNavigationController;
@ -66,7 +66,7 @@ static NSString *const kCallSegue = @"2.0_6.0_Call_Segue";
andTestingAndLegacyOptions:(NSArray *)testingAndLegacyOptions
andZrtpClientId:(NSData *)zrtpClientId
andZrtpVersionId:(NSData *)zrtpVersionId
andContactsManager:(ContactsManager *)contactsManager;
andContactsManager:(OWSContactsManager *)contactsManager;
+ (Environment *)getCurrent;
+ (void)setCurrent:(Environment *)curEnvironment;

@ -67,7 +67,7 @@ static Environment *environment = nil;
andTestingAndLegacyOptions:(NSArray *)testingAndLegacyOptions
andZrtpClientId:(NSData *)zrtpClientId
andZrtpVersionId:(NSData *)zrtpVersionId
andContactsManager:(ContactsManager *)contactsManager {
andContactsManager:(OWSContactsManager *)contactsManager {
ows_require(errorNoter != nil);
ows_require(zrtpClientId != nil);
ows_require(zrtpVersionId != nil);

@ -58,7 +58,7 @@ static unsigned char DH3K_PRIME[] = {
]
andZrtpClientId:RELEASE_ZRTP_CLIENT_ID
andZrtpVersionId:RELEASE_ZRTP_VERSION_ID
andContactsManager:[ContactsManager new]];
andContactsManager:[OWSContactsManager new]];
}
+ (Environment *)stagingEnvironmentWithLogging:(id<Logging>)logging {
@ -82,7 +82,7 @@ static unsigned char DH3K_PRIME[] = {
]
andZrtpClientId:RELEASE_ZRTP_CLIENT_ID
andZrtpVersionId:RELEASE_ZRTP_VERSION_ID
andContactsManager:[ContactsManager new]];
andContactsManager:[OWSContactsManager new]];
}
+ (Environment *)unitTestEnvironment:(NSArray *)testingAndLegacyOptions {

@ -169,7 +169,7 @@
__block BOOL success;
TSUpdateAttributesRequest *request = [[TSUpdateAttributesRequest alloc] initWithUpdatedAttributesWithVoice:YES];
TSUpdateAttributesRequest *request = [[TSUpdateAttributesRequest alloc] initWithUpdatedAttributesWithVoice];
[[TSNetworkManager sharedManager] makeRequest:request
success:^(NSURLSessionDataTask *task, id responseObject) {
success = YES;

@ -9,7 +9,7 @@
#import <PushKit/PushKit.h>
#import "AppDelegate.h"
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "InCallViewController.h"
#import "NSData+ows_StripToken.h"
#import "NSDate+millisecondTimeStamp.h"

@ -10,7 +10,7 @@
#import <SignalServiceKit/TSAccountManager.h>
#import "Contact.h"
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "Environment.h"
#import "SignalKeyingStorage.h"
@ -28,7 +28,7 @@
- (instancetype)initWithMembersId:(NSArray *)memberIdentifiers without:(NSArray *)removeIds {
self = [super init];
ContactsManager *manager = [Environment.getCurrent contactsManager];
OWSContactsManager *manager = [Environment.getCurrent contactsManager];
NSMutableSet *remainingNumbers = [NSMutableSet setWithArray:memberIdentifiers];

@ -9,7 +9,7 @@
#import "CodeVerificationViewController.h"
#import <SignalServiceKit/TSStorageManager+keyingMaterial.h>
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "Environment.h"
#import "LocalizableText.h"
#import "PushManager.h"
@ -132,7 +132,6 @@
[TSAccountManager verifyAccountWithCode:[self validationCodeFromTextField]
pushToken:pushTokens[0]
voipToken:([pushTokens count] == 2) ? pushTokens.lastObject : nil
supportsVoice:YES
success:^{
[textsecureRegistration trySetResult:@YES];
}

@ -12,24 +12,24 @@
#import "ContactTableViewCell.h"
#import "ContactsUpdater.h"
#import "OWSContactsSearcher.h"
#import "Environment.h"
#import "UIColor+OWS.h"
#import "UIUtil.h"
@interface MessageComposeTableViewController () <UISearchBarDelegate,
UISearchResultsUpdating,
MFMessageComposeViewControllerDelegate> {
UIButton *sendTextButton;
NSString *currentSearchTerm;
NSArray *contacts;
NSArray *searchResults;
}
MFMessageComposeViewControllerDelegate>
@property (nonatomic) UIButton *sendTextButton;
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator;
@property (nonatomic, strong) UIBarButtonItem *addGroup;
@property (nonatomic, strong) UIView *loadingBackgroundView;
@property (nonatomic, strong) UIView *emptyBackgroundView;
@property (nonatomic) NSString *currentSearchTerm;
@property (copy) NSArray<Contact *> *contacts;
@property (copy) NSArray<Contact *> *searchResults;
@end
@ -39,8 +39,8 @@
[super viewDidLoad];
[self.navigationController.navigationBar setTranslucent:NO];
contacts = [[Environment getCurrent] contactsManager].signalContacts;
searchResults = contacts;
self.contacts = [[[Environment getCurrent] contactsManager] signalContacts];
self.searchResults = self.contacts;
[self initializeSearch];
self.searchController.searchBar.hidden = NO;
@ -54,7 +54,7 @@
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([contacts count] == 0) {
if ([self.contacts count] == 0) {
[self showEmptyBackgroundView:YES];
}
}
@ -218,17 +218,17 @@
self.searchController.searchBar.delegate = self;
self.searchController.searchBar.placeholder = NSLocalizedString(@"SEARCH_BYNAMEORNUMBER_PLACEHOLDER_TEXT", @"");
sendTextButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[sendTextButton setBackgroundColor:[UIColor ows_materialBlueColor]];
[sendTextButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
sendTextButton.frame = CGRectMake(self.searchController.searchBar.frame.origin.x,
self.searchController.searchBar.frame.origin.y + 44.0,
self.searchController.searchBar.frame.size.width,
44.0);
[self.view addSubview:sendTextButton];
sendTextButton.hidden = YES;
[sendTextButton addTarget:self action:@selector(sendText) forControlEvents:UIControlEventTouchUpInside];
self.sendTextButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.sendTextButton setBackgroundColor:[UIColor ows_materialBlueColor]];
[self.sendTextButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
self.sendTextButton.frame = CGRectMake(self.searchController.searchBar.frame.origin.x,
self.searchController.searchBar.frame.origin.y + 44.0,
self.searchController.searchBar.frame.size.width,
44.0);
[self.view addSubview:self.sendTextButton];
self.sendTextButton.hidden = YES;
[self.sendTextButton addTarget:self action:@selector(sendText) forControlEvents:UIControlEventTouchUpInside];
[self initializeRefreshControl];
}
@ -257,31 +257,26 @@
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
sendTextButton.hidden = YES;
self.sendTextButton.hidden = YES;
}
#pragma mark - Filter
- (void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope {
// search by contact name or number
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:@"(fullName contains[c] %@) OR (allPhoneNumbers contains[c] %@)", searchText, searchText];
searchResults = [contacts filteredArrayUsingPredicate:resultPredicate];
if (!searchResults.count && _searchController.searchBar.text.length == 0) {
searchResults = contacts;
}
NSString *formattedNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:searchText].toE164;
OWSContactsSearcher *contactsSearcher = [[OWSContactsSearcher alloc] initWithContacts: self.contacts];
self.searchResults = [contactsSearcher filterWithString:searchText];
NSString *formattedNumber = [PhoneNumber tryParsePhoneNumberFromUserSpecifiedText:searchText].toE164;
// text to a non-signal number if we have no results and a valid phone #
if (searchResults.count == 0 && searchText.length > 8 && formattedNumber) {
if (self.searchResults.count == 0 && searchText.length > 8 && formattedNumber) {
NSString *sendTextTo = NSLocalizedString(@"SEND_SMS_BUTTON", @"");
sendTextTo = [sendTextTo stringByAppendingString:formattedNumber];
[sendTextButton setTitle:sendTextTo forState:UIControlStateNormal];
sendTextButton.hidden = NO;
currentSearchTerm = formattedNumber;
[self.sendTextButton setTitle:sendTextTo forState:UIControlStateNormal];
self.sendTextButton.hidden = NO;
self.currentSearchTerm = formattedNumber;
} else {
sendTextButton.hidden = YES;
self.sendTextButton.hidden = YES;
}
}
@ -290,9 +285,9 @@
- (void)sendText {
NSString *confirmMessage = NSLocalizedString(@"SEND_SMS_CONFIRM_TITLE", @"");
if ([currentSearchTerm length] > 0) {
if ([self.currentSearchTerm length] > 0) {
confirmMessage = NSLocalizedString(@"SEND_SMS_INVITE_TITLE", @"");
confirmMessage = [confirmMessage stringByAppendingString:currentSearchTerm];
confirmMessage = [confirmMessage stringByAppendingString:self.currentSearchTerm];
confirmMessage = [confirmMessage stringByAppendingString:NSLocalizedString(@"QUESTIONMARK_PUNCTUATION", @"")];
}
@ -318,7 +313,7 @@
picker.messageComposeDelegate = self;
picker.recipients =
[currentSearchTerm length] > 0 ? [NSArray arrayWithObject:currentSearchTerm] : nil;
[self.currentSearchTerm length] > 0 ? [NSArray arrayWithObject:self.currentSearchTerm] : nil;
picker.body = [NSLocalizedString(@"SMS_INVITE_BODY", @"")
stringByAppendingString:
@" https://itunes.apple.com/us/app/signal-private-messenger/id874139669?mt=8"];
@ -336,7 +331,7 @@
[alertController addAction:cancelAction];
[alertController addAction:okAction];
sendTextButton.hidden = YES;
self.sendTextButton.hidden = YES;
self.searchController.searchBar.text = @"";
//must dismiss search controller before presenting alert.
@ -396,9 +391,9 @@
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.searchController.active) {
return (NSInteger)[searchResults count];
return (NSInteger)[self.searchResults count];
} else {
return (NSInteger)[contacts count];
return (NSInteger)[self.contacts count];
}
}
@ -426,11 +421,6 @@
}
#pragma mark - Table View delegate
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
Contact *person = [self contactForIndexPath:indexPath];
return person.isTextSecureContact ? indexPath : nil;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = [[[self contactForIndexPath:indexPath] textSecureIdentifiers] firstObject];
@ -441,7 +431,6 @@
}];
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
ContactTableViewCell *cell = (ContactTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
@ -451,9 +440,9 @@
Contact *contact = nil;
if (self.searchController.active) {
contact = [searchResults objectAtIndex:(NSUInteger)indexPath.row];
contact = [self.searchResults objectAtIndex:(NSUInteger)indexPath.row];
} else {
contact = [contacts objectAtIndex:(NSUInteger)indexPath.row];
contact = [self.contacts objectAtIndex:(NSUInteger)indexPath.row];
}
return contact;
@ -465,7 +454,7 @@
[self.refreshControl endRefreshing];
[self showLoadingBackgroundView:NO];
if ([contacts count] == 0) {
if ([self.contacts count] == 0) {
[self showEmptyBackgroundView:YES];
} else {
[self showEmptyBackgroundView:NO];
@ -476,7 +465,7 @@
[[ContactsUpdater sharedUpdater]
updateSignalContactIntersectionWithABContacts:[Environment getCurrent].contactsManager.allContacts
success:^{
contacts = [[Environment getCurrent] contactsManager].signalContacts;
self.contacts = [[[Environment getCurrent] contactsManager] signalContacts];
dispatch_async(dispatch_get_main_queue(), ^{
[self updateSearchResultsForSearchController:self.searchController];
[self.tableView reloadData];
@ -495,7 +484,7 @@
});
}];
if ([contacts count] == 0) {
if ([self.contacts count] == 0) {
[self showLoadingBackgroundView:YES];
}
}

@ -14,7 +14,7 @@
#import <MobileCoreServices/UTCoreTypes.h>
#import <SignalServiceKit/TSAccountManager.h>
#import <YapDatabase/YapDatabaseView.h>
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "DJWActionSheet+OWS.h"
#import "Environment.h"
#import "FingerprintViewController.h"
@ -437,9 +437,7 @@ typedef enum : NSUInteger {
target:self
action:@selector(callAction)];
self.navigationItem.rightBarButtonItem.imageInsets = UIEdgeInsetsMake(0, -10, 0, 10);
} else if (!_thread.isGroupThread) {
self.navigationItem.rightBarButtonItem = nil;
} else {
} else if ([self.thread isGroupThread]) {
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"contact-options-action"]
imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]
@ -447,6 +445,9 @@ typedef enum : NSUInteger {
target:self
action:@selector(didSelectShow:)];
self.navigationItem.rightBarButtonItem.imageInsets = UIEdgeInsetsMake(10, 20, 10, 0);
} else {
self.navigationItem.rightBarButtonItem = nil;
DDLogError(@"Thread was neither group thread nor callable");
}
[self hideInputIfNeeded];
@ -627,17 +628,8 @@ typedef enum : NSUInteger {
return recipient;
}
- (BOOL)isRedPhoneReachable {
return [self signalRecipient].supportsVoice;
}
- (BOOL)isTextSecureReachable {
if (isGroupConversation) {
return YES;
} else {
return [self signalRecipient];
}
return isGroupConversation || [self signalRecipient];
}
- (PhoneNumber *)phoneNumberForThread {
@ -646,18 +638,17 @@ typedef enum : NSUInteger {
}
- (void)callAction {
if ([self isRedPhoneReachable]) {
if ([self canCall]) {
PhoneNumber *number = [self phoneNumberForThread];
Contact *contact = [[Environment.getCurrent contactsManager] latestContactForPhoneNumber:number];
[Environment.phoneManager initiateOutgoingCallToContact:contact atRemoteNumber:number];
} else {
DDLogWarn(@"Tried to initiate a call but contact has no RedPhone identifier");
DDLogWarn(@"Tried to initiate a call but thread is not callable.");
}
}
- (BOOL)canCall {
return !isGroupConversation && [self isRedPhoneReachable] &&
![((TSContactThread *)_thread).contactIdentifier isEqualToString:[TSAccountManager localNumber]];
return !(isGroupConversation || [((TSContactThread *)self.thread).contactIdentifier isEqualToString:[TSAccountManager localNumber]]);
}
- (void)textViewDidChange:(UITextView *)textView {

@ -11,7 +11,7 @@
#import <SignalServiceKit/TSAccountManager.h>
#import <SignalServiceKit/TSMessagesManager+attachments.h>
#import <SignalServiceKit/TSMessagesManager+sendMessages.h>
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "DJWActionSheet+OWS.h"
#import "Environment.h"
#import "FunctionalUtil.h"

@ -17,7 +17,7 @@
#import "TSSocketManager.h"
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "AboutTableViewController.h"
#import "AdvancedSettingsTableViewController.h"

@ -11,7 +11,7 @@
#import "SignalsViewController.h"
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "Environment.h"
#import "GroupContactsResult.h"

@ -9,7 +9,7 @@
#import "InboxTableViewCell.h"
#import "UIUtil.h"
#import "ContactsManager.h"
#import "OWSContactsManager.h"
#import "InCallViewController.h"
#import "MessagesViewController.h"
#import "NSDate+millisecondTimeStamp.h"

@ -1,5 +1,5 @@
#import <UIKit/UIKit.h>
#import "ContactsManager.h"
#import "OWSContactsManager.h"
/**
*

@ -4,11 +4,10 @@
#import "Environment.h"
#import "PhoneManager.h"
#define CONTACT_TABLE_CELL_BORDER_WIDTH 1.0f
@interface ContactTableViewCell ()
@interface ContactTableViewCell () {
}
@property (strong, nonatomic) Contact *associatedContact;
@end
@implementation ContactTableViewCell
@ -22,17 +21,9 @@
return NSStringFromClass(self.class);
}
- (void)configureWithContact:(Contact *)contact {
if (!contact.isTextSecureContact) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
}
_associatedContact = contact;
_nameLabel.attributedText = [self attributedStringForContact:contact];
if (!contact.isTextSecureContact) {
_nameLabel.textColor = [UIColor lightGrayColor];
}
self.associatedContact = contact;
self.nameLabel.attributedText = [self attributedStringForContact:contact];
}
- (NSAttributedString *)attributedStringForContact:(Contact *)contact {

@ -1,29 +0,0 @@
#import <XCTest/XCTest.h>
#import "TestUtil.h"
#import "ContactsManager.h"
@interface ContactManagerTest : XCTestCase
@end
@implementation ContactManagerTest
- (void)testQueryMatching {
test([ContactsManager name:@"big dave" matchesQuery:@"big dave"]);
test([ContactsManager name:@"big dave" matchesQuery:@"dave big"]);
test([ContactsManager name:@"big dave" matchesQuery:@"dave"]);
test([ContactsManager name:@"big dave" matchesQuery:@"big"]);
test([ContactsManager name:@"big dave" matchesQuery:@"big "]);
test([ContactsManager name:@"big dave" matchesQuery:@" big "]);
test([ContactsManager name:@"big dave" matchesQuery:@"dav"]);
test([ContactsManager name:@"big dave" matchesQuery:@"bi dav"]);
test([ContactsManager name:@"big dave" matchesQuery:@"big big big big big big big big big big dave dave dave dave dave"]);
test(![ContactsManager name:@"big dave" matchesQuery:@"ave"]);
test(![ContactsManager name:@"big dave" matchesQuery:@"dare"]);
test(![ContactsManager name:@"big dave" matchesQuery:@"mike"]);
test(![ContactsManager name:@"big dave" matchesQuery:@"mike"]);
test(![ContactsManager name:@"dave" matchesQuery:@"big"]);
}
@end

@ -0,0 +1,30 @@
#import <XCTest/XCTest.h>
#import "TestUtil.h"
#import "OWSContactsManager.h"
@interface OWSContactsManagerTest : XCTestCase
@end
@implementation OWSContactsManagerTest
- (void)testQueryMatching {
test([OWSContactsManager name:@"big dave" matchesQuery:@"big dave"]);
test([OWSContactsManager name:@"big dave" matchesQuery:@"dave big"]);
test([OWSContactsManager name:@"big dave" matchesQuery:@"dave"]);
test([OWSContactsManager name:@"big dave" matchesQuery:@"big"]);
test([OWSContactsManager name:@"big dave" matchesQuery:@"big "]);
test([OWSContactsManager name:@"big dave" matchesQuery:@" big "]);
test([OWSContactsManager name:@"big dave" matchesQuery:@"dav"]);
test([OWSContactsManager name:@"big dave" matchesQuery:@"bi dav"]);
test([OWSContactsManager name:@"big dave" matchesQuery:@"big big big big big big big big big big dave dave dave dave dave"]);
test(![OWSContactsManager name:@"big dave" matchesQuery:@"ave"]);
test(![OWSContactsManager name:@"big dave" matchesQuery:@"dare"]);
test(![OWSContactsManager name:@"big dave" matchesQuery:@"mike"]);
test(![OWSContactsManager name:@"big dave" matchesQuery:@"mike"]);
test(![OWSContactsManager name:@"dave" matchesQuery:@"big"]);
}
@end

@ -0,0 +1,69 @@
//
// OWSContactSearcherTest.m
// Signal
//
// Created by Michael Kirk on 6/27/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "OWSContactsSearcher.h"
@interface OWSContactsSearcherTest : XCTestCase
@property Contact *meow;
@property Contact *clement;
@property OWSContactsSearcher *contactsSearcher;
@end
@implementation OWSContactsSearcherTest
- (void)setUp {
[super setUp];
self.meow = [[Contact alloc] initWithContactWithFirstName:@"Chairman"
andLastName:@"Meow"
andUserTextPhoneNumbers:@[ @"1-323-555-1234", @"+86 10 1111 2222" ]
andImage:nil
andContactID:1];
self.clement = [[Contact alloc] initWithContactWithFirstName:@"Clément"
andLastName:@"Duval"
andUserTextPhoneNumbers:@[ @"33 123456789" ]
andImage:nil
andContactID:2];
self.contactsSearcher = [[OWSContactsSearcher alloc] initWithContacts:@[self.meow, self.clement]];
}
- (void)testFilterWithStringMatchAllOnEmtpy {
XCTAssertEqualObjects((@[self.meow, self.clement]), [self.contactsSearcher filterWithString:@""]);
XCTAssertEqualObjects((@[self.meow, self.clement]), [self.contactsSearcher filterWithString:@" "]);
}
- (void)testFilterWithStringMatchByName {
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"Chairman"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"Chair"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"Meow"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"Chairman Meow"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@" Chairman Meow "]);
XCTAssertEqualObjects((@[self.meow, self.clement]), ([self.contactsSearcher filterWithString:@"C"]));
XCTAssertEqualObjects(@[], [self.contactsSearcher filterWithString:@"Chairman Meowww"]);
}
- (void)testFilterWithStringByNumber {
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"1-323-555-1234"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"+86 10 1111 2222"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"323-555-1234"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"323.555.1234"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"3235551234"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"323"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"323 555 1234"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"+1 323 555 1234"]);
XCTAssertEqualObjects(@[self.meow], [self.contactsSearcher filterWithString:@"+13235551234"]);
XCTAssertEqualObjects((@[self.meow, self.clement]), [self.contactsSearcher filterWithString:@"1234"]);
}
@end
Loading…
Cancel
Save