blob: 53e7334e2e79ba9c1362ec8c9e8eee6c1020056b [file] [log] [blame]
Loïc Siretfcb4ca62016-09-21 17:12:09 -04001/*
2 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
3 * Author: Loïc Siret <loic.siret@savoirfairelinux.com>
Kateryna Kostiukecaa3952018-07-13 16:00:34 -04004 * Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
Loïc Siretfcb4ca62016-09-21 17:12:09 -04005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#import "RingWizardNewAccountVC.h"
22
23
24//Cocoa
Loïc Siretfcb4ca62016-09-21 17:12:09 -040025#import <Quartz/Quartz.h>
Kateryna Kostiuk91b44e32018-09-28 17:08:02 -040026#import <AVFoundation/AVFoundation.h>
Loïc Siretfcb4ca62016-09-21 17:12:09 -040027
28//Qt
29#import <QUrl>
30#import <QPixmap>
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040031#import <QSize>
32#import <QtMacExtras/qmacfunctions.h>
Loïc Siretfcb4ca62016-09-21 17:12:09 -040033
34//LRC
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040035#import <api/lrc.h>
36#import <api/newaccountmodel.h>
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040037#import <api/account.h>
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040038#import <interfaces/pixmapmanipulatori.h>
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -040039#import <namedirectory.h>
Loïc Siretfcb4ca62016-09-21 17:12:09 -040040
Loïc Siretfcb4ca62016-09-21 17:12:09 -040041#import "Constants.h"
42#import "views/NSImage+Extensions.h"
43#import "views/NSColor+RingTheme.h"
Andreas Traczyk92c101e2018-07-03 14:43:53 -040044#import "utils.h"
Loïc Siretfcb4ca62016-09-21 17:12:09 -040045
46@interface RingWizardNewAccountVC ()
47@end
48
49@implementation RingWizardNewAccountVC
50{
Loïc Siret3652cfb2016-10-27 10:12:07 -040051 __unsafe_unretained IBOutlet NSView* loadingView;
52 __unsafe_unretained IBOutlet NSView* creationView;
53
Loïc Siretfcb4ca62016-09-21 17:12:09 -040054 __unsafe_unretained IBOutlet NSButton* photoView;
Alexandre Lision882289b2016-10-31 16:10:39 -040055 __unsafe_unretained IBOutlet NSTextField* displayNameField;
56 __unsafe_unretained IBOutlet NSTextField* registeredNameField;
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -040057 __unsafe_unretained IBOutlet NSTextField* registeredNameError;
58 __unsafe_unretained IBOutlet NSTextField* passwordError;
Loïc Siretfcb4ca62016-09-21 17:12:09 -040059 __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
Loïc Siret3652cfb2016-10-27 10:12:07 -040060 __unsafe_unretained IBOutlet NSSecureTextField* passwordRepeatField;
Kateryna Kostiuk87ae2bf2018-05-04 13:46:17 -040061 __unsafe_unretained IBOutlet NSImageView* addProfilePhotoImage;
Loïc Siret3652cfb2016-10-27 10:12:07 -040062
63 __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
Alexandre Lision882289b2016-10-31 16:10:39 -040064
Alexandre Lision882289b2016-10-31 16:10:39 -040065 __unsafe_unretained IBOutlet NSProgressIndicator* indicatorLookupResult;
66
67 __unsafe_unretained IBOutlet NSPopover* helpBlockchainContainer;
68 __unsafe_unretained IBOutlet NSPopover* helpPasswordContainer;
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -050069 __unsafe_unretained IBOutlet NSLayoutConstraint* buttonTopConstraint;
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -050070 __unsafe_unretained IBOutlet NSButton* passwordButton;
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -040071 __unsafe_unretained IBOutlet NSStackView* repeatPasswordView;
Alexandre Lision882289b2016-10-31 16:10:39 -040072
Alexandre Lision882289b2016-10-31 16:10:39 -040073 QMetaObject::Connection registeredNameFound;
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040074 QMetaObject::Connection accountCreated;
75 QMetaObject::Connection accountRemoved;
Alexandre Lision882289b2016-10-31 16:10:39 -040076
77 BOOL lookupQueued;
78 NSString* usernameWaitingForLookupResult;
Kateryna Kostiukc867eb92020-03-08 13:15:17 -040079 QString accountToCreate;
Loïc Siretfcb4ca62016-09-21 17:12:09 -040080}
81
Alexandre Lision882289b2016-10-31 16:10:39 -040082NSInteger const DISPLAY_NAME_TAG = 1;
83NSInteger const BLOCKCHAIN_NAME_TAG = 2;
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -040084NSInteger const PASSWORD_TAG = 3;
85NSInteger const REPEAT_PASSWORD_TAG = 4;
Loïc Siretfcb4ca62016-09-21 17:12:09 -040086
Loïc Siret3652cfb2016-10-27 10:12:07 -040087//ERROR CODE for textfields validations
88NSInteger const ERROR_PASSWORD_TOO_SHORT = -1;
89NSInteger const ERROR_REPEAT_MISMATCH = -2;
90
Kateryna Kostiukecaa3952018-07-13 16:00:34 -040091@synthesize accountModel;
92
93-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountmodel:(lrc::api::NewAccountModel*) accountModel {
94 if (self = [self initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
95 {
96 self.accountModel = accountModel;
97 }
98 return self;
99}
100
Loïc Siret3652cfb2016-10-27 10:12:07 -0400101- (BOOL)produceError:(NSError**)error withCode:(NSInteger)code andMessage:(NSString*)message
102{
103 if (error != NULL){
104 NSDictionary *errorDetail = @{NSLocalizedDescriptionKey: message};
105 *error = [NSError errorWithDomain:@"Input" code:code userInfo:errorDetail];
106 }
107 return NO;
108}
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400109
Alexandre Lision882289b2016-10-31 16:10:39 -0400110- (IBAction)showBlockchainHelp:(id)sender
111{
112 [helpBlockchainContainer showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMaxYEdge];
113}
114
115- (IBAction)showPasswordHelp:(id)sender
116{
117 [helpPasswordContainer showRelativeToRect:[sender bounds] ofView:sender preferredEdge:NSMaxYEdge];
118}
119
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400120- (void)prepareViewToShow {
121 [self.view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
122 [creationView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
Kateryna Kostiuk61d41162019-10-25 16:51:44 -0400123 [loadingView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400124 [passwordField setHidden: YES];
125 [repeatPasswordView setHidden: YES];
126 buttonTopConstraint.constant = 35;
127}
128
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400129- (void)show
130{
Alexandre Lision882289b2016-10-31 16:10:39 -0400131 [displayNameField setTag:DISPLAY_NAME_TAG];
132 [registeredNameField setTag:BLOCKCHAIN_NAME_TAG];
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400133 [photoView setWantsLayer: YES];
134 photoView.layer.cornerRadius = photoView.frame.size.width / 2;
135 photoView.layer.masksToBounds = YES;
Alexandre Lisionc2ad6392016-11-08 11:20:34 -0500136 self.signUpBlockchainState = YES;
137 [self toggleSignupRing:nil];
Kateryna Kostiuk87ae2bf2018-05-04 13:46:17 -0400138 [addProfilePhotoImage setWantsLayer: YES];
139 [photoView setBordered:YES];
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -0500140 [passwordButton setState: NSControlStateValueOff];
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -0500141 self.registeredName = @"";
142 self.password = @"";
143 self.repeatPassword = @"";
Loïc Siret3652cfb2016-10-27 10:12:07 -0400144 [self display:creationView];
145}
146
Loïc Siret3652cfb2016-10-27 10:12:07 -0400147- (void)display:(NSView *)view
148{
149 [self.delegate showView:view];
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400150}
151
152- (IBAction)editPhoto:(id)sender
153{
Loïc Siret3652cfb2016-10-27 10:12:07 -0400154 auto pictureTaker = [IKPictureTaker pictureTaker];
Kateryna Kostiukdc563242019-08-19 12:05:54 -0400155#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
Kateryna Kostiuk91b44e32018-09-28 17:08:02 -0400156 if (@available(macOS 10.14, *)) {
157 AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
158 if(authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)
159 {
160 [pictureTaker setValue:0 forKey:IKPictureTakerAllowsVideoCaptureKey];
161 }
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400162
Kateryna Kostiuk91b44e32018-09-28 17:08:02 -0400163 if(authStatus == AVAuthorizationStatusNotDetermined)
164 {
165 [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
166 if(!granted){
167 [pictureTaker setValue:0 forKey:IKPictureTakerAllowsVideoCaptureKey];
168 }
169 }];
170 }
171 }
Kateryna Kostiukdc563242019-08-19 12:05:54 -0400172#endif
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400173 [pictureTaker beginPictureTakerSheetForWindow:[self.delegate window]
174 withDelegate:self
175 didEndSelector:@selector(pictureTakerDidEnd:returnCode:contextInfo:)
176 contextInfo:nil];
177
178}
179
180- (void)pictureTakerDidEnd:(IKPictureTaker *) picker
Alexandre Lision882289b2016-10-31 16:10:39 -0400181 returnCode:(NSInteger) code
182 contextInfo:(void*) contextInfo
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400183{
Kateryna Kostiuk256814e2018-09-04 14:47:33 -0400184 //do nothing when editing canceled
185 if (code == 0) {
186 return;
187 }
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400188 if (auto outputImage = [picker outputImage]) {
Kateryna Kostiuk87ae2bf2018-05-04 13:46:17 -0400189 [photoView setBordered:NO];
Kateryna Kostiuk1f8c1252018-07-30 18:18:57 -0400190 auto image = [picker inputImage];
Kateryna Kostiuk2f2ef952019-05-07 11:04:41 -0400191 CGFloat newSize = MIN(MIN(image.size.height, image.size.width), MAX_IMAGE_SIZE);
192 outputImage = [outputImage imageResizeInsideMax: newSize];
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400193 [photoView setImage:outputImage];
Kateryna Kostiuk87ae2bf2018-05-04 13:46:17 -0400194 [addProfilePhotoImage setHidden:YES];
195 } else if(!photoView.image) {
196 [photoView setBordered:YES];
197 [addProfilePhotoImage setHidden:NO];
Alexandre Lisionc2ad6392016-11-08 11:20:34 -0500198 }
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400199}
200
Loïc Siret3652cfb2016-10-27 10:12:07 -0400201#pragma mark - Input validation
Alexandre Lision882289b2016-10-31 16:10:39 -0400202
Loïc Siret3652cfb2016-10-27 10:12:07 -0400203- (BOOL)isPasswordValid
204{
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400205 return self.password.length >= 6 || self.password.length == 0;
Loïc Siret3652cfb2016-10-27 10:12:07 -0400206}
207
208- (BOOL)isRepeatPasswordValid
209{
Anthony Léonard24110e82017-09-15 16:29:11 -0400210 return [self.password isEqualToString:self.repeatPassword] || ([self.password length] == 0 && [self.repeatPassword length] == 0);
Loïc Siret3652cfb2016-10-27 10:12:07 -0400211}
212
213- (BOOL)validateRepeatPassword:(NSError **)error
214{
215 if (!self.isRepeatPasswordValid){
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400216 passwordError.stringValue = NSLocalizedString(@"Passwords don't match",
217 @"Indication for user");
Loïc Siret3652cfb2016-10-27 10:12:07 -0400218 return [self produceError:error
219 withCode:ERROR_REPEAT_MISMATCH
220 andMessage:NSLocalizedString(@"Passwords don't match",
Alexandre Lision882289b2016-10-31 16:10:39 -0400221 @"Indication for user")];
Loïc Siret3652cfb2016-10-27 10:12:07 -0400222 }
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400223 passwordError.stringValue = @"";
Loïc Siret3652cfb2016-10-27 10:12:07 -0400224 return YES;
225}
226
227- (BOOL)validatePassword:(NSError **)error
228{
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400229 if (!self.isPasswordValid){
230 passwordError.stringValue = NSLocalizedString(@"Password is too short",
231 @"Indication for user");
Loïc Siret3652cfb2016-10-27 10:12:07 -0400232 return [self produceError:error
233 withCode:ERROR_PASSWORD_TOO_SHORT
234 andMessage:NSLocalizedString(@"Password is too short",
Alexandre Lision882289b2016-10-31 16:10:39 -0400235 @"Indication for user")];
Loïc Siret3652cfb2016-10-27 10:12:07 -0400236 }
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400237 passwordError.stringValue = @"";
Loïc Siret3652cfb2016-10-27 10:12:07 -0400238 return YES;
239}
240
241- (BOOL)validateUserInputPassword:(NSError **)error
242{
243 return [self validatePassword:error] && [self validateRepeatPassword:error];
244}
245
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400246- (IBAction)createRingAccount:(id)sender
247{
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400248 QObject::disconnect(accountCreated);
249 QObject::disconnect(accountRemoved);
250 accountCreated = QObject::connect(self.accountModel,
251 &lrc::api::NewAccountModel::accountAdded,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400252 [self] (const QString& accountID) {
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400253 if(accountID.compare(accountToCreate) != 0) {
254 return;
255 }
256 QObject::disconnect(accountCreated);
257 QObject::disconnect(accountRemoved);
258 //set account avatar
259 if([photoView image]) {
260 NSImage *avatarImage = [photoView image];
261 auto imageToBytes = QByteArray::fromNSData([avatarImage TIFFRepresentation]).toBase64();
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400262 self.accountModel->setAvatar(accountID, QString(imageToBytes));
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400263 }
264 //register username
265 if (self.registeredName && ![self.registeredName isEqualToString:@""]) {
266 NSString *passwordString = self.password ? self.password: @"";
267 NSString *usernameString = self.registeredName;
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400268 self.accountModel->registerName(accountID,
269 QString::fromNSString(passwordString),
270 QString::fromNSString(usernameString));
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400271 }
Kateryna Kostiuk0c0801e2019-07-18 20:10:51 -0400272 lrc::api::account::ConfProperties_t accountProperties = self.accountModel->getAccountConfig(accountID);
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400273 accountProperties.Ringtone.ringtonePath = QString::fromNSString(defaultRingtonePath());
Kateryna Kostiuk0c0801e2019-07-18 20:10:51 -0400274 self.accountModel->setAccountConfig(accountID, accountProperties);
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400275 [self registerDefaultPreferences];
Kateryna Kostiuk61d41162019-10-25 16:51:44 -0400276 [self.delegate didCreateAccountWithSuccess:YES accountId: accountToCreate];
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400277 });
278 //if account creation failed remove loading view
279 accountRemoved = QObject::connect(self.accountModel,
280 &lrc::api::NewAccountModel::accountRemoved,
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400281 [self] (const QString& accountID) {
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400282 if(accountID.compare(accountToCreate) != 0) {
283 return;
284 }
285 QObject::disconnect(accountCreated);
286 QObject::disconnect(accountRemoved);
Kateryna Kostiuk61d41162019-10-25 16:51:44 -0400287 [self.delegate didCreateAccountWithSuccess:NO accountId: accountToCreate];
Kateryna Kostiukecaa3952018-07-13 16:00:34 -0400288 });
Loïc Siret3652cfb2016-10-27 10:12:07 -0400289 [self display:loadingView];
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400290 [progressBar startAnimation:nil];
Loïc Siret3652cfb2016-10-27 10:12:07 -0400291
Kateryna Kostiukc867eb92020-03-08 13:15:17 -0400292 accountToCreate = self.accountModel->createNewAccount(lrc::api::profile::Type::RING, QString::fromNSString(displayNameField.stringValue),"",QString::fromNSString(passwordField.stringValue), "");
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400293}
294
295/**
296 * Set default values for preferences
297 */
298- (void)registerDefaultPreferences
299{
Andreas Traczyk92c101e2018-07-03 14:43:53 -0400300 if (!appSandboxed()) {
301 // enable AutoStartup
302 LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
303 if (loginItemsRef == nil) return;
304 CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
305 LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
306 if (itemRef) CFRelease(itemRef);
307 }
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400308
309 // enable Notifications
Kateryna Kostiuke3503842018-12-12 16:39:45 -0500310 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::CallNotifications];
311 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::MessagesNotifications];
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400312}
313
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400314- (IBAction)cancel:(id)sender
315{
Kateryna Kostiuk61d41162019-10-25 16:51:44 -0400316 [self.delegate didCreateAccountWithSuccess:NO accountId: accountToCreate];
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400317}
318
Alexandre Lision882289b2016-10-31 16:10:39 -0400319#pragma mark - UserNameRegistration delegate methods
320
321- (IBAction)toggleSignupRing:(id)sender
322{
323 if (self.withBlockchain) {
324 [self lookupUserName];
325 }
326}
327
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -0500328- (IBAction)togglePasswordButton:(NSButton *)sender
329{
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400330 [passwordField setHidden: !passwordField.hidden];
331 [repeatPasswordView setHidden: !repeatPasswordView.hidden];
332 buttonTopConstraint.constant = repeatPasswordView.hidden ? 35 : 25;
333 [self display:creationView];
Kateryna Kostiuk23222fe2018-11-16 14:28:02 -0500334}
335
Alexandre Lision882289b2016-10-31 16:10:39 -0400336- (BOOL)withBlockchain
337{
338 return self.signUpBlockchainState == NSOnState;
339}
340
341- (BOOL)userNameAvailableORNotBlockchain
342{
343 return !self.withBlockchain || (self.registeredName.length > 0 && self.isUserNameAvailable);
344}
345
346- (void)showLookUpAvailable:(BOOL)available andText:(NSString *)message
347{
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400348 if (registeredNameField.stringValue.length > 0) {
349 registeredNameError.stringValue = message;
350 }
351 [indicatorLookupResult setHidden:YES];
352 [indicatorLookupResult stopAnimation:nil];
Alexandre Lision882289b2016-10-31 16:10:39 -0400353}
354
355- (void)onUsernameAvailabilityChangedWithNewAvailability:(BOOL)newAvailability
356{
357 self.isUserNameAvailable = newAvailability;
358}
359
360- (void)hideLookupSpinner
361{
362 [indicatorLookupResult setHidden:YES];
363}
364
365- (void)showLookupSpinner
366{
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400367 registeredNameError.stringValue = @"";
368 if (registeredNameField.stringValue.length > 0) {
369 [indicatorLookupResult setHidden:NO];
370 [indicatorLookupResult startAnimation:nil];
371 }
Alexandre Lision882289b2016-10-31 16:10:39 -0400372}
373
374- (BOOL)lookupUserName
375{
376 [self showLookupSpinner];
377 QObject::disconnect(registeredNameFound);
378 registeredNameFound = QObject::connect(
379 &NameDirectory::instance(),
380 &NameDirectory::registeredNameFound,
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400381 [=] (NameDirectory::LookupStatus status,
382 const QString& address, const QString& name) {
Alexandre Lision882289b2016-10-31 16:10:39 -0400383 NSLog(@"Name lookup ended");
384 lookupQueued = NO;
385 //If this is the username we are waiting for, we can disconnect.
386 if (name.compare(QString::fromNSString(usernameWaitingForLookupResult)) == 0) {
387 QObject::disconnect(registeredNameFound);
388 } else {
389 //Keep waiting...
390 return;
391 }
392
393 //We may now stop the spinner
394 [self hideLookupSpinner];
395
396 BOOL isAvailable = NO;
397 NSString* message;
398 switch(status)
399 {
400 case NameDirectory::LookupStatus::SUCCESS:
401 {
402 message = NSLocalizedString(@"The entered username is not available",
403 @"Text shown to user when his username is already registered");
404 isAvailable = NO;
405 break;
406 }
407 case NameDirectory::LookupStatus::NOT_FOUND:
408 {
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400409 message = @"";
Alexandre Lision882289b2016-10-31 16:10:39 -0400410 isAvailable = YES;
411 break;
412 }
413 case NameDirectory::LookupStatus::INVALID_NAME:
414 {
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400415 message = NSLocalizedString(@"Invalid username.",
Alexandre Lision882289b2016-10-31 16:10:39 -0400416 @"Text shown to user when his username is invalid to be registered");
417 isAvailable = NO;
418 break;
419 }
420 case NameDirectory::LookupStatus::ERROR:
421 default:
422 {
423 message = NSLocalizedString(@"Failed to perform lookup",
424 @"Text shown to user when an error occur at registration");
425 isAvailable = NO;
426 break;
427 }
428 }
429 [self showLookUpAvailable:isAvailable andText: message];
430 [self onUsernameAvailabilityChangedWithNewAvailability:isAvailable];
431
432 });
433
434 //Start the lookup in a second so that the UI dosen't seem to freeze
Kateryna Kostiukbe7e2e42019-07-26 17:44:12 -0400435 BOOL result = NameDirectory::instance().lookupName(QString(), QString::fromNSString(usernameWaitingForLookupResult));
Alexandre Lision882289b2016-10-31 16:10:39 -0400436
437}
438
Alexandre Lision5dc5d312016-11-10 10:41:37 -0500439#pragma mark - NSTextFieldDelegate delegate methods
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400440
Alexandre Lision882289b2016-10-31 16:10:39 -0400441- (void)controlTextDidChange:(NSNotification *)notif
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400442{
443 NSTextField* textField = [notif object];
Kateryna Kostiukc7e68f32019-10-09 16:15:45 -0400444 if (textField.tag == PASSWORD_TAG) {
445 NSError *error = nil;
446 [self validatePassword: &error];
447 return;
448 }
449 if (textField.tag == REPEAT_PASSWORD_TAG) {
450 NSError *error = nil;
451 [self validateRepeatPassword: &error];
452 return;
453 }
Alexandre Lision882289b2016-10-31 16:10:39 -0400454 if (textField.tag != BLOCKCHAIN_NAME_TAG) {
455 return;
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400456 }
Alexandre Lision882289b2016-10-31 16:10:39 -0400457 NSString* alias = textField.stringValue;
Alexandre Lision882289b2016-10-31 16:10:39 -0400458 [self showLookupSpinner];
459 [self onUsernameAvailabilityChangedWithNewAvailability:NO];
460 [NSObject cancelPreviousPerformRequestsWithTarget:self];
461 [self performSelector:@selector(lookUp:) withObject:alias afterDelay:0.5];
462}
463
464- (void) lookUp:(NSString*) name
465{
466 if (self.withBlockchain && !lookupQueued) {
467 usernameWaitingForLookupResult = name;
468 lookupQueued = YES;
469 [self lookupUserName];
470 }
471}
472
473
474+ (NSSet *)keyPathsForValuesAffectingUserNameAvailableORNotBlockchain
475{
476 return [NSSet setWithObjects: NSStringFromSelector(@selector(signUpBlockchainState)),
477 NSStringFromSelector(@selector(isUserNameAvailable)),
478 nil];
479}
480
481+ (NSSet *)keyPathsForValuesAffectingWithBlockchain
482{
483 return [NSSet setWithObjects: NSStringFromSelector(@selector(signUpBlockchainState)),
484 nil];
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400485}
486
Loïc Siret3652cfb2016-10-27 10:12:07 -0400487+ (NSSet *)keyPathsForValuesAffectingIsPasswordValid
488{
489 return [NSSet setWithObjects:@"password", nil];
490}
491
492+ (NSSet *)keyPathsForValuesAffectingIsRepeatPasswordValid
493{
494 return [NSSet setWithObjects:@"password", @"repeatPassword", nil];
495}
Loïc Siretfcb4ca62016-09-21 17:12:09 -0400496@end