From c93ea790f5c37a30a60db9b660120a6dad7c7cfb Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 4 Oct 2023 18:07:10 +0200 Subject: [PATCH 01/10] Add "Notification by email" button in setting (button has no action actually) --- .../Modules/Settings/SettingsViewController.m | 28 +++++++++++++++++++ .../Localizations/fr.lproj/Tchap.strings | 2 +- Tchap/target.yml | 1 + Tools/SwiftGen/swiftgen-config.yml | 5 ++-- 4 files changed, 33 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 16c9d8893..e51f8376e 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -119,6 +119,7 @@ typedef NS_ENUM(NSUInteger, NOTIFICATION_SETTINGS) NOTIFICATION_SETTINGS_DEFAULT_SETTINGS_INDEX, NOTIFICATION_SETTINGS_MENTION_AND_KEYWORDS_SETTINGS_INDEX, NOTIFICATION_SETTINGS_OTHER_SETTINGS_INDEX, + NOTIFICATION_SETTINGS_ENABLE_BY_EMAIL_INDEX, // Tchap: allow notifications by email }; typedef NS_ENUM(NSUInteger, CALLS_ENABLE_STUN_SERVER) @@ -483,6 +484,7 @@ - (void)updateSections [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_SHOW_DECODED_CONTENT]; } + [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_ENABLE_BY_EMAIL_INDEX]; [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_PIN_MISSED_NOTIFICATIONS_INDEX]; [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_PIN_UNREAD_INDEX]; @@ -2193,6 +2195,27 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleShowDecodedContent:) forControlEvents:UIControlEventTouchUpInside]; + cell = labelAndSwitchCell; + } + else if (row == NOTIFICATION_SETTINGS_ENABLE_BY_EMAIL_INDEX) + { + MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; + + labelAndSwitchCell.mxkLabel.text = TchapL10n.settingsNotificationEmail; + labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor; + labelAndSwitchCell.mxkSwitch.enabled = YES; + [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleNotificationsByEmail:) forControlEvents:UIControlEventTouchUpInside]; + +// BOOL isPushEnabled = account.pushNotificationServiceIsActive; +// +// // Even if push is enabled for the account, the user may have turned off notifications in system settings +// if (isPushEnabled && self.systemNotificationSettings) +// { +// isPushEnabled = self.systemNotificationSettings.authorizationStatus == UNAuthorizationStatusAuthorized; +// } + + labelAndSwitchCell.mxkSwitch.on = !labelAndSwitchCell.mxkSwitch.on; + cell = labelAndSwitchCell; } else if (row == NOTIFICATION_SETTINGS_PIN_MISSED_NOTIFICATIONS_INDEX) @@ -3380,6 +3403,11 @@ - (void)togglePushNotifications:(UISwitch *)sender } } +- (void)toggleNotificationsByEmail:(UISwitch *)sender +{ + NSLog(@"toggleNotificationsByEmail"); +} + - (void)toggleShowInAppNotifications:(UISwitch *)sender { RiotSettings.shared.showInAppNotifications = sender.isOn; diff --git a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings index 7a68d8800..74e52114e 100644 --- a/Tchap/Assets/Localizations/fr.lproj/Tchap.strings +++ b/Tchap/Assets/Localizations/fr.lproj/Tchap.strings @@ -145,7 +145,7 @@ "settings_show_profile_changes_messages_title" = "Afficher les changements d’avatar"; "settings_crypto_import" = "Importer les clés"; "settings_crypto_import_invalid_file" = "Fichier de clés invalide."; - +"settings_notification_email" = "Notification par courriel"; //////////////////////////////////////////////////////////////////////////////// // MARK: Search diff --git a/Tchap/target.yml b/Tchap/target.yml index 014ac20f5..3a7179b2d 100644 --- a/Tchap/target.yml +++ b/Tchap/target.yml @@ -112,6 +112,7 @@ targetTemplates: - "**/*.strings" # Exclude all strings files - "**/*.cer" - path: ../Tchap/Generated/Images_Riot.swift + - path: ../Tchap/Generated/Strings.swift - path: ../Tchap/Modules/Application/VersionUpdate - path: ../Tchap/Modules/Room/Views/BubbleCells/Antivirus diff --git a/Tools/SwiftGen/swiftgen-config.yml b/Tools/SwiftGen/swiftgen-config.yml index 18ba80afd..654a3bec1 100755 --- a/Tools/SwiftGen/swiftgen-config.yml +++ b/Tools/SwiftGen/swiftgen-config.yml @@ -33,10 +33,11 @@ ib: strings: inputs: Tchap/Assets/Localizations/fr.lproj/Tchap.strings outputs: - - templateName: flat-swift4 + templatePath: Templates/Strings/flat-swift4-vector.stencil output: Tchap/Generated/Strings.swift params: - enumName: TchapL10n + className: TchapL10n + publicAccess: true xcassets: - inputs: - Tchap/Assets/Images.xcassets From 8c4e425157db335e0fdb20731f973dda490c714e Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 5 Oct 2023 17:37:01 +0200 Subject: [PATCH 02/10] Rename currentPusher -> currentApnsPush to prepare the use of currentEmailPusher --- .../MatrixKit/Models/Account/MXKAccount.h | 2 +- .../MatrixKit/Models/Account/MXKAccount.m | 48 +++++++++---------- .../Modules/Settings/SettingsViewController.m | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h index ecd5b3aad..59ee455bd 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h @@ -313,7 +313,7 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer @param success A block object called when the operation succeeds. @param failure A block object called when the operation fails. */ -- (void)loadCurrentPusher:(nullable void (^)(void))success failure:(nullable void (^)(NSError *error))failure; +- (void)loadCurrentApnsPusher:(nullable void (^)(void))success failure:(nullable void (^)(NSError *error))failure; /** Load the current device information for this account. diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 8d03739af..622ba40b6 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -84,7 +84,7 @@ @interface MXKAccount () // Observe NSCurrentLocaleDidChangeNotification to refresh MXRoomSummaries on time formatting change. id NSCurrentLocaleDidChangeNotificationObserver; - MXPusher *currentPusher; + MXPusher *currentApnsPusher; } /// Will be true if the session is not in a pauseable state or we requested for the session to pause but not finished yet. Will be reverted to false again after `resume` called. @@ -148,7 +148,7 @@ - (nonnull instancetype)initWithCredentials:(MXCredentials*)credentials // Refresh device information [self loadDeviceInformation:nil failure:nil]; - [self loadCurrentPusher:nil failure:nil]; + [self loadCurrentApnsPusher:nil failure:nil]; [self registerAccountDataDidChangeIdentityServerNotification]; [self registerIdentityServiceDidChangeAccessTokenNotification]; @@ -184,7 +184,7 @@ - (id)initWithCoder:(NSCoder *)coder // Refresh device information [self loadDeviceInformation:nil failure:nil]; - [self loadCurrentPusher:nil failure:nil]; + [self loadCurrentApnsPusher:nil failure:nil]; } return self; @@ -304,10 +304,10 @@ - (UIColor*)userTintColor - (BOOL)pushNotificationServiceIsActive { - if (currentPusher && currentPusher.enabled) + if (currentApnsPusher && currentApnsPusher.enabled) { - MXLogDebug(@"[MXKAccount][Push] pushNotificationServiceIsActive: currentPusher.enabled %@", currentPusher.enabled); - return currentPusher.enabled.boolValue; + MXLogDebug(@"[MXKAccount][Push] pushNotificationServiceIsActive: currentPusher.enabled %@", currentApnsPusher.enabled); + return currentApnsPusher.enabled.boolValue; } BOOL pushNotificationServiceIsActive = ([[MXKAccountManager sharedManager] isAPNSAvailable] && self.hasPusherForPushNotifications && mxSession); @@ -324,22 +324,22 @@ - (void)enablePushNotifications:(BOOL)enable if (enable) { - if (currentPusher && currentPusher.enabled && !currentPusher.enabled.boolValue) + if (currentApnsPusher && currentApnsPusher.enabled && !currentApnsPusher.enabled.boolValue) { - [self.mxSession.matrixRestClient setPusherWithPushkey:currentPusher.pushkey - kind:currentPusher.kind - appId:currentPusher.appId - appDisplayName:currentPusher.appDisplayName - deviceDisplayName:currentPusher.deviceDisplayName - profileTag:currentPusher.profileTag - lang:currentPusher.lang - data:currentPusher.data.JSONDictionary + [self.mxSession.matrixRestClient setPusherWithPushkey:currentApnsPusher.pushkey + kind:currentApnsPusher.kind + appId:currentApnsPusher.appId + appDisplayName:currentApnsPusher.appDisplayName + deviceDisplayName:currentApnsPusher.deviceDisplayName + profileTag:currentApnsPusher.profileTag + lang:currentApnsPusher.lang + data:currentApnsPusher.data.JSONDictionary append:NO enabled:enable success:^{ MXLogDebug(@"[MXKAccount][Push] enablePushNotifications: remotely enabled Push: Success"); - [self loadCurrentPusher:^{ + [self loadCurrentApnsPusher:^{ if (success) { success(); @@ -398,7 +398,7 @@ - (void)enablePushNotifications:(BOOL)enable } } } - else if (self.hasPusherForPushNotifications || currentPusher) + else if (self.hasPusherForPushNotifications || currentApnsPusher) { MXLogDebug(@"[MXKAccount][Push] enablePushNotifications: Disable APNS for %@ account", self.mxCredentials.userId); @@ -670,7 +670,7 @@ - (void)load3PIDs:(void (^)(void))success failure:(void (^)(NSError *))failure }]; } -- (void)loadCurrentPusher:(void (^)(void))success failure:(void (^)(NSError *error))failure +- (void)loadCurrentApnsPusher:(void (^)(void))success failure:(void (^)(NSError *error))failure { if (!self.mxSession.myDeviceId) { @@ -699,13 +699,13 @@ - (void)loadCurrentPusher:(void (^)(void))success failure:(void (^)(NSError *err MXPusher *ownPusher; for (MXPusher *pusher in pushers) { - if ([pusher.deviceId isEqualToString:self.mxSession.myDeviceId]) + if ([pusher.kind isEqualToString:@"http"] && [pusher.deviceId isEqualToString:self.mxSession.myDeviceId]) { ownPusher = pusher; } } - self->currentPusher = ownPusher; + self->currentApnsPusher = ownPusher; if (success) { @@ -876,7 +876,7 @@ -(void)openSessionWithStore:(id)store [MXKContactManager.sharedManager validateSyncLocalContactsStateForSession:self.mxSession]; // Refresh pusher state - [self loadCurrentPusher:^{ + [self loadCurrentApnsPusher:^{ [self refreshAPNSPusher]; } failure:nil]; [self refreshPushKitPusher]; @@ -1206,7 +1206,7 @@ - (void)refreshAPNSPusher { MXLogDebug(@"[MXKAccount][Push] refreshAPNSPusher"); - if (currentPusher) + if (currentApnsPusher) { MXLogDebug(@"[MXKAccount][Push] refreshAPNSPusher aborted as a pusher has been found"); return; @@ -1272,7 +1272,7 @@ - (void)enableAPNSPusher:(BOOL)enabled success:(void (^)(void))success failure:( if (enabled) { - [self loadCurrentPusher:^{ + [self loadCurrentApnsPusher:^{ if (success) { success(); @@ -1290,7 +1290,7 @@ - (void)enableAPNSPusher:(BOOL)enabled success:(void (^)(void))success failure:( } else { - self->currentPusher = nil; + self->currentApnsPusher = nil; if (success) { diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index e51f8376e..0c3a29b83 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -1418,7 +1418,7 @@ - (void)refreshSettings // Update notification access [self refreshSystemNotificationSettings]; - [[MXKAccountManager sharedManager].activeAccounts.firstObject loadCurrentPusher:nil failure:nil]; + [[MXKAccountManager sharedManager].activeAccounts.firstObject loadCurrentApnsPusher:nil failure:nil]; } - (void)refreshSystemNotificationSettings From 55b196c07fb1355594a168350d399926b430bcb4 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Fri, 6 Oct 2023 08:59:23 +0200 Subject: [PATCH 03/10] Activate Email Pusher linked to email only --- .../MatrixKit/Models/Account/MXKAccount.h | 26 +- .../MatrixKit/Models/Account/MXKAccount.m | 371 +++++++++++++++++- .../MatrixKit/Models/Account/MXKAccountData.h | 7 + .../MatrixKit/Models/Account/MXKAccountData.m | 2 + .../Modules/Settings/SettingsViewController.m | 16 +- .../UserSessionOverviewService.swift | 2 +- 6 files changed, 407 insertions(+), 17 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h index 59ee455bd..97c11f5dd 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h @@ -307,7 +307,7 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer - (void)load3PIDs:(void (^)(void))success failure:(void (^)(NSError *error))failure; /** - Loads the pusher instance linked to this account. + Loads theAPNS pusher instance linked to this account. This method must be called to refresh self.pushNotificationServiceIsActive @param success A block object called when the operation succeeds. @@ -315,6 +315,30 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer */ - (void)loadCurrentApnsPusher:(nullable void (^)(void))success failure:(nullable void (^)(NSError *error))failure; +// Tchap: email notifications +/** + Enable Email notification. + + This method creates or removes a pusher on the homeserver. + + @param enable YES to enable it. + @param success A block object called when the operation succeeds. + @param failure A block object called when the operation fails. + */ +- (void)enableEmailNotifications:(BOOL)enable + success:(void (^)(void))success + failure:(void (^)(NSError *))failure; + +// Tchap: email notifications +/** + Loads the Email pusher instance linked to this account. + This method must be called to refresh self.emailNotificationServiceIsActive + + @param success A block object called when the operation succeeds. + @param failure A block object called when the operation fails. + */ +- (void)loadCurrentEmailPusher:(nullable void (^)(void))success failure:(nullable void (^)(NSError *error))failure; + /** Load the current device information for this account. This method must be called to refresh self.device. diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 622ba40b6..8b5f800d2 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -85,6 +85,7 @@ @interface MXKAccount () id NSCurrentLocaleDidChangeNotificationObserver; MXPusher *currentApnsPusher; + MXPusher *currentEmailPusher; // Tchap: email notifications } /// Will be true if the session is not in a pauseable state or we requested for the session to pause but not finished yet. Will be reverted to false again after `resume` called. @@ -149,6 +150,7 @@ - (nonnull instancetype)initWithCredentials:(MXCredentials*)credentials // Refresh device information [self loadDeviceInformation:nil failure:nil]; [self loadCurrentApnsPusher:nil failure:nil]; + [self loadCurrentEmailPusher:nil failure:nil]; // Tchap: email notifications [self registerAccountDataDidChangeIdentityServerNotification]; [self registerIdentityServiceDidChangeAccessTokenNotification]; @@ -185,6 +187,7 @@ - (id)initWithCoder:(NSCoder *)coder // Refresh device information [self loadDeviceInformation:nil failure:nil]; [self loadCurrentApnsPusher:nil failure:nil]; + [self loadCurrentEmailPusher:nil failure:nil]; // Tchap: email notifications } return self; @@ -302,6 +305,8 @@ - (UIColor*)userTintColor return userTintColor; } +#pragma mark - Notification Pusher + - (BOOL)pushNotificationServiceIsActive { if (currentApnsPusher && currentApnsPusher.enabled) @@ -422,6 +427,117 @@ - (void)enablePushNotifications:(BOOL)enable } } +#pragma mark - Tchap Email Pusher + +// Tchap: email notifications +- (BOOL)emailNotificationServiceIsActive +{ + if (currentEmailPusher && currentEmailPusher.enabled) + { + MXLogDebug(@"[MXKAccount][Push] emailNotificationServiceIsActive: currentPusher.enabled %@", currentEmailPusher.enabled); + return currentEmailPusher.enabled.boolValue; + } + + BOOL emailNotificationServiceIsActive = (self.hasPusherForEmailNotifications && mxSession); + MXLogDebug(@"[MXKAccount][Push] emailNotificationServiceIsActive: %@", @(emailNotificationServiceIsActive)); + + return emailNotificationServiceIsActive; +} + +// Tchap: email notifications +- (void)enableEmailNotifications:(BOOL)enable + success:(void (^)(void))success + failure:(void (^)(NSError *))failure +{ + MXLogDebug(@"[MXKAccount][Push] enableEmailNotifications: %@", @(enable)); + + if (enable) + { + if (currentEmailPusher && currentEmailPusher.enabled && !currentEmailPusher.enabled.boolValue) + { + [self.mxSession.matrixRestClient setPusherWithPushkey:currentEmailPusher.pushkey + kind:currentEmailPusher.kind + appId:currentEmailPusher.appId + appDisplayName:currentEmailPusher.appDisplayName + deviceDisplayName:currentEmailPusher.deviceDisplayName + profileTag:currentEmailPusher.profileTag + lang:currentEmailPusher.lang + data:currentEmailPusher.data.JSONDictionary + append:NO + enabled:enable + success:^{ + + MXLogDebug(@"[MXKAccount][Push] enableEmailNotifications: remotely enabled Email notifications: Success"); + [self loadCurrentEmailPusher:^{ + if (success) + { + success(); + } + } failure:^(NSError *error) { + + MXLogWarning(@"[MXKAccount][Push] enableEmailNotifications: load current pusher failed with error: %@", error); + if (failure) + { + failure(error); + } + }]; + } failure:^(NSError *error) { + + MXLogWarning(@"[MXKAccount][Push] enableEmailNotifications: remotely enable Email notifications failed with error: %@", error); + if (failure) + { + failure(error); + } + }]; + } + else + { + MXLogDebug(@"[MXKAccount][Push] enableEmailNotifications: Enable Email for %@ account", self.mxCredentials.userId); + + // Create/restore the pusher + [self enableEmailPusher:YES success:^{ + + MXLogDebug(@"[MXKAccount][Push] enableEmailNotifications: Enable Email: Success"); + if (success) + { + success(); + } + } failure:^(NSError *error) { + + MXLogDebug(@"[MXKAccount][Push] enableEmailNotifications: Enable Email: Error: %@", error); + if (failure) + { + failure(error); + } + }]; + } + } + else if (self.hasPusherForEmailNotifications || currentEmailPusher) + { + MXLogDebug(@"[MXKAccount][Push] enableEmailNotifications: Disable Email notifications for %@ account", self.mxCredentials.userId); + + // Delete the pusher, report the new value only on success. + [self enableEmailPusher:NO + success:^{ + + MXLogDebug(@"[MXKAccount][Push] enableEmailNotifications: Disable Push: Success"); + if (success) + { + success(); + } + } failure:^(NSError *error) { + + MXLogDebug(@"[MXKAccount][Push] enableEmailNotifications: Disable Push: Error: %@", error); + if (failure) + { + failure(error); + } + }]; + } +} + +#pragma mark - Push Kit Pusher + - (BOOL)isPushKitNotificationActive { BOOL isPushKitNotificationActive = ([[MXKAccountManager sharedManager] isPushAvailable] && self.hasPusherForPushKitNotifications && mxSession); @@ -674,7 +790,7 @@ - (void)loadCurrentApnsPusher:(void (^)(void))success failure:(void (^)(NSError { if (!self.mxSession.myDeviceId) { - MXLogWarning(@"[MXKAccount] loadPusher: device ID not found"); + MXLogWarning(@"[MXKAccount] loadApnsPusher: device ID not found"); if (failure) { failure([NSError errorWithDomain:kMXKAccountErrorDomain code:0 userInfo:nil]); @@ -685,7 +801,7 @@ - (void)loadCurrentApnsPusher:(void (^)(void))success failure:(void (^)(NSError [self.mxSession supportedMatrixVersions:^(MXMatrixVersions *matrixVersions) { if (!matrixVersions.supportsRemotelyTogglingPushNotifications) { - MXLogDebug(@"[MXKAccount] loadPusher: remotely toggling push notifications not supported"); + MXLogDebug(@"[MXKAccount] loadApnsPusher: remotely toggling push notifications not supported"); if (success) { @@ -696,23 +812,89 @@ - (void)loadCurrentApnsPusher:(void (^)(void))success failure:(void (^)(NSError } [self.mxSession.matrixRestClient pushers:^(NSArray *pushers) { - MXPusher *ownPusher; + MXPusher *apnsPusher; for (MXPusher *pusher in pushers) { - if ([pusher.kind isEqualToString:@"http"] && [pusher.deviceId isEqualToString:self.mxSession.myDeviceId]) - { - ownPusher = pusher; + if ([pusher.deviceId isEqualToString:self.mxSession.myDeviceId]) { + if ([pusher.kind isEqualToString:@"http"]) + { + apnsPusher = pusher; + } } } - self->currentApnsPusher = ownPusher; + self->currentApnsPusher = apnsPusher; + + if (success) + { + success(); + } + } failure:^(NSError *error) { + MXLogWarning(@"[MXKAccount] loadApnsPusher: get pushers failed due to error %@", error); + + if (failure) + { + failure(error); + } + }]; + } failure:^(NSError *error) { + MXLogWarning(@"[MXKAccount] loadApnsPusher: supportedMatrixVersions failed due to error %@", error); + + if (failure) + { + failure(error); + } + }]; +} + +// Tchap: email notifications +- (void)loadCurrentEmailPusher:(void (^)(void))success failure:(void (^)(NSError *error))failure +{ + // DeviceId not needed nor present for Email pusher +// if (!self.mxSession.myDeviceId) +// { +// MXLogWarning(@"[MXKAccount] loadEmailPusher: device ID not found"); +// if (failure) +// { +// failure([NSError errorWithDomain:kMXKAccountErrorDomain code:0 userInfo:nil]); +// } +// return; +// } + + [self.mxSession supportedMatrixVersions:^(MXMatrixVersions *matrixVersions) { + // Tchpa: TODO check for supportsRemotelyTogglingEmailNotifications +// if (!matrixVersions.supportsRemotelyTogglingPushNotifications) +// { +// MXLogDebug(@"[MXKAccount] loadEmailPusher: remotely toggling push notifications not supported"); +// +// if (success) +// { +// success(); +// } +// +// return; +// } + + [self.mxSession.matrixRestClient pushers:^(NSArray *pushers) { + MXPusher *emailPusher; + for (MXPusher *pusher in pushers) + { +// if ([pusher.deviceId isEqualToString:self.mxSession.myDeviceId]) { + if ([pusher.kind isEqualToString:@"email"]) + { + emailPusher = pusher; + } +// } + } + + self->currentEmailPusher = emailPusher; if (success) { success(); } } failure:^(NSError *error) { - MXLogWarning(@"[MXKAccount] loadPusher: get pushers failed due to error %@", error); + MXLogWarning(@"[MXKAccount] loadEmailPusher: get pushers failed due to error %@", error); if (failure) { @@ -720,7 +902,7 @@ - (void)loadCurrentApnsPusher:(void (^)(void))success failure:(void (^)(NSError } }]; } failure:^(NSError *error) { - MXLogWarning(@"[MXKAccount] loadPusher: supportedMatrixVersions failed due to error %@", error); + MXLogWarning(@"[MXKAccount] loadEmailPusher: supportedMatrixVersions failed due to error %@", error); if (failure) { @@ -880,7 +1062,13 @@ -(void)openSessionWithStore:(id)store [self refreshAPNSPusher]; } failure:nil]; [self refreshPushKitPusher]; - + + // Tchap: email notifications + // Refresh Email pusher state + [self loadCurrentEmailPusher:^{ + [self refreshEmailPusher]; + } failure:nil]; + // Launch server sync [self launchInitialServerSync]; @@ -1158,6 +1346,7 @@ - (void)resume [self setUserPresence:self.preferredSyncPresence andStatusMessage:nil completion:nil]; [self refreshAPNSPusher]; + [self refreshEmailPusher]; // Tchap: email notifications [self refreshPushKitPusher]; }]; @@ -1170,6 +1359,7 @@ - (void)resume [self launchInitialServerSync]; [self refreshAPNSPusher]; + [self refreshEmailPusher]; // Tchap: email notifications [self refreshPushKitPusher]; break; @@ -1177,6 +1367,7 @@ - (void)resume case MXSessionStateSyncInProgress: { [self refreshAPNSPusher]; + [self refreshEmailPusher]; // Tchap: email notifications [self refreshPushKitPusher]; break; @@ -1338,6 +1529,142 @@ - (void)enableAPNSPusher:(BOOL)enabled success:(void (^)(void))success failure:( }]; } +// Tchap: handle Email notification +// Refresh the Email pusher state for this account on this device. +- (void)refreshEmailPusher +{ + MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher"); + + if (currentEmailPusher) + { + MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher aborted as a pusher has been found"); + return; + } + + // Check the conditions required to run the pusher + if (self.emailNotificationServiceIsActive) + { + MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher: Refresh APNS pusher for %@ account", self.mxCredentials.userId); + + // Create/restore the pusher + [self enableEmailPusher:YES + success:nil + failure:^(NSError *error) { + MXLogDebug(@"[MXKAccount][Email] ;: Error: %@", error); + }]; + } + else if (_hasPusherForEmailNotifications) + { + if (mxSession) + { + // Turn off pusher if user denied remote notification. + MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher: Disable Email pusher for %@ account (notifications are denied)", self.mxCredentials.userId); + [self enableAPNSPusher:NO success:nil failure:nil]; + } + } +} + +// Tchap: handle Email notification +// Enable/Disable the Email pusher for this account on this device on the homeserver. +- (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure:(void (^)(NSError *))failure +{ + MXLogDebug(@"[MXKAccount][Push] enableEmailPusher: %@", @(enabled)); + + NSString *accountUserEmail = self.linkedEmails.firstObject; + + if (accountUserEmail == nil) + { + MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher aborted as user account has no email defined."); + return; + } + + NSData *accountUserEmailAsData = [accountUserEmail dataUsingEncoding:NSUTF8StringEncoding]; + + if (accountUserEmailAsData == nil) + { + MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher aborted as user account email can't be converted to NSData : %@.", accountUserEmail); + return; + } + + NSString *appId = @"m.email"; + + NSDictionary *pushData = @{}; // No data for Email notifications + + [self enablePusher:enabled appId:appId token:accountUserEmailAsData pushData:pushData success:^{ + + MXLogDebug(@"[MXKAccount][Push] enableEmailPusher: Succeeded to update Email pusher for %@ (%d)", self.mxCredentials.userId, enabled); + + self->_hasPusherForEmailNotifications = enabled; + [[MXKAccountManager sharedManager] saveAccounts]; + + if (enabled) + { + [self loadCurrentEmailPusher:^{ + if (success) + { + success(); + } + + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + } failure:^(NSError *error) { + if (success) + { + success(); + } + + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + }]; + } + else + { + self->currentApnsPusher = nil; + + if (success) + { + success(); + } + + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + } + + } failure:^(NSError *error) { + + // Ignore error if the client try to disable an unknown token + if (!enabled) + { + // Check whether the token was unknown + MXError *mxError = [[MXError alloc] initWithNSError:error]; + if (mxError && [mxError.errcode isEqualToString:kMXErrCodeStringUnknown]) + { + MXLogDebug(@"[MXKAccount][Push] enableEmailPusher: Email was already disabled for %@!", self.mxCredentials.userId); + + // Ignore the error + if (success) + { + success(); + } + + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + + return; + } + + MXLogDebug(@"[MXKAccount][Push] enableEmailPusher: Failed to disable Email %@! (%@)", self.mxCredentials.userId, error); + } + else + { + MXLogDebug(@"[MXKAccount][Push] enableEmailPusher: Failed to send Email for %@! (%@)", self.mxCredentials.userId, error); + } + + if (failure) + { + failure(error); + } + + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + }]; +} + // Refresh the PushKit pusher state for this account on this device. - (void)refreshPushKitPusher { @@ -1503,8 +1830,6 @@ - (void)enablePusher:(BOOL)enabled appId:(NSString*)appId token:(NSData*)token p NSString *appDisplayName = [NSString stringWithFormat:@"%@ (iOS)", [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]]; - NSString *b64Token = [token base64EncodedStringWithOptions:0]; - NSString *deviceLang = [NSLocale preferredLanguages][0]; NSString * profileTag = [[NSUserDefaults standardUserDefaults] valueForKey:@"pusherProfileTag"]; @@ -1525,7 +1850,25 @@ - (void)enablePusher:(BOOL)enabled appId:(NSString*)appId token:(NSData*)token p MXLogDebug(@"[MXKAccount][Push] enablePusher: Using existing profile tag: %@", profileTag); } - NSObject *kind = enabled ? @"http" : [NSNull null]; + NSObject *kind = [NSNull null]; + + // PushKey will be Base64 APNStoken if kind is "http". + // It will be user's email id kind is "email". + NSString *pushKey = nil; + + // Tchap[: handle 'http' and 'email' notifications + if( enabled ) { + if( [@"m.email" isEqualToString:appId] ) + { + kind = @"email"; + pushKey = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding]; + } + else + { + kind = @"http"; + pushKey = [token base64EncodedStringWithOptions:0]; + } + } // Use the append flag to handle multiple accounts registration. BOOL append = NO; @@ -1543,7 +1886,7 @@ - (void)enablePusher:(BOOL)enabled appId:(NSString*)appId token:(NSData*)token p MXRestClient *restCli = self.mxRestClient; - [restCli setPusherWithPushkey:b64Token kind:kind appId:appId appDisplayName:appDisplayName deviceDisplayName:[[UIDevice currentDevice] name] profileTag:profileTag lang:deviceLang data:pushData append:append enabled:enabled success:success failure:failure]; + [restCli setPusherWithPushkey:pushKey kind:kind appId:appId appDisplayName:appDisplayName deviceDisplayName:[[UIDevice currentDevice] name] profileTag:profileTag lang:deviceLang data:pushData append:append enabled:enabled success:success failure:failure]; } #pragma mark - InApp notifications diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccountData.h b/Riot/Modules/MatrixKit/Models/Account/MXKAccountData.h index ed49eb55c..026565341 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccountData.h +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccountData.h @@ -32,6 +32,7 @@ @protected BOOL _isSoftLogout; @protected BOOL _hasPusherForPushNotifications; @protected BOOL _hasPusherForPushKitNotifications; +@protected BOOL _hasPusherForEmailNotifications; // Tchap: email notifications @protected MXPresence _preferredSyncPresence; } @@ -79,6 +80,12 @@ */ @property (nonatomic, readonly) BOOL hasPusherForPushNotifications; +// Tchap: email notifications +/** + Flag to indicate that an Email pusher has been set on the homeserver for this device. + */ +@property (nonatomic, readonly) BOOL hasPusherForEmailNotifications; + /** The Push notification activity (based on PushKit) for this account. YES when Push is turned on (locally available and enabled homeserver side). diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccountData.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccountData.m index e878ffb25..a5d57349d 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccountData.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccountData.m @@ -73,6 +73,7 @@ - (id)initWithCoder:(NSCoder *)coder _hasPusherForPushNotifications = [coder decodeBoolForKey:@"_enablePushNotifications"]; _hasPusherForPushKitNotifications = [coder decodeBoolForKey:@"enablePushKitNotifications"]; + _hasPusherForEmailNotifications = [coder decodeBoolForKey:@"enableEmailNotifications"]; // Tchap: email notifications _enableInAppNotifications = [coder decodeBoolForKey:@"enableInAppNotifications"]; _disabled = [coder decodeBoolForKey:@"disabled"]; @@ -146,6 +147,7 @@ - (void)encodeWithCoder:(NSCoder *)coder [coder encodeBool:_hasPusherForPushNotifications forKey:@"_enablePushNotifications"]; [coder encodeBool:_hasPusherForPushKitNotifications forKey:@"enablePushKitNotifications"]; + [coder encodeBool:_hasPusherForEmailNotifications forKey:@"enableEmailNotifications"]; // Tchap: email notifications [coder encodeBool:_enableInAppNotifications forKey:@"enableInAppNotifications"]; [coder encodeBool:_disabled forKey:@"disabled"]; diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 0c3a29b83..d74b66768 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -1419,6 +1419,7 @@ - (void)refreshSettings [self refreshSystemNotificationSettings]; [[MXKAccountManager sharedManager].activeAccounts.firstObject loadCurrentApnsPusher:nil failure:nil]; + [[MXKAccountManager sharedManager].activeAccounts.firstObject loadCurrentEmailPusher:nil failure:nil]; // Tchap: email notifications } - (void)refreshSystemNotificationSettings @@ -3403,9 +3404,22 @@ - (void)togglePushNotifications:(UISwitch *)sender } } +// Tchap: email notifications - (void)toggleNotificationsByEmail:(UISwitch *)sender { - NSLog(@"toggleNotificationsByEmail"); + if ([MXKAccountManager sharedManager].activeAccounts.count) + { + [self startActivityIndicator]; + + MXKAccountManager *accountManager = [MXKAccountManager sharedManager]; + MXKAccount* account = accountManager.activeAccounts.firstObject; + + [account enableEmailNotifications:sender.isOn success:^{ + [self stopActivityIndicator]; + } failure:^(NSError *error) { + [self stopActivityIndicator]; + }]; + } } - (void)toggleShowInAppNotifications:(UISwitch *)sender diff --git a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Service/MatrixSDK/UserSessionOverviewService.swift b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Service/MatrixSDK/UserSessionOverviewService.swift index 103a9b6a8..ff4edbc1f 100644 --- a/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Service/MatrixSDK/UserSessionOverviewService.swift +++ b/RiotSwiftUI/Modules/UserSessions/UserSessionOverview/Service/MatrixSDK/UserSessionOverviewService.swift @@ -100,7 +100,7 @@ class UserSessionOverviewService: UserSessionOverviewServiceProtocol { switch response { case .success: if let account = MXKAccountManager.shared().activeAccounts.first, account.device?.deviceId == pusher.deviceId { - account.loadCurrentPusher(nil) + account.loadCurrentApnsPusher(nil) // Tchap adaptation on call name } self.loadPushers { [weak self] pushers in From caafddf1c43e86db3be38f1069e51a9d3851b938 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 9 Oct 2023 16:40:00 +0200 Subject: [PATCH 04/10] Allow disabling Email Notification from Settings --- .../MatrixKit/Models/Account/MXKAccount.h | 7 +++++- .../MatrixKit/Models/Account/MXKAccount.m | 24 +++++++++++++++---- .../Modules/Settings/SettingsViewController.m | 13 +++------- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h index 97c11f5dd..684193c74 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h @@ -307,7 +307,7 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer - (void)load3PIDs:(void (^)(void))success failure:(void (^)(NSError *error))failure; /** - Loads theAPNS pusher instance linked to this account. + Loads the APNS pusher instance linked to this account. This method must be called to refresh self.pushNotificationServiceIsActive @param success A block object called when the operation succeeds. @@ -330,6 +330,11 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer failure:(void (^)(NSError *))failure; // Tchap: email notifications +/** + The Email Notification Service activity for this account. YES when Email notification service is turned on (locally available and synced with server). + */ +@property (nonatomic, readonly) BOOL emailNotificationServiceIsActive; + /** Loads the Email pusher instance linked to this account. This method must be called to refresh self.emailNotificationServiceIsActive diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 8b5f800d2..4bbe608a3 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -1559,7 +1559,13 @@ - (void)refreshEmailPusher { // Turn off pusher if user denied remote notification. MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher: Disable Email pusher for %@ account (notifications are denied)", self.mxCredentials.userId); - [self enableAPNSPusher:NO success:nil failure:nil]; + [self enableEmailPusher:NO success:nil failure:nil]; + } + else + { + MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher: Reset locally Email pusher for %@ account becasue no Session is active. Reset _hasPusherForEmailNotifications", self.mxCredentials.userId); + _hasPusherForEmailNotifications = NO; + [[MXKAccountManager sharedManager] saveAccounts]; } } } @@ -1617,7 +1623,7 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: } else { - self->currentApnsPusher = nil; + self->currentEmailPusher = nil; if (success) { @@ -1854,19 +1860,27 @@ - (void)enablePusher:(BOOL)enabled appId:(NSString*)appId token:(NSData*)token p // PushKey will be Base64 APNStoken if kind is "http". // It will be user's email id kind is "email". + // It is always required. NSString *pushKey = nil; - // Tchap[: handle 'http' and 'email' notifications + if( [@"m.email" isEqualToString:appId] ) + { + pushKey = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding]; + } + else + { + pushKey = [token base64EncodedStringWithOptions:0]; + } + + // Tchap: handle 'http' and 'email' notifications if( enabled ) { if( [@"m.email" isEqualToString:appId] ) { kind = @"email"; - pushKey = [[NSString alloc] initWithData:token encoding:NSUTF8StringEncoding]; } else { kind = @"http"; - pushKey = [token base64EncodedStringWithOptions:0]; } } diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index d74b66768..ccc1c84c2 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -2195,10 +2195,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N labelAndSwitchCell.mxkSwitch.enabled = account.pushNotificationServiceIsActive; [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleShowDecodedContent:) forControlEvents:UIControlEventTouchUpInside]; - cell = labelAndSwitchCell; } - else if (row == NOTIFICATION_SETTINGS_ENABLE_BY_EMAIL_INDEX) + else if (row == NOTIFICATION_SETTINGS_ENABLE_BY_EMAIL_INDEX) // Tchap: email notifications { MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; @@ -2207,15 +2206,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N labelAndSwitchCell.mxkSwitch.enabled = YES; [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleNotificationsByEmail:) forControlEvents:UIControlEventTouchUpInside]; -// BOOL isPushEnabled = account.pushNotificationServiceIsActive; -// -// // Even if push is enabled for the account, the user may have turned off notifications in system settings -// if (isPushEnabled && self.systemNotificationSettings) -// { -// isPushEnabled = self.systemNotificationSettings.authorizationStatus == UNAuthorizationStatusAuthorized; -// } + BOOL isPushEnabled = account.emailNotificationServiceIsActive; - labelAndSwitchCell.mxkSwitch.on = !labelAndSwitchCell.mxkSwitch.on; + labelAndSwitchCell.mxkSwitch.on = isPushEnabled; cell = labelAndSwitchCell; } From 1349b8a3b1b1b05f77ee45071afd8841299f7227 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Mon, 9 Oct 2023 19:37:28 +0200 Subject: [PATCH 05/10] Set internal notification when Email push notification state change --- .../MatrixKit/Models/Account/MXKAccount.h | 7 +++++ .../MatrixKit/Models/Account/MXKAccount.m | 11 ++++--- .../Modules/Settings/SettingsViewController.m | 31 ++++++++++++++++++- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h index 684193c74..3d671fdad 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.h @@ -33,6 +33,13 @@ extern NSString *const kMXKAccountUserInfoDidChangeNotification; */ extern NSString *const kMXKAccountAPNSActivityDidChangeNotification; +// Tchap: email notifications +/** + Posted when the activity of the Email Notification Service has been changed. + The notification object is the matrix user id of the account. + */ +extern NSString *const kMXKAccountEmailActivityDidChangeNotification; + /** Posted when the activity of the Push notification based on PushKit has been changed. The notification object is the matrix user id of the account. diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 4bbe608a3..1f9cd150d 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -40,6 +40,7 @@ NSString *const kMXKAccountUserInfoDidChangeNotification = @"kMXKAccountUserInfoDidChangeNotification"; NSString *const kMXKAccountAPNSActivityDidChangeNotification = @"kMXKAccountAPNSActivityDidChangeNotification"; +NSString *const kMXKAccountEmailActivityDidChangeNotification = @"kMXKAccountEmailActivityDidChangeNotification"; // Tchap: email notifications NSString *const kMXKAccountPushKitActivityDidChangeNotification = @"kMXKAccountPushKitActivityDidChangeNotification"; NSString *const kMXKAccountErrorDomain = @"kMXKAccountErrorDomain"; @@ -1611,14 +1612,14 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: success(); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; } failure:^(NSError *error) { if (success) { success(); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; }]; } else @@ -1630,7 +1631,7 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: success(); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; } } failure:^(NSError *error) { @@ -1650,7 +1651,7 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: success(); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; return; } @@ -1667,7 +1668,7 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: failure(error); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; }]; } diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index ccc1c84c2..1e56e4325 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -231,7 +231,8 @@ @interface SettingsViewController () *tmpSections = [NSMutableArray arrayWithCapacity:SECTION_TAG_DEACTIVATE_ACCOUNT + 1]; @@ -762,6 +778,17 @@ - (void)viewDidLoad }]; + // Tchap: Email notification. Add observer to push settings + emailInfoUpdateObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXKAccountEmailActivityDidChangeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { + + MXStrongifyAndReturnIfNil(self); + + [self stopActivityIndicator]; + + [self refreshSettings]; + + }]; + [self registerAccountDataDidChangeIdentityServerNotification]; // Add each matrix session, to update the view controller appearance according to mx sessions state @@ -942,6 +969,8 @@ - (void)viewWillDisappear:(BOOL)animated [[NSNotificationCenter defaultCenter] removeObserver:kAppDelegateDidTapStatusBarNotificationObserver]; kAppDelegateDidTapStatusBarNotificationObserver = nil; } + + } #pragma mark - Internal methods From 1309b4051b7346b6cff065d54bc0f14e6b2dc3c5 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 10 Oct 2023 17:02:03 +0200 Subject: [PATCH 06/10] Synchronize local state with back-end state at loading --- .../MatrixKit/Models/Account/MXKAccount.m | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 1f9cd150d..2d5ede9e8 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -851,45 +851,33 @@ - (void)loadCurrentApnsPusher:(void (^)(void))success failure:(void (^)(NSError // Tchap: email notifications - (void)loadCurrentEmailPusher:(void (^)(void))success failure:(void (^)(NSError *error))failure { - // DeviceId not needed nor present for Email pusher -// if (!self.mxSession.myDeviceId) -// { -// MXLogWarning(@"[MXKAccount] loadEmailPusher: device ID not found"); -// if (failure) -// { -// failure([NSError errorWithDomain:kMXKAccountErrorDomain code:0 userInfo:nil]); -// } -// return; -// } - [self.mxSession supportedMatrixVersions:^(MXMatrixVersions *matrixVersions) { - // Tchpa: TODO check for supportsRemotelyTogglingEmailNotifications -// if (!matrixVersions.supportsRemotelyTogglingPushNotifications) -// { -// MXLogDebug(@"[MXKAccount] loadEmailPusher: remotely toggling push notifications not supported"); -// -// if (success) -// { -// success(); -// } -// -// return; -// } [self.mxSession.matrixRestClient pushers:^(NSArray *pushers) { MXPusher *emailPusher; for (MXPusher *pusher in pushers) { -// if ([pusher.deviceId isEqualToString:self.mxSession.myDeviceId]) { - if ([pusher.kind isEqualToString:@"email"]) - { - emailPusher = pusher; - } -// } + if ([pusher.kind isEqualToString:@"email"]) + { + emailPusher = pusher; + } } + // On application launch, if email notification is activated on the back-end + // emailPusher is not nil here. self->currentEmailPusher = emailPusher; + if (self->currentEmailPusher == nil) + { + self->_hasPusherForEmailNotifications = NO; + [[MXKAccountManager sharedManager] saveAccounts]; + } + else + { + self->_hasPusherForEmailNotifications = YES; + [[MXKAccountManager sharedManager] saveAccounts]; + } + if (success) { success(); @@ -1531,7 +1519,7 @@ - (void)enableAPNSPusher:(BOOL)enabled success:(void (^)(void))success failure:( } // Tchap: handle Email notification -// Refresh the Email pusher state for this account on this device. +// Refresh the Email pusher state for this account. - (void)refreshEmailPusher { MXLogDebug(@"[MXKAccount][Email] refreshEmailPusher"); From 15c7a2b47e212c822dd86b612bce62ca18e68dbf Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Tue, 10 Oct 2023 17:11:34 +0200 Subject: [PATCH 07/10] Add changelog --- changelog.d/882.feature | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog.d/882.feature diff --git a/changelog.d/882.feature b/changelog.d/882.feature new file mode 100644 index 000000000..8888a1ae9 --- /dev/null +++ b/changelog.d/882.feature @@ -0,0 +1,2 @@ +Activer/désactiver les notifications par email + From b2b2be53479f658c58a1979b4ba911fd682e6586 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 11 Oct 2023 13:58:23 +0200 Subject: [PATCH 08/10] Add Tchap comments --- Riot/Modules/MatrixKit/Models/Account/MXKAccount.m | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 2d5ede9e8..b67c5b78b 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -857,13 +857,13 @@ - (void)loadCurrentEmailPusher:(void (^)(void))success failure:(void (^)(NSError MXPusher *emailPusher; for (MXPusher *pusher in pushers) { - if ([pusher.kind isEqualToString:@"email"]) + if ([pusher.kind isEqualToString:@"email"]) // Tchap: email notification { emailPusher = pusher; } } - // On application launch, if email notification is activated on the back-end + // Tchap: on application launch, if email notification is activated on the back-end // emailPusher is not nil here. self->currentEmailPusher = emailPusher; @@ -1600,14 +1600,14 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: success(); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; // Tchap: email notifications } failure:^(NSError *error) { if (success) { success(); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; // Tchap: email notifications }]; } else @@ -1619,7 +1619,7 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: success(); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; // Tchap: email notifications } } failure:^(NSError *error) { @@ -1639,7 +1639,7 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: success(); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; // Tchap: email notifications return; } @@ -1656,7 +1656,7 @@ - (void)enableEmailPusher:(BOOL)enabled success:(void (^)(void))success failure: failure(error); } - [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; + [[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountEmailActivityDidChangeNotification object:self.mxCredentials.userId]; // Tchap: email notifications }]; } From 823897a5042dc79d548865adf405be947da8f14b Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Wed, 11 Oct 2023 13:58:51 +0200 Subject: [PATCH 09/10] Correct cleaning (dealloc) of controller and observers --- .../Modules/Settings/SettingsViewController.m | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 1e56e4325..f09037aa9 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -378,19 +378,9 @@ - (void)finalizeInit self.screenTracker = [[AnalyticsScreenTracker alloc] initWithScreen:AnalyticsScreenSettings]; } +// Tchap: fix for destroy not being called (https://github.com/vector-im/element-ios/pull/7697) - (void)dealloc { - // Remove observers - if (pushInfoUpdateObserver) - { - [[NSNotificationCenter defaultCenter] removeObserver:pushInfoUpdateObserver name:kMXKAccountAPNSActivityDidChangeNotification object:nil]; - pushInfoUpdateObserver = nil; - } - - if (emailInfoUpdateObserver) - { - [[NSNotificationCenter defaultCenter] removeObserver:emailInfoUpdateObserver name:kMXKAccountEmailActivityDidChangeNotification object:nil]; - emailInfoUpdateObserver = nil; - } + [self destroy]; } - (void)updateSections @@ -1033,6 +1023,13 @@ - (void)reset pushInfoUpdateObserver = nil; } + // Tchap: remove Email notification update observer + if (emailInfoUpdateObserver) + { + [[NSNotificationCenter defaultCenter] removeObserver:emailInfoUpdateObserver name:kMXKAccountEmailActivityDidChangeNotification object:nil]; + emailInfoUpdateObserver = nil; + } + [[NSNotificationCenter defaultCenter] removeObserver:self]; onReadyToDestroyHandler = nil; From 01c8c86d57b9b3148c92393e70a99e8a503dd9a4 Mon Sep 17 00:00:00 2001 From: Nicolas Buquet Date: Thu, 12 Oct 2023 16:26:34 +0200 Subject: [PATCH 10/10] Deploy email notifications setting only to DINUM clients --- Riot/Modules/Settings/SettingsViewController.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index f09037aa9..e1e7b0fe9 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -490,7 +490,10 @@ - (void)updateSections [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_SHOW_DECODED_CONTENT]; } - [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_ENABLE_BY_EMAIL_INDEX]; + // Tchap: allow enabling email notifications only for DINUM homeserver + if ([account.identityServerURL isEqualToString:[BuildSettings.serverUrlPrefix stringByAppendingString:@"agent.dinum.tchap.gouv.fr"]]) { + [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_ENABLE_BY_EMAIL_INDEX]; + } [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_PIN_MISSED_NOTIFICATIONS_INDEX]; [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_PIN_UNREAD_INDEX];