diff --git a/Riot/AppDelegate.h b/Riot/AppDelegate.h index c50209be9..69ae2addd 100644 --- a/Riot/AppDelegate.h +++ b/Riot/AppDelegate.h @@ -101,7 +101,14 @@ extern NSString *const kAppDelegateNetworkStatusDidChangeNotification; // Reload all running matrix sessions - (void)reloadMatrixSessions:(BOOL)clearCache; -- (void)logout; +/** + Log out all the accounts after asking for a potential confirmation. + Show the authentication screen on successful logout. + + @param askConfirmation tell whether a confirmation is required before logging out. + @param completion the block to execute at the end of the operation. + */ +- (void)logoutWithConfirmation:(BOOL)askConfirmation completion:(void (^)(BOOL isLoggedOut))completion; #pragma mark - Matrix Accounts handling diff --git a/Riot/AppDelegate.m b/Riot/AppDelegate.m index f8a79e326..2d06f62cb 100644 --- a/Riot/AppDelegate.m +++ b/Riot/AppDelegate.m @@ -208,6 +208,8 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN @property (strong, nonatomic) UIAlertController *mxInAppNotification; +@property (strong, nonatomic) UIAlertController *logoutConfirmation; + @property (nonatomic, nullable, copy) void (^registrationForRemoteNotificationsCompletion)(NSError *); @@ -2084,6 +2086,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN }]; } } + // Check whether this is a registration links. else if ([pathParams[0] isEqualToString:@"register"]) { NSLog(@"[AppDelegate] Universal link with registration parameters"); @@ -2395,7 +2398,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN // Logout the app when there is no available account if (![MXKAccountManager sharedManager].accounts.count) { - [self logout]; + [self logoutWithConfirmation:NO completion:nil]; } }]; @@ -2567,8 +2570,90 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN } } -- (void)logout +- (void)logoutWithConfirmation:(BOOL)askConfirmation completion:(void (^)(BOOL isLoggedOut))completion { + // Check whether we have to ask confirmation before logging out. + if (askConfirmation) + { + if (self.logoutConfirmation) + { + [self.logoutConfirmation dismissViewControllerAnimated:NO completion:nil]; + self.logoutConfirmation = nil; + } + + __weak typeof(self) weakSelf = self; + + NSString *message = NSLocalizedStringFromTable(@"settings_sign_out_confirmation", @"Vector", nil); + + // If the user has encrypted rooms, warn he will lose his e2e keys + MXSession *session = self.mxSessions.firstObject; + for (MXRoom *room in session.rooms) + { + if (room.state.isEncrypted) + { + message = [message stringByAppendingString:[NSString stringWithFormat:@"\n\n%@", NSLocalizedStringFromTable(@"settings_sign_out_e2e_warn", @"Vector", nil)]]; + break; + } + } + + // Ask confirmation + self.logoutConfirmation = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil) message:message preferredStyle:UIAlertControllerStyleAlert]; + + [self.logoutConfirmation addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil) + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * action) { + + if (weakSelf) + { + typeof(self) self = weakSelf; + self.logoutConfirmation = nil; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + + [self logoutWithConfirmation:NO completion:completion]; + + }); + } + + }]]; + + [self.logoutConfirmation addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] + style:UIAlertActionStyleCancel + handler:^(UIAlertAction * action) { + + if (weakSelf) + { + typeof(self) self = weakSelf; + self.logoutConfirmation = nil; + + if (completion) + { + completion(NO); + } + } + + }]]; + + [self.logoutConfirmation mxk_setAccessibilityIdentifier: @"AppDelegateLogoutConfirmationAlert"]; + [self showNotificationAlert:self.logoutConfirmation]; + return; + } + + // Display a loading wheel during the logout process + id topVC; + if (_masterTabBarController && _masterTabBarController == _masterNavigationController.visibleViewController) + { + topVC = _masterTabBarController.selectedViewController; + } + else + { + topVC = _masterNavigationController.visibleViewController; + } + if (topVC && [topVC respondsToSelector:@selector(startActivityIndicator)]) + { + [topVC startActivityIndicator]; + } + self.pushRegistry = nil; isPushRegistered = NO; @@ -2587,15 +2672,22 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN #endif // Logout all matrix account - [[MXKAccountManager sharedManager] logout]; - - // Return to authentication screen - [_masterTabBarController showAuthenticationScreen]; - - // Note: Keep App settings - - // Reset the contact manager - [[MXKContactManager sharedManager] reset]; + [[MXKAccountManager sharedManager] logoutWithCompletion:^{ + + if (completion) + { + completion (YES); + } + + // Return to authentication screen + [_masterTabBarController showAuthenticationScreen]; + + // Note: Keep App settings + + // Reset the contact manager + [[MXKContactManager sharedManager] reset]; + + }]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context @@ -2917,7 +3009,7 @@ NSString *const kAppDelegateNetworkStatusDidChangeNotification = @"kAppDelegateN typeof(self) self = weakSelf; self->_errorNotification = nil; - [self logout]; + [self logoutWithConfirmation:NO completion:nil]; } }]]; diff --git a/Riot/ViewController/MasterTabBarController.m b/Riot/ViewController/MasterTabBarController.m index 38f3ba6ad..6a1a6c667 100644 --- a/Riot/ViewController/MasterTabBarController.m +++ b/Riot/ViewController/MasterTabBarController.m @@ -372,13 +372,19 @@ } else { - NSLog(@"[MasterTabBarController] Universal link: Logout current sessions and open AuthViewController to complete the registration"); + NSLog(@"[MasterTabBarController] Universal link: Prompt to logout current sessions and open AuthViewController to complete the registration"); // Keep a ref on the params authViewControllerRegistrationParameters = parameters; - // And do a logout out. It will then display AuthViewController - [[AppDelegate theDelegate] logout]; + // Prompt to logout. It will then display AuthViewController if the user is logged out. + [[AppDelegate theDelegate] logoutWithConfirmation:YES completion:^(BOOL isLoggedOut) { + if (!isLoggedOut) + { + // Reset temporary params + authViewControllerRegistrationParameters = nil; + } + }]; } } diff --git a/Riot/ViewController/SettingsViewController.m b/Riot/ViewController/SettingsViewController.m index a81a10fcb..acb4c8126 100644 --- a/Riot/ViewController/SettingsViewController.m +++ b/Riot/ViewController/SettingsViewController.m @@ -2572,63 +2572,24 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); - (void)onSignout:(id)sender { - [currentAlert dismissViewControllerAnimated:NO completion:nil]; - - __weak typeof(self) weakSelf = self; - - NSString *message = NSLocalizedStringFromTable(@"settings_sign_out_confirmation", @"Vector", nil); - - // If the user has encrypted rooms, warn he will lose his e2e keys - MXSession* session = [[AppDelegate theDelegate].mxSessions objectAtIndex:0]; - for (MXRoom *room in session.rooms) - { - if (room.state.isEncrypted) + // Feedback: disable button and run activity indicator + UIButton *button = (UIButton*)sender; + button.enabled = NO; + [self startActivityIndicator]; + + __weak typeof(self) weakSelf = self; + + [[AppDelegate theDelegate] logoutWithConfirmation:YES completion:^(BOOL isLoggedOut) { + + if (!isLoggedOut && weakSelf) { - message = [message stringByAppendingString:[NSString stringWithFormat:@"\n\n%@", NSLocalizedStringFromTable(@"settings_sign_out_e2e_warn", @"Vector", nil)]]; - break; + typeof(self) self = weakSelf; + + // Enable the button and stop activity indicator + button.enabled = YES; + [self stopActivityIndicator]; } - } - - // Ask confirmation - currentAlert = [UIAlertController alertControllerWithTitle:NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil) message:message preferredStyle:UIAlertControllerStyleAlert]; - - [currentAlert addAction:[UIAlertAction actionWithTitle:NSLocalizedStringFromTable(@"settings_sign_out", @"Vector", nil) - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { - - if (weakSelf) - { - typeof(self) self = weakSelf; - self->currentAlert = nil; - - // Feedback: disable button and run activity indicator - UIButton *button = (UIButton*)sender; - button.enabled = NO; - [self startActivityIndicator]; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - - [[MXKAccountManager sharedManager] logout]; - - }); - } - - }]]; - - [currentAlert addAction:[UIAlertAction actionWithTitle:[NSBundle mxk_localizedStringForKey:@"cancel"] - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * action) { - - if (weakSelf) - { - typeof(self) self = weakSelf; - self->currentAlert = nil; - } - - }]]; - - [currentAlert mxk_setAccessibilityIdentifier: @"SettingsVCSignoutAlert"]; - [self presentViewController:currentAlert animated:YES completion:nil]; + }]; } - (void)onRemove3PID:(NSIndexPath*)path @@ -2932,7 +2893,7 @@ typedef void (^blockSettingsViewController_onReadyToDestroy)(); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - [[MXKAccountManager sharedManager] logout]; + [[AppDelegate theDelegate] logoutWithConfirmation:NO completion:nil]; }); }