diff --git a/Monal/Classes/ActiveChatsViewController.m b/Monal/Classes/ActiveChatsViewController.m index 1bfedaf5b..2e37f53d9 100755 --- a/Monal/Classes/ActiveChatsViewController.m +++ b/Monal/Classes/ActiveChatsViewController.m @@ -25,6 +25,7 @@ #import "XMPPIQ.h" #import "MLIQProcessor.h" #import "UIColor+Theme.h" +#import "Quicksy_Country.h" #import #define prependToViewQueue(firstArg, ...) metamacro_if_eq(0, metamacro_argcount(__VA_ARGS__))([self prependToViewQueue:firstArg withId:MLViewIDUnspecified andFile:(char*)__FILE__ andLine:__LINE__ andFunc:(char*)__func__])(_prependToViewQueue(firstArg, __VA_ARGS__)) @@ -654,7 +655,7 @@ -(void) segueToIntroScreensIfNeeded prependToViewQueue(MLViewIDWelcomeLoginView, (^(PMKResolver resolve) { #ifdef IS_QUICKSY - if([[DataLayer sharedInstance] enabledAccountCnts].intValue == 0) + if([[[DataLayer sharedInstance] accountList] count] == 0) { DDLogDebug(@"Showing account registration view..."); UIViewController* view = [[SwiftuiInterface new] makeAccountRegistration:@{}]; @@ -713,6 +714,19 @@ -(void) segueToIntroScreensIfNeeded NSArray* needingMigration = [[DataLayer sharedInstance] accountListNeedingPasswordMigration]; if(needingMigration.count > 0) { +#ifdef IS_QUICKSY + DDLogDebug(@"Showing account registration view to do password migration..."); + UIViewController* view = [[SwiftuiInterface new] makeAccountRegistration:@{}]; + if(UIDevice.currentDevice.userInterfaceIdiom != UIUserInterfaceIdiomPad) + view.modalPresentationStyle = UIModalPresentationFullScreen; + else + view.ml_disposeCallback = ^{ + [self sheetDismissed]; + }; + [self dismissCompleteViewChainWithAnimation:NO andCompletion:^{ + [self presentViewController:view animated:NO completion:^{resolve(nil);}]; + }]; +#else DDLogDebug(@"Showing password migration view..."); UIViewController* passwordMigration = [[SwiftuiInterface new] makePasswordMigration:needingMigration]; passwordMigration.ml_disposeCallback = ^{ @@ -721,6 +735,7 @@ -(void) segueToIntroScreensIfNeeded [self dismissCompleteViewChainWithAnimation:NO andCompletion:^{ [self presentViewController:passwordMigration animated:YES completion:^{resolve(nil);}]; }]; +#endif } else resolve(nil); @@ -737,7 +752,8 @@ -(void) syncContacts [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError* _Nullable error) { if(granted) { - NSString* countryCode = [[HelperTools defaultsDB] objectForKey:@"Quicksy_countryCode"]; + Quicksy_Country* country = [[HelperTools defaultsDB] objectForKey:@"Quicksy_country"]; + NSString* countryCode = country.code; NSCharacterSet* allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:@"+0123456789"] invertedSet]; NSMutableDictionary* numbers = [NSMutableDictionary new]; diff --git a/Monal/Classes/HelperTools.m b/Monal/Classes/HelperTools.m index dd26c4c85..81b315e6e 100644 --- a/Monal/Classes/HelperTools.m +++ b/Monal/Classes/HelperTools.m @@ -58,6 +58,7 @@ #import "MLContactSoftwareVersionInfo.h" #import "IPC.h" #import "MLDelayableTimer.h" +#import "Quicksy_Country.h" @import UserNotifications; @import CoreImage; @@ -324,6 +325,7 @@ -(void) swizzled_setObject:(id) value forKey:(NSString*) defaultName if( [value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] || + [value isKindOfClass:[NSDate class]] || [value isKindOfClass:[NSURL class]] || [value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSMutableDictionary class]] || diff --git a/Monal/Classes/MLXMPPManager.m b/Monal/Classes/MLXMPPManager.m index b03ae396f..6dadc4944 100644 --- a/Monal/Classes/MLXMPPManager.m +++ b/Monal/Classes/MLXMPPManager.m @@ -712,7 +712,6 @@ -(void) sendChatState:(BOOL) isTyping toContact:(MLContact*) contact #pragma mark - login/register -//this will NOT set plain_activated to YES, only using the advanced account creation ui can do this -(NSNumber*) login:(NSString*) jid password:(NSString*) password { //check if it is a JID diff --git a/Monal/Classes/Quicksy_RegisterAccount.swift b/Monal/Classes/Quicksy_RegisterAccount.swift index 2a0457f4f..653d3d0cf 100644 --- a/Monal/Classes/Quicksy_RegisterAccount.swift +++ b/Monal/Classes/Quicksy_RegisterAccount.swift @@ -47,8 +47,8 @@ class Quicksy_State: ObservableObject { @defaultsDB("Quicksy_phoneNumber") var phoneNumber: String? - @defaultsDB("Quicksy_countryCode") - var countryCode: String? + @defaultsDB("Quicksy_country") + var country: Quicksy_Country? } struct Quicksy_RegisterAccount: View { @@ -77,8 +77,7 @@ struct Quicksy_RegisterAccount: View { init(delegate: SheetDismisserProtocol) { self.delegate = delegate - self.state.phoneNumber = nil - var countries = COUNTRY_CODES + var countries = COUNTRY_CODES as! [Quicksy_Country] countries.sort { country2name($0) < country2name($1) } @@ -92,6 +91,7 @@ struct Quicksy_RegisterAccount: View { }.done { data, response in DDLogDebug("Got sendSMSRequest success: \(String(describing:response))\n\(String(describing:data))") state.phoneNumber = number + state.country = selectedCountry //used to add a country code to phonebook entries not having any }.catch { error in DDLogError("Catched sendSMSRequest error: \(String(describing:error))") if let response = error as? PMKHTTPError { @@ -101,9 +101,8 @@ struct Quicksy_RegisterAccount: View { } private func createAccount() { - state.countryCode = selectedCountry!.code //used to add a country code to phonebook entries not having any let password = HelperTools.generateRandomPassword() - if let number = state.phoneNumber { + if let number = state.phoneNumber, let _ = state.country { showPromisingLoadingOverlay(overlay, headline:NSLocalizedString("Registering account...", comment: ""), description: "") { sendRegisterRequest(number:number, pin:pin, password:password) }.done { result in @@ -111,12 +110,22 @@ struct Quicksy_RegisterAccount: View { startLoginTimeout() showLoadingOverlay(overlay, headline:NSLocalizedString("Logging in", comment: "")) self.errorObserverEnabled = true - self.newAccountNo = MLXMPPManager.sharedInstance().login("\(number)@quicksy.im", password: password) - if(self.newAccountNo == nil) { - currentTimeout = nil // <- disable timeout on error - errorObserverEnabled = false - showLoginErrorAlert(errorMessage:NSLocalizedString("Account already configured!", comment: "")) - self.newAccountNo = nil + //check if account is already configured and reset its password and its enabled and needs_password_migration states + if let newAccountID = DataLayer.sharedInstance().accountID(forUser:number, andDomain:"quicksy.im") { + self.newAccountNo = newAccountID + var accountDict = DataLayer.sharedInstance().details(forAccount:newAccountID) as! [String:AnyObject] + accountDict["needs_password_migration"] = NSNumber(value:false) + accountDict["enabled"] = NSNumber(value:true) + DDLogDebug("Updating account in DB: enabled=\(String(describing:accountDict["enabled"])), needs_password_migration=\(String(describing:accountDict["needs_password_migration"])), password.count=\(password.count)") + DataLayer.sharedInstance().updateAccoun(with:accountDict) + MLXMPPManager.sharedInstance().updatePassword(password, forAccount:newAccountID) + DDLogDebug("Connecting successfully recovered and enabled account...") + MLXMPPManager.sharedInstance().connectAccount(newAccountID) + } else { + self.newAccountNo = MLXMPPManager.sharedInstance().login("\(number)@quicksy.im", password: password) + if(self.newAccountNo == nil) { + unreachable("Account already configured? This should never happen!") + } } }.catch { error in DDLogError("Catched sendRegisterRequest error: \(String(describing:error))") @@ -191,7 +200,7 @@ struct Quicksy_RegisterAccount: View { /// Ensure the ZStack takes the entire area Color.clear - if state.phoneNumber == nil { + if state.phoneNumber == nil || state.country == nil { VStack(alignment: .leading) { Text("Verify your phone number") .font(.title) @@ -287,13 +296,20 @@ struct Quicksy_RegisterAccount: View { DDLogInfo("Localization: current locale localized string for regionCode: \(String(describing:Locale.current.localizedString(forRegionCode:regionCode)))") DDLogInfo("Localization: en_US localized string for regionCode: \(String(describing:Locale(identifier: "en_US").localizedString(forRegionCode:regionCode)))") for country in countries { - if country.alpha2 == regionCode || country.name == Locale.current.localizedString(forRegionCode:regionCode) || country.name == Locale(identifier: "en_US").localizedString(forRegionCode:regionCode) { + if let previousCountry = state.country { + //check alpha2 code and country name explicitly to still match even when changing other properties + if previousCountry.alpha2 == country.alpha2 || previousCountry.name == country.name { + selectedCountry = country + break + } + } else if country.alpha2 == regionCode || country.name == Locale.current.localizedString(forRegionCode:regionCode) || country.name == Locale(identifier: "en_US").localizedString(forRegionCode:regionCode) { selectedCountry = country + break } } phoneNumberFocused = true } - } else if let number = state.phoneNumber { + } else if let number = state.phoneNumber, let _ = state.country { VStack(alignment: .leading) { Text("Verify your phone number") .font(.title) @@ -389,6 +405,8 @@ struct Quicksy_RegisterAccount: View { .onAppear { pinFocused = true } + } else { + unreachable("quicksy registration out of ui options!") } } .alert(isPresented: $showAlert) { diff --git a/Monal/Classes/SwiftHelpers.swift b/Monal/Classes/SwiftHelpers.swift index 27b329d38..ea3cb01da 100644 --- a/Monal/Classes/SwiftHelpers.swift +++ b/Monal/Classes/SwiftHelpers.swift @@ -35,6 +35,9 @@ public typealias monal_id_block_t = @convention(block) (AnyObject?) -> Void; public typealias monal_id_returning_void_block_t = @convention(block) () -> AnyObject?; public typealias monal_id_returning_id_block_t = @convention(block) (AnyObject?) -> AnyObject?; +extension MLContact : Identifiable {} //make MLContact be usable in swiftui ForEach clauses etc. +extension Quicksy_Country : Identifiable {} //make Quicksy_Country be usable in swiftui ForEach clauses etc. + //see https://stackoverflow.com/a/40629365/3528174 extension String: Error {} diff --git a/Monal/Classes/SwiftuiHelpers.swift b/Monal/Classes/SwiftuiHelpers.swift index 02fd33b20..87e7303af 100644 --- a/Monal/Classes/SwiftuiHelpers.swift +++ b/Monal/Classes/SwiftuiHelpers.swift @@ -19,8 +19,6 @@ import FLAnimatedImage import OrderedCollections import CropViewController -extension MLContact : Identifiable {} //make MLContact be usable in swiftui ForEach clauses - let monalGreen = Color(UIColor(red:128.0/255, green:203.0/255, blue:182.0/255, alpha:1.0)); let monalDarkGreen = Color(UIColor(red:20.0/255, green:138.0/255, blue:103.0/255, alpha:1.0));