blob: 063018f4c726510fe10bc08e6c5dea89b555c639 [file] [log] [blame]
/*
* Copyright (C) 2016 Savoir-faire Linux Inc.
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import "RegisterNameWC.h"
//Cocoa
#import <AddressBook/AddressBook.h>
//LRC
#import <accountmodel.h>
#import <QItemSelectionModel>
#import <account.h>
#import "AppDelegate.h"
@interface RegisterNameWC ()
@end
@implementation RegisterNameWC
{
__unsafe_unretained IBOutlet NSTextField* registeredNameField;
__unsafe_unretained IBOutlet NSSecureTextField* passwordField;
__unsafe_unretained IBOutlet NSImageView* ivLookupResult;
__unsafe_unretained IBOutlet NSProgressIndicator* indicatorLookupResult;
__unsafe_unretained IBOutlet NSProgressIndicator *registrationProgress;
QMetaObject::Connection registrationEnded;
QMetaObject::Connection registeredNameFound;
BOOL lookupQueued;
NSString* usernameWaitingForLookupResult;
}
NSInteger const BLOCKCHAIN_NAME_TAG = 2;
- (id)initWithDelegate:(id <LoadingWCDelegate>) del
{
return [self initWithDelegate:del actionCode:0];
}
- (id)initWithDelegate:(id <RegisterNameDelegate>) del actionCode:(NSInteger) code
{
return [super initWithWindowNibName:@"RegisterNameWindow" delegate:del actionCode:code];
}
- (void)windowDidLoad
{
[super windowDidLoad];
[registeredNameField setTag:BLOCKCHAIN_NAME_TAG];
self.registeredName = @"";
[ivLookupResult setHidden:YES];
[indicatorLookupResult setHidden:YES];
}
#pragma mark - Input validation
- (BOOL)isPasswordValid
{
return self.password.length >= 6;
}
#pragma mark - Username validation delegate methods
- (BOOL)userNameAvailable
{
return (self.registeredName.length > 0 && self.isUserNameAvailable);
}
- (void)showLookUpAvailable:(BOOL)available andText:(NSString *)message
{
[ivLookupResult setImage:[NSImage imageNamed:(available?@"ic_action_accept":@"ic_action_cancel")]] ;
[ivLookupResult setHidden:NO];
[ivLookupResult setToolTip:message];
}
- (void)onUsernameAvailabilityChangedWithNewAvailability:(BOOL)newAvailability
{
self.isUserNameAvailable = newAvailability;
}
- (void)hideLookupSpinner
{
[indicatorLookupResult setHidden:YES];
}
- (void)showLookupSpinner
{
[ivLookupResult setHidden:YES];
[indicatorLookupResult setHidden:NO];
[indicatorLookupResult startAnimation:nil];
}
- (BOOL)lookupUserName
{
[self showLookupSpinner];
QObject::disconnect(registeredNameFound);
registeredNameFound = QObject::connect(
&NameDirectory::instance(),
&NameDirectory::registeredNameFound,
[=] ( const Account* account, NameDirectory::LookupStatus status, const QString& address, const QString& name) {
NSLog(@"Name lookup ended");
lookupQueued = NO;
//If this is the username we are waiting for, we can disconnect.
if (name.compare(QString::fromNSString(usernameWaitingForLookupResult)) == 0) {
QObject::disconnect(registeredNameFound);
} else {
//Keep waiting...
return;
}
//We may now stop the spinner
[self hideLookupSpinner];
BOOL isAvailable = NO;
NSString* message;
switch(status)
{
case NameDirectory::LookupStatus::SUCCESS:
{
message = NSLocalizedString(@"The entered username is not available",
@"Text shown to user when his username is already registered");
isAvailable = NO;
break;
}
case NameDirectory::LookupStatus::NOT_FOUND:
{
message = NSLocalizedString(@"The entered username is available",
@"Text shown to user when his username is available to be registered");
isAvailable = YES;
break;
}
case NameDirectory::LookupStatus::INVALID_NAME:
{
message = NSLocalizedString(@"The entered username is invalid. It must have at leat 3 characters and contains only lowercase alphanumeric characters.",
@"Text shown to user when his username is invalid to be registered");
isAvailable = NO;
break;
}
case NameDirectory::LookupStatus::ERROR:
default:
{
message = NSLocalizedString(@"Failed to perform lookup",
@"Text shown to user when an error occur at registration");
isAvailable = NO;
break;
}
}
[self showLookUpAvailable:isAvailable andText: message];
[self onUsernameAvailabilityChangedWithNewAvailability:isAvailable];
}
);
//Start the lookup in a second so that the UI dosen't seem to freeze
BOOL result = NameDirectory::instance().lookupName(nullptr, QString(), QString::fromNSString(usernameWaitingForLookupResult));
}
- (void)controlTextDidChange:(NSNotification *)notif
{
NSTextField* textField = [notif object];
if (textField.tag != BLOCKCHAIN_NAME_TAG) {
return;
}
NSString* alias = textField.stringValue;
[self showLookupSpinner];
[self onUsernameAvailabilityChangedWithNewAvailability:NO];
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[self performSelector:@selector(lookUp:) withObject:alias afterDelay:0.5];
}
- (void) lookUp:(NSString*) name
{
if (!lookupQueued) {
usernameWaitingForLookupResult = name;
lookupQueued = YES;
[self lookupUserName];
}
}
#pragma mark - Registration process
- (IBAction)registerUsername:(id)sender
{
[registrationProgress startAnimation:nil];
[self showLoading];
[self setCallback];
self.isUserNameAvailable = AccountModel::instance().selectedAccount()->registerName(QString::fromNSString(self.password),
QString::fromNSString(self.registeredName));
if (!self.isUserNameAvailable) {
NSLog(@"Could not initialize registerName operation");
QObject::disconnect(registrationEnded);
}
}
- (void)setCallback
{
QObject::disconnect(registrationEnded);
registrationEnded = QObject::connect(AccountModel::instance().selectedAccount(),
&Account::nameRegistrationEnded,
[=] (NameDirectory::RegisterNameStatus status, const QString& name)
{
QObject::disconnect(registrationEnded);
switch(status) {
case NameDirectory::RegisterNameStatus::WRONG_PASSWORD:
case NameDirectory::RegisterNameStatus::ALREADY_TAKEN:
case NameDirectory::RegisterNameStatus::NETWORK_ERROR:
[self showError];
break;
case NameDirectory::RegisterNameStatus::SUCCESS:
[self.delegate didRegisterNameWithSuccess];
break;
}
});
}
+ (NSSet *)keyPathsForValuesAffectingUserNameAvailableORNotBlockchain
{
return [NSSet setWithObjects: NSStringFromSelector(@selector(isUserNameAvailable)), nil];
}
+ (NSSet *)keyPathsForValuesAffectingIsPasswordValid
{
return [NSSet setWithObjects:@"password", nil];
}
@end