mirror of
https://github.com/danog/Telegram.git
synced 2024-12-02 09:27:55 +01:00
332 lines
13 KiB
Objective-C
332 lines
13 KiB
Objective-C
#import "TGUsernameController.h"
|
|
|
|
#import "TGProgressWindow.h"
|
|
|
|
#import "TGDatabase.h"
|
|
#import "TGTelegraph.h"
|
|
#import "ActionStage.h"
|
|
|
|
#import "TGCollectionMenuSection.h"
|
|
#import "TGCommentCollectionItem.h"
|
|
#import "TGUsernameCollectionItem.h"
|
|
|
|
#import "TGCollectionMenuLayout.h"
|
|
|
|
#import "TGAlertView.h"
|
|
|
|
typedef enum {
|
|
TGUsernameControllerUsernameStateNone,
|
|
TGUsernameControllerUsernameStateValid,
|
|
TGUsernameControllerUsernameStateTooShort,
|
|
TGUsernameControllerUsernameStateInvalidCharacters,
|
|
TGUsernameControllerUsernameStateStartsWithNumber,
|
|
TGUsernameControllerUsernameStateTaken,
|
|
TGUsernameControllerUsernameStateChecking
|
|
} TGUsernameControllerUsernameState;
|
|
|
|
@interface TGUsernameController () <ASWatcher>
|
|
{
|
|
TGUsernameCollectionItem *_usernameItem;
|
|
TGCommentCollectionItem *_invalidUsernameItem;
|
|
TGCommentCollectionItem *_hintItem;
|
|
|
|
NSString *_currentCheckPath;
|
|
TGProgressWindow *_progressWindow;
|
|
}
|
|
|
|
@property (nonatomic, strong) ASHandle *actionHandle;
|
|
|
|
@end
|
|
|
|
@implementation TGUsernameController
|
|
|
|
- (instancetype)init
|
|
{
|
|
self = [super init];
|
|
if (self != nil)
|
|
{
|
|
_actionHandle = [[ASHandle alloc] initWithDelegate:self releaseOnMainThread:true];
|
|
|
|
self.title = TGLocalized(@"Username.Title");
|
|
[self setLeftBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:TGLocalized(@"Common.Cancel") style:UIBarButtonItemStylePlain target:self action:@selector(cancelPressed)]];
|
|
[self setRightBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:TGLocalized(@"Common.Done") style:UIBarButtonItemStyleDone target:self action:@selector(donePressed)]];
|
|
|
|
TGUser *user = [TGDatabaseInstance() loadUser:TGTelegraphInstance.clientUserId];
|
|
|
|
_usernameItem = [[TGUsernameCollectionItem alloc] init];
|
|
_usernameItem.username = user.userName;
|
|
_usernameItem.usernameValid = true;
|
|
__weak TGUsernameController *weakSelf = self;
|
|
_usernameItem.usernameChanged = ^(NSString *username)
|
|
{
|
|
__strong TGUsernameController *strongSelf = weakSelf;
|
|
[strongSelf usernameChanged:username];
|
|
};
|
|
|
|
TGCommentCollectionItem *commentItem = [[TGCommentCollectionItem alloc] initWithFormattedText:TGLocalized(@"Username.Help")];
|
|
commentItem.topInset = 1.0f;
|
|
|
|
_invalidUsernameItem = [[TGCommentCollectionItem alloc] init];
|
|
_invalidUsernameItem.topInset = 6.0f;
|
|
_invalidUsernameItem.alpha = 0.0f;
|
|
_invalidUsernameItem.hidden = true;
|
|
|
|
_hintItem = [[TGCommentCollectionItem alloc] init];
|
|
_hintItem.topInset = 6.0f;
|
|
_hintItem.alpha = 1.0f;
|
|
_hintItem.hidden = false;
|
|
_hintItem.action = ^
|
|
{
|
|
__strong TGUsernameController *strongSelf = weakSelf;
|
|
if (strongSelf != nil)
|
|
{
|
|
if (strongSelf->_usernameItem.username.length != 0)
|
|
{
|
|
[[UIPasteboard generalPasteboard] setString:[[NSString alloc] initWithFormat:@"https://telegram.me/%@", strongSelf->_usernameItem.username]];
|
|
[[[TGAlertView alloc] initWithTitle:nil message:TGLocalized(@"Username.LinkCopied") cancelButtonTitle:TGLocalized(@"Common.OK") okButtonTitle:nil completionBlock:nil] show];
|
|
}
|
|
}
|
|
};
|
|
|
|
[self updateLinkHint:user.userName];
|
|
|
|
TGCollectionMenuSection *section = [[TGCollectionMenuSection alloc] initWithItems:@[_usernameItem, _invalidUsernameItem, commentItem, _hintItem]];
|
|
section.insets = UIEdgeInsetsMake(32.0f, 0.0f, 0.0f, 0.0f);
|
|
[self.menuSections addSection:section];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[_actionHandle reset];
|
|
[ActionStageInstance() removeWatcher:self];
|
|
}
|
|
|
|
- (BOOL)shouldAutorotate
|
|
{
|
|
return true;
|
|
}
|
|
|
|
- (void)cancelPressed
|
|
{
|
|
[self.view endEditing:true];
|
|
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
|
|
}
|
|
|
|
- (void)donePressed
|
|
{
|
|
if (TGStringCompare(_usernameItem.username, [TGDatabaseInstance() loadUser:TGTelegraphInstance.clientUserId].userName))
|
|
{
|
|
[self.view endEditing:true];
|
|
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
|
|
}
|
|
else if (_usernameItem.username.length != 0 && ![self usernameIsValid:_usernameItem.username])
|
|
{
|
|
unichar c = [_usernameItem.username characterAtIndex:0];
|
|
if (c >= '0' && c <= '9')
|
|
{
|
|
[[[TGAlertView alloc] initWithTitle:TGLocalized(@"Username.InvalidStartsWithNumber") message:nil cancelButtonTitle:TGLocalized(@"Common.Cancel") okButtonTitle:nil completionBlock:nil] show];
|
|
}
|
|
else
|
|
{
|
|
[[[TGAlertView alloc] initWithTitle:TGLocalized(@"Username.InvalidCharacters") message:nil cancelButtonTitle:TGLocalized(@"Common.Cancel") okButtonTitle:nil completionBlock:nil] show];
|
|
}
|
|
}
|
|
else if (_usernameItem.username.length != 0 && _usernameItem.username.length < 5)
|
|
{
|
|
[[[TGAlertView alloc] initWithTitle:TGLocalized(@"Username.InvalidTooShort") message:nil cancelButtonTitle:TGLocalized(@"Common.Cancel") okButtonTitle:nil completionBlock:nil] show];
|
|
}
|
|
else
|
|
{
|
|
_progressWindow = [[TGProgressWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
|
[_progressWindow show:true];
|
|
|
|
[ActionStageInstance() requestActor:[[NSString alloc] initWithFormat:@"/tg/applyUsername/(%lu)", (unsigned long)[_usernameItem.username hash]] options:@{@"username": _usernameItem.username == nil ? @"" : _usernameItem.username} flags:0 watcher:self];
|
|
}
|
|
}
|
|
|
|
- (void)setUsernameState:(TGUsernameControllerUsernameState)state username:(NSString *)username
|
|
{
|
|
switch (state)
|
|
{
|
|
case TGUsernameControllerUsernameStateNone:
|
|
break;
|
|
case TGUsernameControllerUsernameStateValid:
|
|
_invalidUsernameItem.showProgress = false;
|
|
break;
|
|
case TGUsernameControllerUsernameStateTooShort:
|
|
_invalidUsernameItem.showProgress = false;
|
|
break;
|
|
case TGUsernameControllerUsernameStateInvalidCharacters:
|
|
_invalidUsernameItem.showProgress = false;
|
|
break;
|
|
case TGUsernameControllerUsernameStateStartsWithNumber:
|
|
_invalidUsernameItem.showProgress = false;
|
|
break;
|
|
case TGUsernameControllerUsernameStateTaken:
|
|
_invalidUsernameItem.showProgress = false;
|
|
break;
|
|
case TGUsernameControllerUsernameStateChecking:
|
|
_invalidUsernameItem.showProgress = true;
|
|
break;
|
|
}
|
|
|
|
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^
|
|
{
|
|
switch (state)
|
|
{
|
|
case TGUsernameControllerUsernameStateNone:
|
|
_invalidUsernameItem.alpha = 0.0f;
|
|
_invalidUsernameItem.hidden = true;
|
|
break;
|
|
case TGUsernameControllerUsernameStateValid:
|
|
[_invalidUsernameItem setText:[[NSString alloc] initWithFormat:TGLocalized(@"Username.UsernameIsAvailable"), username]];
|
|
_invalidUsernameItem.alpha = 1.0f;
|
|
_invalidUsernameItem.hidden = false;
|
|
_invalidUsernameItem.showProgress = false;
|
|
[_invalidUsernameItem setTextColor:UIColorRGB(0x26972c)];
|
|
break;
|
|
case TGUsernameControllerUsernameStateTooShort:
|
|
[_invalidUsernameItem setText:TGLocalized(@"Username.InvalidTooShort")];
|
|
_invalidUsernameItem.alpha = 1.0f;
|
|
_invalidUsernameItem.hidden = false;
|
|
_invalidUsernameItem.showProgress = false;
|
|
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
|
|
break;
|
|
case TGUsernameControllerUsernameStateInvalidCharacters:
|
|
[_invalidUsernameItem setText:TGLocalized(@"Username.InvalidCharacters")];
|
|
_invalidUsernameItem.alpha = 1.0f;
|
|
_invalidUsernameItem.hidden = false;
|
|
_invalidUsernameItem.showProgress = false;
|
|
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
|
|
break;
|
|
case TGUsernameControllerUsernameStateStartsWithNumber:
|
|
[_invalidUsernameItem setText:TGLocalized(@"Username.InvalidStartsWithNumber")];
|
|
_invalidUsernameItem.alpha = 1.0f;
|
|
_invalidUsernameItem.hidden = false;
|
|
_invalidUsernameItem.showProgress = false;
|
|
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
|
|
break;
|
|
case TGUsernameControllerUsernameStateTaken:
|
|
[_invalidUsernameItem setText:TGLocalized(@"Username.InvalidTaken")];
|
|
_invalidUsernameItem.alpha = 1.0f;
|
|
_invalidUsernameItem.hidden = false;
|
|
_invalidUsernameItem.showProgress = false;
|
|
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
|
|
break;
|
|
case TGUsernameControllerUsernameStateChecking:
|
|
[_invalidUsernameItem setText:[[NSString alloc] initWithFormat:@" %@", TGLocalized(@"Username.CheckingUsername")]];
|
|
_invalidUsernameItem.alpha = 1.0f;
|
|
_invalidUsernameItem.hidden = false;
|
|
_invalidUsernameItem.showProgress = true;
|
|
[_invalidUsernameItem setTextColor:UIColorRGB(0x6d6d72)];
|
|
break;
|
|
}
|
|
|
|
[self.collectionLayout invalidateLayout];
|
|
[self.collectionView layoutSubviews];
|
|
} completion:nil];
|
|
}
|
|
|
|
- (bool)usernameIsValid:(NSString *)username
|
|
{
|
|
for (NSUInteger i = 0; i < username.length; i++)
|
|
{
|
|
unichar c = [username characterAtIndex:i];
|
|
if (c == '_' && i != 0 && i != username.length - 1)
|
|
continue;
|
|
if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (i > 0 && c >= '0' && c <= '9')))
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
- (void)usernameChanged:(NSString *)username
|
|
{
|
|
if (_currentCheckPath != nil)
|
|
{
|
|
[ActionStageInstance() removeWatcher:self fromPath:_currentCheckPath];
|
|
_currentCheckPath = nil;
|
|
}
|
|
|
|
if (username.length == 0)
|
|
{
|
|
[self setUsernameState:TGUsernameControllerUsernameStateNone username:username];
|
|
}
|
|
else if (![self usernameIsValid:username])
|
|
{
|
|
unichar c = [username characterAtIndex:0];
|
|
TGUsernameControllerUsernameState state;
|
|
if (c >= '0' && c <= '9')
|
|
state = TGUsernameControllerUsernameStateStartsWithNumber;
|
|
else
|
|
state = TGUsernameControllerUsernameStateInvalidCharacters;
|
|
[self setUsernameState:state username:username];
|
|
}
|
|
else if (username.length < 5)
|
|
{
|
|
[self setUsernameState:TGUsernameControllerUsernameStateTooShort username:username];
|
|
}
|
|
else
|
|
{
|
|
[self setUsernameState:TGUsernameControllerUsernameStateChecking username:username];
|
|
|
|
_currentCheckPath = [[NSString alloc] initWithFormat:@"/tg/checkUsernameAvailability/(%d)", (int)[_usernameItem.username hash]];
|
|
[ActionStageInstance() requestActor:_currentCheckPath options:@{@"username": _usernameItem.username} flags:0 watcher:self];
|
|
}
|
|
|
|
[self updateLinkHint:username];
|
|
}
|
|
|
|
- (void)updateLinkHint:(NSString *)username
|
|
{
|
|
if (username.length == 0)
|
|
_hintItem.text = nil;
|
|
else
|
|
[_hintItem setFormattedText:[[NSString alloc] initWithFormat:TGLocalized(@"Username.LinkHint"), username]];
|
|
}
|
|
|
|
- (void)actorCompleted:(int)status path:(NSString *)path result:(id)result
|
|
{
|
|
if ([path isEqualToString:_currentCheckPath])
|
|
{
|
|
TGDispatchOnMainThread(^
|
|
{
|
|
_currentCheckPath = nil;
|
|
|
|
_usernameItem.usernameChecking = false;
|
|
|
|
if (status == ASStatusSuccess)
|
|
{
|
|
[self setUsernameState:[result[@"usernameValid"] boolValue] ? TGUsernameControllerUsernameStateValid : TGUsernameControllerUsernameStateTaken username:_usernameItem.username];
|
|
}
|
|
else
|
|
{
|
|
[self setUsernameState:TGUsernameControllerUsernameStateTaken username:_usernameItem.username];
|
|
}
|
|
});
|
|
}
|
|
else if ([path hasPrefix:@"/tg/applyUsername/"])
|
|
{
|
|
TGDispatchOnMainThread(^
|
|
{
|
|
if (status == ASStatusSuccess)
|
|
{
|
|
[_progressWindow dismissWithSuccess];
|
|
[self.view endEditing:true];
|
|
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
|
|
}
|
|
else
|
|
{
|
|
[_progressWindow dismiss:true];
|
|
|
|
[[[TGAlertView alloc] initWithTitle:TGLocalized(@"Username.InvalidTaken") message:nil cancelButtonTitle:TGLocalized(@"Common.OK") okButtonTitle:nil completionBlock:nil] show];
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@end
|