1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-02 17:38:07 +01:00
Telegram/Telegraph/TGChannelLinkSetupController.m
2015-10-01 19:19:52 +03:00

386 lines
16 KiB
Objective-C

#import "TGChannelLinkSetupController.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"
#import "TGChannelManagementSignals.h"
#import "TGTelegramNetworking.h"
typedef enum {
TGUsernameControllerUsernameStateNone,
TGUsernameControllerUsernameStateValid,
TGUsernameControllerUsernameStateTooShort,
TGUsernameControllerUsernameStateInvalidCharacters,
TGUsernameControllerUsernameStateStartsWithNumber,
TGUsernameControllerUsernameStateTaken,
TGUsernameControllerUsernameStateChecking,
TGUsernameControllerUsernameStateTooManyUsernames
} TGUsernameControllerUsernameState;
@interface TGChannelLinkSetupController ()
{
TGConversation *_conversation;
TGUsernameCollectionItem *_usernameItem;
TGCommentCollectionItem *_invalidUsernameItem;
TGCommentCollectionItem *_hintItem;
SMetaDisposable *_checkUsernameDisposable;
SMetaDisposable *_updateUsernameDisposable;
void (^_block)(NSString *);
}
@end
@implementation TGChannelLinkSetupController
- (instancetype)initWithConversation:(TGConversation *)conversation
{
self = [super init];
if (self != nil)
{
_conversation = conversation;
[self commonInit];
}
return self;
}
- (instancetype)initWithBlock:(void (^)(NSString *username))block
{
self = [super init];
if (self != nil)
{
_block = [block copy];
[self commonInit];
}
return self;
}
- (void)commonInit {
self.title = TGLocalized(@"Channel.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)]];
_usernameItem = [[TGUsernameCollectionItem alloc] init];
_usernameItem.username = _conversation.username;
_usernameItem.usernameValid = true;
_usernameItem.placeholder = @"";
_usernameItem.title = @"";
_usernameItem.prefix = @"telegram.me/";
__weak TGChannelLinkSetupController *weakSelf = self;
_usernameItem.usernameChanged = ^(NSString *username)
{
__strong TGChannelLinkSetupController *strongSelf = weakSelf;
[strongSelf usernameChanged:username];
};
TGCommentCollectionItem *commentItem = [[TGCommentCollectionItem alloc] initWithFormattedText:TGLocalized(@"Channel.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 TGChannelLinkSetupController *strongSelf = weakSelf;
if (strongSelf != nil)
{
if (strongSelf->_usernameItem.username.length != 0)
{
[[UIPasteboard generalPasteboard] setString:[[NSString alloc] initWithFormat:@"http://telegram.me/%@", strongSelf->_usernameItem.username]];
[[[TGAlertView alloc] initWithTitle:nil message:TGLocalized(@"Username.LinkCopied") cancelButtonTitle:TGLocalized(@"Common.OK") okButtonTitle:nil completionBlock:nil] show];
}
}
};
[self updateLinkHint:_conversation.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];
_checkUsernameDisposable = [[SMetaDisposable alloc] init];
_updateUsernameDisposable = [[SMetaDisposable alloc] init];
}
- (void)dealloc
{
[_checkUsernameDisposable dispose];
[_updateUsernameDisposable dispose];
}
- (BOOL)shouldAutorotate
{
return true;
}
- (void)cancelPressed
{
[self.view endEditing:true];
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
}
- (void)donePressed
{
if (TGStringCompare(_usernameItem.username, _conversation.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
{
__weak TGChannelLinkSetupController *weakSelf = self;
void (^continueSetup)() = ^{
__strong TGChannelLinkSetupController *strongSelf = weakSelf;
if (strongSelf != nil) {
if (strongSelf->_block != nil) {
[self.view endEditing:true];
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
strongSelf->_block(strongSelf->_usernameItem.username);
} else {
TGProgressWindow *progressWindow = [[TGProgressWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[progressWindow show:true];
__weak TGChannelLinkSetupController *weakSelf = self;
[[[[TGChannelManagementSignals updateChannelUsername:strongSelf->_conversation.conversationId accessHash:strongSelf->_conversation.accessHash username:strongSelf->_usernameItem.username] deliverOn:[SQueue mainQueue]] onDispose:^{
TGDispatchOnMainThread(^{
[progressWindow dismiss:true];
});
}] startWithNext:nil error:^(__unused id error) {
__strong TGChannelLinkSetupController *strongSelf = weakSelf;
if (strongSelf != nil) {
[[[TGAlertView alloc] initWithTitle:TGLocalized(@"Username.InvalidTaken") message:nil cancelButtonTitle:TGLocalized(@"Common.OK") okButtonTitle:nil completionBlock:nil] show];
}
} completed:^{
__strong TGChannelLinkSetupController *strongSelf = weakSelf;
if (strongSelf != nil) {
[strongSelf.view endEditing:true];
[strongSelf.presentingViewController dismissViewControllerAnimated:true completion:nil];
}
}];
}
}
};
if (_usernameItem.username.length != 0 && _conversation.username.length == 0) {
[[[TGAlertView alloc] initWithTitle:nil message:TGLocalized(@"Channel.Edit.PrivatePublicLinkAlert") cancelButtonTitle:TGLocalized(@"Common.Cancel") okButtonTitle:TGLocalized(@"Common.OK") completionBlock:^(bool okButtonPressed) {
if (okButtonPressed) {
continueSetup();
}
}] show];;
} else {
continueSetup();
}
}
}
- (void)setUsernameState:(TGUsernameControllerUsernameState)state username:(NSString *)username
{
bool valid = false;
switch (state)
{
case TGUsernameControllerUsernameStateNone:
_invalidUsernameItem.showProgress = false;
valid = true;
break;
case TGUsernameControllerUsernameStateValid:
_invalidUsernameItem.showProgress = false;
valid = true;
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 TGUsernameControllerUsernameStateTooManyUsernames:
_invalidUsernameItem.showProgress = false;
break;
case TGUsernameControllerUsernameStateChecking:
_invalidUsernameItem.showProgress = true;
break;
}
self.navigationItem.rightBarButtonItem.enabled = !_invalidUsernameItem.showProgress && valid;
[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(@"Channel.Username.UsernameIsAvailable"), username]];
_invalidUsernameItem.alpha = 1.0f;
_invalidUsernameItem.hidden = false;
_invalidUsernameItem.showProgress = false;
[_invalidUsernameItem setTextColor:UIColorRGB(0x26972c)];
break;
case TGUsernameControllerUsernameStateTooShort:
[_invalidUsernameItem setText:TGLocalized(@"Channel.Username.InvalidTooShort")];
_invalidUsernameItem.alpha = 1.0f;
_invalidUsernameItem.hidden = false;
_invalidUsernameItem.showProgress = false;
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
break;
case TGUsernameControllerUsernameStateInvalidCharacters:
[_invalidUsernameItem setText:TGLocalized(@"Channel.Username.InvalidCharacters")];
_invalidUsernameItem.alpha = 1.0f;
_invalidUsernameItem.hidden = false;
_invalidUsernameItem.showProgress = false;
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
break;
case TGUsernameControllerUsernameStateStartsWithNumber:
[_invalidUsernameItem setText:TGLocalized(@"Channel.Username.InvalidStartsWithNumber")];
_invalidUsernameItem.alpha = 1.0f;
_invalidUsernameItem.hidden = false;
_invalidUsernameItem.showProgress = false;
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
break;
case TGUsernameControllerUsernameStateTaken:
[_invalidUsernameItem setText:TGLocalized(@"Channel.Username.InvalidTaken")];
_invalidUsernameItem.alpha = 1.0f;
_invalidUsernameItem.hidden = false;
_invalidUsernameItem.showProgress = false;
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
break;
case TGUsernameControllerUsernameStateTooManyUsernames:
[_invalidUsernameItem setText:TGLocalized(@"Channel.Username.InvalidTooManyUsernames")];
_invalidUsernameItem.alpha = 1.0f;
_invalidUsernameItem.hidden = false;
_invalidUsernameItem.showProgress = false;
[_invalidUsernameItem setTextColor:UIColorRGB(0xcf3030)];
break;
case TGUsernameControllerUsernameStateChecking:
[_invalidUsernameItem setText:[[NSString alloc] initWithFormat:@" %@", TGLocalized(@"Channel.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
{
[_checkUsernameDisposable setDisposable: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];
SSignal *checkSignal = [[[SSignal complete] delay:0.2 onQueue:[SQueue mainQueue]] then:[TGChannelManagementSignals checkChannelUsername:_conversation.conversationId accessHash:_conversation.accessHash username:username]];
__weak TGChannelLinkSetupController *weakSelf = self;
[_checkUsernameDisposable setDisposable:[[checkSignal deliverOn:[SQueue mainQueue]] startWithNext:nil error:^(id error) {
__strong TGChannelLinkSetupController *strongSelf = weakSelf;
if (strongSelf != nil) {
NSString *errorText = [[TGTelegramNetworking instance] extractNetworkErrorType:error];
TGUsernameControllerUsernameState state = TGUsernameControllerUsernameStateTaken;
if ([errorText isEqual:@"CHANNELS_ADMIN_PUBLIC_TOO_MUCH"]) {
state = TGUsernameControllerUsernameStateTooManyUsernames;
}
[strongSelf setUsernameState:state username:strongSelf->_usernameItem.username];
}
} completed:^{
__strong TGChannelLinkSetupController *strongSelf = weakSelf;
if (strongSelf != nil) {
strongSelf->_usernameItem.usernameChecking = false;
[strongSelf setUsernameState:TGUsernameControllerUsernameStateValid username:strongSelf->_usernameItem.username];
}
}]];
}
[self updateLinkHint:username];
}
- (void)updateLinkHint:(NSString *)username
{
if (username.length == 0)
_hintItem.text = nil;
else
[_hintItem setFormattedText:[[NSString alloc] initWithFormat:TGLocalized(@"Channel.Username.LinkHint"), username]];
}
@end