mirror of
https://github.com/vector-im/element-ios.git
synced 2024-10-01 00:32:41 +00:00
92f1e2f602
The matrix IDs are retrieved in one time instead of getting them one by one -> ConsoleEmail and ConsolePhoneNumber inherit of ConsoleContactField. ConsoleContactField manages the matrix part (id + thumbnail download...) -> the unknown room members are added into the contacts list. Thus, it would easier to start a chat.
279 lines
13 KiB
Objective-C
279 lines
13 KiB
Objective-C
/*
|
|
Copyright 2014 OpenMarket Ltd
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
#import "ContactManager.h"
|
|
|
|
#import "ConsoleContact.h"
|
|
#import "ConsolePhoneNumber.h"
|
|
#import "ConsoleEmail.h"
|
|
|
|
#import "MatrixHandler.h"
|
|
|
|
// warn when there is a contacts list refresh
|
|
NSString *const kContactManagerRefreshNotification = @"kContactManagerRefreshNotification";
|
|
|
|
@implementation ContactManager
|
|
@synthesize contacts;
|
|
|
|
#pragma mark Singleton Methods
|
|
static ContactManager* sharedContactManager = nil;
|
|
|
|
+ (id)sharedManager {
|
|
@synchronized(self) {
|
|
if(sharedContactManager == nil)
|
|
sharedContactManager = [[self alloc] init];
|
|
}
|
|
return sharedContactManager;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
-(ContactManager *)init {
|
|
if (self = [super init]) {
|
|
NSString *label = [NSString stringWithFormat:@"ConsoleMatrix.%@.Contacts", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]];
|
|
|
|
processingQueue = dispatch_queue_create([label UTF8String], NULL);
|
|
|
|
// put an empty array instead of nil
|
|
contacts = [[NSMutableArray alloc] init];
|
|
|
|
// check if the application is allowed to list the contacts
|
|
ABAuthorizationStatus cbStatus = ABAddressBookGetAuthorizationStatus();
|
|
|
|
// did not yet request the access
|
|
if (cbStatus == kABAuthorizationStatusNotDetermined) {
|
|
// request address book access
|
|
ABAddressBookRef ab = ABAddressBookCreateWithOptions(nil, nil);
|
|
|
|
if (ab) {
|
|
ABAddressBookRequestAccessWithCompletion(ab, ^(bool granted, CFErrorRef error) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self refresh];
|
|
});
|
|
|
|
});
|
|
|
|
CFRelease(ab);
|
|
}
|
|
}
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
-(void)dealloc {
|
|
}
|
|
|
|
- (void)refresh
|
|
{
|
|
// did not yet request the access
|
|
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
|
|
// wait that the user gives the Authorization
|
|
return;
|
|
}
|
|
|
|
//
|
|
matrixIDBy3PID = [[NSMutableDictionary alloc] init];
|
|
|
|
dispatch_async(processingQueue, ^{
|
|
ABAddressBookRef ab = ABAddressBookCreateWithOptions(nil, nil);
|
|
ABRecordRef contactRecord;
|
|
int index;
|
|
|
|
//CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();
|
|
CFMutableArrayRef people = (CFMutableArrayRef)ABAddressBookCopyArrayOfAllPeople(ab);
|
|
|
|
NSMutableArray* contactsList = [[NSMutableArray alloc] init];
|
|
|
|
if (nil != people) {
|
|
int peopleCount = CFArrayGetCount(people);
|
|
|
|
for (index = 0; index < peopleCount; index++) {
|
|
contactRecord = (ABRecordRef)CFArrayGetValueAtIndex(people, index);
|
|
[contactsList addObject:[[ConsoleContact alloc] initWithABRecord:contactRecord]];
|
|
}
|
|
|
|
CFRelease(people);
|
|
}
|
|
|
|
if (ab) {
|
|
CFRelease(ab);
|
|
}
|
|
|
|
contacts = contactsList;
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self refreshMatrixIDs];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:kContactManagerRefreshNotification object:nil userInfo:nil];
|
|
});
|
|
});
|
|
}
|
|
|
|
- (void)refreshMatrixIDs {
|
|
|
|
// build the request parameters
|
|
NSMutableArray* pids = [[NSMutableArray alloc] init];
|
|
NSMutableArray* medias = [[NSMutableArray alloc] init];
|
|
|
|
for(ConsoleContact* contact in contacts) {
|
|
// the phonenumbers are not managed
|
|
/*for(ConsolePhoneNumber* pn in contact.phoneNumbers) {
|
|
if (pn.textNumber.length > 0) {
|
|
|
|
// not yet added
|
|
if ([pids indexOfObject:pn.textNumber] == NSNotFound) {
|
|
[pids addObject:pn.textNumber];
|
|
[medias addObject:@"msisdn"];
|
|
}
|
|
}
|
|
}*/
|
|
|
|
for(ConsoleEmail* email in contact.emailAddresses) {
|
|
if (email.emailAddress.length > 0) {
|
|
|
|
// not yet added
|
|
if ([pids indexOfObject:email.emailAddress] == NSNotFound) {
|
|
[pids addObject:email.emailAddress];
|
|
[medias addObject:@"email"];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// get some pids
|
|
if (pids.count > 0) {
|
|
MatrixHandler *mxHandler = [MatrixHandler sharedHandler];
|
|
|
|
if (mxHandler.mxRestClient) {
|
|
[mxHandler.mxRestClient lookup3pids:pids
|
|
forMedia:medias
|
|
success:^(NSArray *userIds) {
|
|
// sanity check
|
|
if (userIds.count == pids.count) {
|
|
|
|
matrixIDBy3PID = [[NSMutableDictionary alloc] initWithObjects:userIds forKeys:pids];
|
|
|
|
for(ConsoleContact* contact in contacts) {
|
|
// the phonenumbers wil be managed later
|
|
/*for(ConsolePhoneNumber* pn in contact.phoneNumbers) {
|
|
if (pn.textNumber.length > 0) {
|
|
|
|
// not yet added
|
|
if ([pids indexOfObject:pn.textNumber] == NSNotFound) {
|
|
[pids addObject:pn.textNumber];
|
|
[medias addObject:@"msisdn"];
|
|
}
|
|
}
|
|
}*/
|
|
|
|
for(ConsoleEmail* email in contact.emailAddresses) {
|
|
if (email.emailAddress.length > 0) {
|
|
id matrixID = [matrixIDBy3PID valueForKey:email.emailAddress];
|
|
|
|
if ([matrixID isKindOfClass:[NSString class]]) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[email setMatrixID:matrixID];
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// check if the some room users are not defined in the local contacts book
|
|
MatrixHandler *mxHandler = [MatrixHandler sharedHandler];
|
|
|
|
// check if the user is already known
|
|
NSArray* users = [mxHandler.mxSession users];
|
|
|
|
NSMutableArray* unknownRoomContacts = [[NSMutableArray alloc] init];
|
|
|
|
for(MXUser* user in users) {
|
|
|
|
if ([userIds indexOfObject:user.userId] == NSNotFound) {
|
|
NSString* dummyContactID = [NSString stringWithFormat:@"%lu", (unsigned long)user.userId.hash];
|
|
|
|
// with the current API, there is no way to get the email from the matrxID
|
|
ConsoleEmail* email = [[ConsoleEmail alloc] initWithEmailAddress:user.userId type:@"" contactID:dummyContactID matrixID:user.userId];
|
|
ConsoleContact* contact = [[ConsoleContact alloc] initWithDisplayName:(user.displayname ? user.displayname : user.userId) contactID:dummyContactID emails:@[email] phonenumbers:nil];
|
|
|
|
[unknownRoomContacts addObject:contact];
|
|
}
|
|
}
|
|
|
|
// some members are not listed in the contacts
|
|
if (unknownRoomContacts.count > 0) {
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self.contacts addObjectsFromArray:unknownRoomContacts];
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:kContactManagerRefreshNotification object:nil userInfo:nil];
|
|
});
|
|
|
|
}
|
|
}
|
|
}
|
|
failure:^(NSError *error) {
|
|
// try later
|
|
dispatch_after(dispatch_walltime(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
|
[self refreshMatrixIDs];
|
|
});
|
|
}
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (SectionedContacts *)getSectionedContacts:(NSArray*)contactsList {
|
|
UILocalizedIndexedCollation *collation = [UILocalizedIndexedCollation currentCollation];
|
|
|
|
int indexOffset = 0;
|
|
|
|
NSInteger index, sectionTitlesCount = [[collation sectionTitles] count];
|
|
NSMutableArray *tmpSectionsArray = [[NSMutableArray alloc] initWithCapacity:(sectionTitlesCount)];
|
|
|
|
sectionTitlesCount += indexOffset;
|
|
|
|
for (index = 0; index < sectionTitlesCount; index++) {
|
|
NSMutableArray *array = [[NSMutableArray alloc] init];
|
|
[tmpSectionsArray addObject:array];
|
|
}
|
|
|
|
int contactsCount = 0;
|
|
|
|
for (ConsoleContact *aContact in contactsList)
|
|
{
|
|
NSInteger section = [collation sectionForObject:aContact collationStringSelector:@selector(displayName)] + indexOffset;
|
|
|
|
[[tmpSectionsArray objectAtIndex:section] addObject:aContact];
|
|
++contactsCount;
|
|
}
|
|
|
|
NSMutableArray *tmpSectionedContactsTitle = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];
|
|
NSMutableArray *shortSectionsArray = [[NSMutableArray alloc] initWithCapacity:sectionTitlesCount];
|
|
|
|
for (index = indexOffset; index < sectionTitlesCount; index++) {
|
|
|
|
NSMutableArray *usersArrayForSection = [tmpSectionsArray objectAtIndex:index];
|
|
|
|
if ([usersArrayForSection count] != 0) {
|
|
NSArray* sortedUsersArrayForSection = [collation sortedArrayFromArray:usersArrayForSection collationStringSelector:@selector(displayName)];
|
|
[shortSectionsArray addObject:sortedUsersArrayForSection];
|
|
[tmpSectionedContactsTitle addObject:[[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:(index - indexOffset)]];
|
|
}
|
|
}
|
|
|
|
return [[SectionedContacts alloc] initWithContacts:shortSectionsArray andTitles:tmpSectionedContactsTitle andCount:contactsCount];
|
|
}
|
|
|
|
@end
|