1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-04 10:27:46 +01:00
Telegram/legacy/TelegraphKit/TGUser.m
2016-02-25 01:03:51 +01:00

428 lines
14 KiB
Objective-C

#import "TGUser.h"
#import "TGStringUtils.h"
#import "TGPhoneUtils.h"
#import "NSObject+TGLock.h"
#import "TGNotificationPrivacyAccountSetting.h"
#import "TGDatabase.h"
#import "PSKeyValueCoder.h"
typedef enum {
TGUserFlagVerified = (1 << 0),
TGUserFlagHasExplicitContent = (1 << 1),
TGUserFlagIsContextBot = (1 << 2),
TGUserFlagMinimalRepresentation = (1 << 3)
} TGUserFlags;
@interface TGUser ()
{
bool _contactIdInitialized;
bool _formattedPhoneInitialized;
TG_SYNCHRONIZED_DEFINE(_cachedValues);
}
@property (nonatomic, strong) NSString *cachedFormattedNumber;
@end
@implementation TGUser
- (instancetype)initWithKeyValueCoder:(PSKeyValueCoder *)coder
{
self = [super init];
if (self != nil)
{
_kind = [coder decodeInt32ForCKey:"k"];
if (_kind == TGUserKindBot || _kind == TGUserKindSmartBot)
{
_botInfoVersion = [coder decodeInt32ForCKey:"biv"];
_botKind = [coder decodeInt32ForCKey:"bk"];
}
_flags = [coder decodeInt32ForCKey:"f"];
_restrictionReason = [coder decodeStringForCKey:"rr"];
if ([self isContextBot]) {
_contextBotPlaceholder = [coder decodeStringForCKey:"cbp"];
}
}
return self;
}
- (void)encodeWithKeyValueCoder:(PSKeyValueCoder *)coder
{
[coder encodeInt32:_kind forCKey:"k"];
if (_kind == TGUserKindBot || _kind == TGUserKindSmartBot)
{
[coder encodeInt32:_botInfoVersion forCKey:"biv"];
[coder encodeInt32:_botKind forCKey:"bk"];
}
[coder encodeInt32:_flags forCKey:"f"];
[coder encodeString:_restrictionReason forCKey:"rr"];
if ([self isContextBot]) {
[coder encodeString:_contextBotPlaceholder forCKey:"cbp"];
}
}
- (id)copyWithZone:(NSZone *)__unused zone
{
TGUser *user = [[TGUser alloc] init];
user.uid = _uid;
user.phoneNumber = _phoneNumber;
user.phoneNumberHash = _phoneNumberHash;
user.firstName = _firstName;
user.lastName = _lastName;
user.userName = _userName;
user.phonebookFirstName = _phonebookFirstName;
user.phonebookLastName = _phonebookLastName;
user.sex = _sex;
user.photoUrlSmall = _photoUrlSmall;
user.photoUrlMedium = _photoUrlMedium;
user.photoUrlBig = _photoUrlBig;
user.presence = _presence;
user.customProperties = _customProperties;
user.contactId = _contactId;
user->_contactIdInitialized = _contactIdInitialized;
user->_formattedPhoneInitialized = _formattedPhoneInitialized;
user.cachedFormattedNumber = _cachedFormattedNumber;
user->_kind = _kind;
user->_botInfoVersion = _botInfoVersion;
user->_botKind = _botKind;
user->_flags = _flags;
user->_restrictionReason = _restrictionReason;
user->_contextBotPlaceholder = _contextBotPlaceholder;
return user;
}
- (bool)hasAnyName
{
return _firstName.length != 0 || _lastName.length != 0 || _phonebookFirstName.length != 0 || _phonebookLastName.length != 0;
}
- (NSString *)firstName
{
return (_phonebookFirstName.length != 0 || _phonebookLastName.length != 0) ? _phonebookFirstName : ((_firstName.length != 0 || _lastName.length != 0) ? _firstName : (_phoneNumber.length == 0 ? @"Name Hidden" : [self formattedPhoneNumber]));
}
- (NSString *)lastName
{
return (_phonebookFirstName.length != 0 || _phonebookLastName.length != 0) ? _phonebookLastName : ((_firstName.length != 0 || _lastName.length != 0) ? _lastName : nil);
}
- (NSString *)realFirstName
{
return _firstName;
}
- (NSString *)realLastName
{
return _lastName;
}
- (NSString *)displayName
{
NSString *firstName = self.firstName;
NSString *lastName = self.lastName;
if (firstName != nil && firstName.length != 0 && lastName != nil && lastName.length != 0)
{
if (TGIsKorean())
return [[NSString alloc] initWithFormat:@"%@ %@", lastName, firstName];
else
return [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName];
}
else if (firstName != nil && firstName.length != 0)
return firstName;
else if (lastName != nil && lastName.length != 0)
return lastName;
return @"";
}
- (NSString *)displayRealName
{
NSString *firstName = self.realFirstName;
NSString *lastName = self.realLastName;
if (firstName != nil && firstName.length != 0 && lastName != nil && lastName.length != 0)
return [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName];
else if (firstName != nil && firstName.length != 0)
return firstName;
else if (lastName != nil && lastName.length != 0)
return lastName;
return @"";
}
- (NSString *)displayFirstName
{
NSString *firstName = self.firstName;
if (firstName.length != 0)
return firstName;
return self.lastName;
}
- (NSString *)compactName
{
NSString *firstName = self.firstName;
NSString *lastName = self.lastName;
if (firstName != nil && firstName.length != 0 && lastName != nil && lastName.length != 0)
return [[NSString alloc] initWithFormat:@"%@.%@", [firstName substringToIndex:1], lastName];
else if (firstName != nil && firstName.length != 0)
return firstName;
else if (lastName != nil && lastName.length != 0)
return lastName;
return @"";
}
- (void)setPhoneNumber:(NSString *)phoneNumber
{
TG_SYNCHRONIZED_BEGIN(_cachedValues);
_phoneNumber = phoneNumber;
_contactIdInitialized = false;
_formattedPhoneInitialized = false;
TG_SYNCHRONIZED_END(_cachedValues);
}
- (int)contactId
{
if (!_contactIdInitialized)
{
int contactId = 0;
if (_phoneNumber != nil && _phoneNumber.length != 0)
contactId = phoneMatchHash(_phoneNumber);
TG_SYNCHRONIZED_BEGIN(_cachedValues);
_contactId = contactId;
_contactIdInitialized = true;
TG_SYNCHRONIZED_END(_cachedValues);
}
return _contactId;
}
- (NSString *)formattedPhoneNumber
{
if (_formattedPhoneInitialized)
return _cachedFormattedNumber;
else
{
NSString *cachedFormattedNumber = nil;
if (_phoneNumber.length != 0)
cachedFormattedNumber = [TGPhoneUtils formatPhone:_phoneNumber forceInternational:true];
TG_SYNCHRONIZED_BEGIN(_cachedValues);
_cachedFormattedNumber = cachedFormattedNumber;
_formattedPhoneInitialized = true;
TG_SYNCHRONIZED_END(_cachedValues);
return cachedFormattedNumber;
}
}
- (BOOL)isEqual:(id)object
{
return [object isKindOfClass:[TGUser class]] && [self isEqualToUser:object];
}
- (bool)isEqualToUser:(TGUser *)anotherUser
{
if (anotherUser.uid == _uid &&
((anotherUser.realFirstName == nil && _firstName == nil) || [anotherUser.realFirstName isEqualToString:_firstName]) &&
((anotherUser.realLastName == nil && _lastName == nil) || [anotherUser.realLastName isEqualToString:_lastName]) &&
anotherUser.sex == _sex &&
((anotherUser.phonebookFirstName == nil && _phonebookFirstName == nil) || [anotherUser.phonebookFirstName isEqualToString:_phonebookFirstName]) &&
((anotherUser.phonebookLastName == nil && _phonebookLastName == nil) || [anotherUser.phonebookLastName isEqualToString:_phonebookLastName]) &&
((anotherUser.phoneNumber == nil && _phoneNumber == nil) || [anotherUser.phoneNumber isEqualToString:_phoneNumber]) &&
anotherUser.phoneNumberHash == _phoneNumberHash &&
((anotherUser.photoUrlSmall == nil && _photoUrlSmall == nil) || [anotherUser.photoUrlSmall isEqualToString:_photoUrlSmall]) &&
((anotherUser.photoUrlMedium == nil && _photoUrlMedium == nil) || [anotherUser.photoUrlMedium isEqualToString:_photoUrlMedium]) &&
((anotherUser.photoUrlBig == nil && _photoUrlBig == nil) || [anotherUser.photoUrlBig isEqualToString:_photoUrlBig]) &&
anotherUser.presence.online == _presence.online && anotherUser.presence.lastSeen == _presence.lastSeen && TGStringCompare(_userName, anotherUser.userName) && anotherUser.kind == _kind && anotherUser.botKind == _botKind &&
TGStringCompare(_restrictionReason, anotherUser.restrictionReason))
{
return true;
}
return false;
}
- (int)differenceFromUser:(TGUser *)anotherUser
{
int difference = 0;
if (_uid != anotherUser.uid)
difference |= TGUserFieldUid;
if ((_phoneNumber == nil) != (anotherUser.phoneNumber == nil) || (_phoneNumber != nil && ![_phoneNumber isEqualToString:anotherUser.phoneNumber]))
difference |= TGUserFieldPhoneNumber;
if (_phoneNumberHash != anotherUser.phoneNumberHash)
difference |= TGUserFieldPhoneNumberHash;
if ((_firstName == nil) != (anotherUser.realFirstName == nil) || (_firstName != nil && ![_firstName isEqualToString:anotherUser.realFirstName]))
difference |= TGUserFieldFirstName;
if ((_lastName == nil) != (anotherUser.realLastName == nil) || (_lastName != nil && ![_lastName isEqualToString:anotherUser.realLastName]))
difference |= TGUserFieldLastName;
if (!TGStringCompare(_userName, anotherUser.userName))
difference |= TGUserFieldUsername;
if ((_phonebookFirstName == nil) != (anotherUser.phonebookFirstName == nil) || (_phonebookFirstName != nil && ![_phonebookFirstName isEqualToString:anotherUser.phonebookFirstName]))
difference |= TGUserFieldPhonebookFirstName;
if ((_phonebookLastName == nil) != (anotherUser.phonebookLastName == nil) || (_phonebookLastName != nil && ![_phonebookLastName isEqualToString:anotherUser.phonebookLastName]))
difference |= TGUserFieldPhonebookLastName;
if (_sex != anotherUser.sex)
difference |= TGUserFieldSex;
if ((_photoUrlSmall == nil) != (anotherUser.photoUrlSmall == nil) || (_photoUrlSmall != nil && ![_photoUrlSmall isEqualToString:anotherUser.photoUrlSmall]))
difference |= TGUserFieldPhotoUrlSmall;
if ((_photoUrlMedium == nil) != (anotherUser.photoUrlMedium == nil) || (_photoUrlMedium != nil && ![_photoUrlMedium isEqualToString:anotherUser.photoUrlMedium]))
difference |= TGUserFieldPhotoUrlMedium;
if ((_photoUrlBig == nil) != (anotherUser.photoUrlBig == nil) || (_photoUrlBig != nil && ![_photoUrlBig isEqualToString:anotherUser.photoUrlBig]))
difference |= TGUserFieldPhotoUrlBig;
if (_presence.lastSeen != anotherUser.presence.lastSeen)
difference |= TGUserFieldPresenceLastSeen;
if (_presence.online != anotherUser.presence.online)
difference |= TGUserFieldPresenceOnline;
if (anotherUser.kind != _kind)
difference |= TGUserFieldOther;
if (anotherUser.botKind != _botKind)
difference |= TGUserFieldOther;
if (anotherUser.flags != _flags) {
difference |= TGUserFieldOther;
}
if (!TGStringCompare(anotherUser.restrictionReason, _restrictionReason)) {
difference |= TGUserFieldOther;
}
if (!TGStringCompare(anotherUser.contextBotPlaceholder, _contextBotPlaceholder)) {
difference |= TGUserFieldOther;
}
return difference;
}
+ (TGUserPresence)approximatePresenceFromPresence:(TGUserPresence)presence currentTime:(NSTimeInterval)currentTime
{
if (presence.lastSeen <= 0)
return presence;
if (presence.lastSeen >= (int)(currentTime - 60 * 60 * 24 * 4))
return (TGUserPresence){.online = false, .lastSeen = TGUserPresenceValueLately, .temporaryLastSeen = 0};
else if (presence.lastSeen >= (int)(currentTime - 60 * 60 * 24 * 4))
return (TGUserPresence){.online = false, .lastSeen = TGUserPresenceValueWithinAWeek, .temporaryLastSeen = 0};
else if (presence.lastSeen >= (int)(currentTime - 60 * 60 * 24 * 31))
return (TGUserPresence){.online = false, .lastSeen = TGUserPresenceValueWithinAMonth, .temporaryLastSeen = 0};
return (TGUserPresence){.online = false, .lastSeen = TGUserPresenceValueALongTimeAgo, .temporaryLastSeen = 0};
}
- (TGUser *)applyPrivacyRules:(TGNotificationPrivacyAccountSetting *)privacyRules currentTime:(NSTimeInterval)currentTime
{
if (privacyRules == nil)
return self;
bool approximatePresenceRequired = false;
switch (privacyRules.lastSeenPrimarySetting)
{
case TGPrivacySettingsLastSeenPrimarySettingEverybody:
if ([privacyRules.neverShareWithUserIds containsObject:@(_uid)])
approximatePresenceRequired = true;
break;
case TGPrivacySettingsLastSeenPrimarySettingContacts:
if ([TGDatabaseInstance() uidIsRemoteContact:_uid])
{
if ([privacyRules.neverShareWithUserIds containsObject:@(_uid)])
approximatePresenceRequired = true;
}
else
{
if (![privacyRules.alwaysShareWithUserIds containsObject:@(_uid)])
approximatePresenceRequired = true;
}
break;
case TGPrivacySettingsLastSeenPrimarySettingNobody:
if (![privacyRules.alwaysShareWithUserIds containsObject:@(_uid)])
approximatePresenceRequired = true;
break;
}
if (approximatePresenceRequired)
{
TGUser *user = [self copy];
user.presence = [TGUser approximatePresenceFromPresence:self.presence currentTime:currentTime];
return user;
}
return self;
}
- (bool)isVerified {
return _flags & TGUserFlagVerified;
}
- (void)setIsVerified:(bool)isVerified {
if (isVerified) {
_flags |= TGUserFlagVerified;
} else {
_flags &= ~TGUserFlagVerified;
}
}
- (bool)isContextBot {
return _flags & TGUserFlagIsContextBot;
}
- (void)setIsContextBot:(bool)isContextBot {
if (isContextBot) {
_flags |= TGUserFlagIsContextBot;
} else {
_flags &= ~TGUserFlagIsContextBot;
}
}
- (bool)hasExplicitContent {
return _flags & TGConversationFlagHasExplicitContent;
}
- (void)setHasExplicitContent:(bool)hasExplicitContent {
if (hasExplicitContent) {
_flags |= TGConversationFlagHasExplicitContent;
} else {
_flags &= ~TGConversationFlagHasExplicitContent;
}
}
- (bool)minimalRepresentation {
return _flags & TGUserFlagMinimalRepresentation;
}
- (void)setMinimalRepresentation:(bool)minimalRepresentation {
if (minimalRepresentation) {
_flags |= TGUserFlagMinimalRepresentation;
} else {
_flags &= ~TGUserFlagMinimalRepresentation;
}
}
@end