1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-03 09:57:46 +01:00
Telegram/Telegraph/TGUserDataRequestBuilder.m
2016-02-25 01:03:51 +01:00

210 lines
7.4 KiB
Objective-C

#import "TGUserDataRequestBuilder.h"
#import "ActionStage.h"
#import "TGTelegraph.h"
#import "TGUser+Telegraph.h"
#import "TGDatabase.h"
#import "TGUserNode.h"
#import "TGContactListRequestBuilder.h"
#import "TGAccountSettings.h"
#import "TGAccountSettingsActor.h"
#import "TGStringUtils.h"
@implementation TGUserDataRequestBuilder
+ (NSString *)genericPath
{
return @"/tg/users/@";
}
+ (void)executeUserLinkUpdates:(NSArray *)usersLinks
{
for (NSArray *record in usersLinks)
{
int uid = [[record objectAtIndex:0] intValue];
int userLink = [[record objectAtIndex:1] intValue];
if ([TGDatabaseInstance() loadUserLink:uid outdated:NULL] != userLink)
{
[TGDatabaseInstance() storeUserLink:uid link:userLink];
[TGTelegraphInstance dispatchUserLinkChanged:uid link:userLink];
}
else
{
[TGDatabaseInstance() storeUserLink:uid link:userLink];
}
if (uid != TGTelegraphInstance.clientUserId)
{
if (((userLink & TGUserLinkForeignMutual) || (userLink & TGUserLinkMyContact)))
{
if (![TGDatabaseInstance() uidIsRemoteContact:uid])
{
TGUser *user = [TGDatabaseInstance() loadUser:uid];
if (user.phoneNumber != nil && user.phoneNumber.length != 0)
{
static int actionId = 0;
[ActionStageInstance() requestActor:[NSString stringWithFormat:@"/tg/synchronizeContacts/(%d,importLink)", actionId++] options:[NSDictionary dictionaryWithObjectsAndKeys:user, @"user", nil] watcher:TGTelegraphInstance];
}
}
}
else if ((userLink & TGUserLinkKnown) && !(userLink & TGUserLinkMyContact))
{
if ([TGDatabaseInstance() uidIsRemoteContact:uid])
{
static int actionId = 0;
[ActionStageInstance() requestActor:[NSString stringWithFormat:@"/tg/synchronizeContacts/(%d,breakLink)", actionId++] options:[NSDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:uid], @"uid", nil] watcher:TGTelegraphInstance];
}
}
}
}
}
+ (void)executeUserObjectsUpdate:(NSArray *)userObjects
{
NSMutableArray *storeUsers = [[NSMutableArray alloc] init];
NSMutableArray *updateUsers = [[NSMutableArray alloc] init];
NSMutableArray *updateUserChanges = [[NSMutableArray alloc] init];
for (TGUser *user in userObjects)
{
TGUser *originalUser = [[TGDatabase instance] loadUser:user.uid];
int difference = [originalUser differenceFromUser:user];
if (originalUser == nil || difference != 0)
{
TGUser *updatedUser = user;
if (originalUser != nil)
{
if (!TGStringCompare(originalUser.phoneNumber, user.phoneNumber) && user.phoneNumber.length != 0 && [TGDatabaseInstance() uidIsRemoteContact:user.uid])
{
TGPhonebookContact *phonebookContact = [TGDatabaseInstance() phonebookContactByPhoneId:phoneMatchHash(originalUser.phoneNumber)];
TGPhonebookContact *newPhonebookContact = [TGDatabaseInstance() phonebookContactByPhoneId:phoneMatchHash(user.phoneNumber)];
if (phonebookContact != nil && newPhonebookContact == nil)
{
[[TGSynchronizeContactsManager instance] scheduleContactPhoneAddition:user.uid];
static int actionId = 0;
[ActionStageInstance() requestActor:[NSString stringWithFormat:@"/tg/synchronizeContacts/(%dappend,appendPhone)", actionId++] options:[NSDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:user.uid], @"uid", user.phoneNumber, @"phoneNumber", @(phonebookContact.nativeId), @"nativeId", nil] watcher:TGTelegraphInstance];
}
}
if (user.minimalRepresentation) {
updatedUser = [user copy];
updatedUser.phoneNumberHash = originalUser.phoneNumberHash;
updatedUser.userName = originalUser.userName;
updatedUser.presence = originalUser.presence;
}
[updateUsers addObject:updatedUser];
[updateUserChanges addObject:[[NSNumber alloc] initWithInt:[updatedUser differenceFromUser:originalUser]]];
}
[storeUsers addObject:updatedUser];
}
}
if (storeUsers.count != 0)
[[TGDatabase instance] storeUsers:storeUsers];
if (updateUsers.count != 0)
{
int count = (int)updateUsers.count;
for (int i = 0; i < count; i++)
{
[TGTelegraphInstance dispatchUserDataChanges:[updateUsers objectAtIndex:i] changes:[[updateUserChanges objectAtIndex:i] intValue]];
}
}
}
+ (void)executeUserDataUpdate:(NSArray *)users
{
NSMutableArray *userObjects = [[NSMutableArray alloc] init];
for (TLUser *userDesc in users)
{
TGUser *user = [[TGUser alloc] initWithTelegraphUserDesc:userDesc];
if (user != nil)
[userObjects addObject:user];
}
[TGUserDataRequestBuilder executeUserObjectsUpdate:userObjects];
}
- (void)execute:(NSDictionary *)options
{
NSArray *downloadedUserData = [options objectForKey:@"downloadedUserData"];
if (downloadedUserData != nil)
{
[TGUserDataRequestBuilder executeUserDataUpdate:downloadedUserData];
// In this case the actor was explicitly invoked, thus we don't need to call nodeRetrieved
}
else
{
NSString *userIdString = [self.path substringWithRange:NSMakeRange(11, self.path.length - 11 - 1)];
int uid = [userIdString intValue];
if (![[NSString stringWithFormat:@"%d", uid] isEqualToString:userIdString])
{
[ActionStageInstance() nodeRetrieveFailed:self.path];
return;
}
TGUser *user = [[TGDatabase instance] loadUser:uid];
if (user != nil)
{
[ActionStageInstance() nodeRetrieved:self.path node:[[TGUserNode alloc] initWithUser:user]];
return;
}
self.cancelToken = [TGTelegraphInstance doRequestUserData:uid requestBuilder:self];
}
}
- (void)userDataRequestSuccess:(NSArray *)users
{
[TGUserDataRequestBuilder executeUserDataUpdate:users];
NSString *userIdString = [self.path substringWithRange:NSMakeRange(11, self.path.length - 11 - 1)];
int uid = [userIdString intValue];
if (![[NSString stringWithFormat:@"%d", uid] isEqualToString:userIdString])
{
[ActionStageInstance() nodeRetrieveFailed:self.path];
return;
}
TGUser *user = [[TGDatabase instance] loadUser:uid];
if (user != nil)
{
[ActionStageInstance() nodeRetrieved:self.path node:[[TGUserNode alloc] initWithUser:user]];
return;
}
else
{
[ActionStageInstance() nodeRetrieveFailed:self.path];
}
}
- (void)userDataRequestFailed
{
[ActionStageInstance() nodeRetrieveFailed:self.path];
}
- (void)cancel
{
if (self.cancelToken != nil)
{
[TGTelegraphInstance cancelRequestByToken:self.cancelToken];
self.cancelToken = nil;
}
[super cancel];
}
@end