From 00d781ac22801fd2eedf78014f452639811e45d8 Mon Sep 17 00:00:00 2001 From: Doug <6060466+pixlwave@users.noreply.github.com> Date: Thu, 7 Jul 2022 15:31:37 +0100 Subject: [PATCH] Add support for in-app notifications. (#6341) --- Riot/Assets/en.lproj/Vector.strings | 2 +- Riot/Generated/Strings.swift | 2 +- .../PushNotificationService.m | 4 +- Riot/Managers/Settings/RiotSettings.swift | 4 + Riot/Modules/Application/LegacyAppDelegate.m | 132 ------------------ .../Modules/Settings/SettingsViewController.m | 19 +++ changelog.d/1108.feature | 1 + 7 files changed, 28 insertions(+), 136 deletions(-) create mode 100644 changelog.d/1108.feature diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 871d73183d..34604b8fa6 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -2346,7 +2346,7 @@ To enable access, tap Settings> Location and select Always"; // Settings "settings" = "Settings"; -"settings_enable_inapp_notifications" = "Enable In-App notifications"; +"settings_enable_inapp_notifications" = "Enable in-app notifications"; "settings_enable_push_notifications" = "Enable push notifications"; "settings_enter_validation_token_for" = "Enter validation token for %@:"; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index 20c3bbab85..04a3645979 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -6743,7 +6743,7 @@ public class VectorL10n: NSObject { public static var settingsEnableCallkit: String { return VectorL10n.tr("Vector", "settings_enable_callkit") } - /// Enable In-App notifications + /// Enable in-app notifications public static var settingsEnableInappNotifications: String { return VectorL10n.tr("Vector", "settings_enable_inapp_notifications") } diff --git a/Riot/Managers/PushNotification/PushNotificationService.m b/Riot/Managers/PushNotification/PushNotificationService.m index 27b07292a1..58b9aaaf90 100644 --- a/Riot/Managers/PushNotification/PushNotificationService.m +++ b/Riot/Managers/PushNotification/PushNotificationService.m @@ -335,7 +335,7 @@ - (void)launchBackgroundSync - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { NSDictionary *userInfo = notification.request.content.userInfo; - if (userInfo[Constants.userInfoKeyPresentNotificationOnForeground]) + if (RiotSettings.shared.showInAppNotifications || userInfo[Constants.userInfoKeyPresentNotificationOnForeground]) { if (!userInfo[Constants.userInfoKeyPresentNotificationInRoom] && [[AppDelegate theDelegate].visibleRoomId isEqualToString:userInfo[@"room_id"]]) @@ -347,7 +347,7 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNot { completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound - | UNNotificationPresentationOptionAlert); + | UNNotificationPresentationOptionBanner); } } else diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift index f2dfc96ccd..548fad9c7f 100644 --- a/Riot/Managers/Settings/RiotSettings.swift +++ b/Riot/Managers/Settings/RiotSettings.swift @@ -80,6 +80,10 @@ final class RiotSettings: NSObject { return RiotSettings.defaults.object(forKey: UserDefaultsKeys.notificationsShowDecryptedContent) != nil } + /// Indicate if notifications should be shown whilst the app is in the foreground. + @UserDefault(key: "showInAppNotifications", defaultValue: true, storage: defaults) + var showInAppNotifications + /// Indicate if encrypted messages content should be displayed in notifications. @UserDefault(key: UserDefaultsKeys.notificationsShowDecryptedContent, defaultValue: false, storage: defaults) var showDecryptedContentInNotifications diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index 316f80c18f..06dfac203d 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -195,8 +195,6 @@ @interface LegacyAppDelegate () NSString formatter - EventFormatter *eventFormatter = [[EventFormatter alloc] initWithMatrixSession:account.mxSession]; - eventFormatter.isForSubtitle = YES; - - [account listenToNotifications:^(MXEvent *event, MXRoomState *roomState, MXPushRule *rule) { - - // Check conditions to display this notification - if (![self.visibleRoomId isEqualToString:event.roomId] - && !self.window.rootViewController.presentedViewController) - { - MXKEventFormatterError error; - NSString* messageText = [eventFormatter stringFromEvent:event - withRoomState:roomState - andLatestRoomState:nil - error:&error]; - if (messageText.length && (error == MXKEventFormatterErrorNone)) - { - // Removing existing notification (if any) - if (self.mxInAppNotification) - { - [self.mxInAppNotification dismissViewControllerAnimated:NO completion:nil]; - } - - // Check whether tweak is required - for (MXPushRuleAction *ruleAction in rule.actions) - { - if (ruleAction.actionType == MXPushRuleActionTypeSetTweak) - { - if ([[ruleAction.parameters valueForKey:@"set_tweak"] isEqualToString:@"sound"]) - { - // Play message sound - AudioServicesPlaySystemSound(self->_messageSound); - } - } - } - - MXRoomSummary *roomSummary = [account.mxSession roomSummaryWithRoomId:event.roomId]; - - __weak typeof(self) weakSelf = self; - self.mxInAppNotification = [UIAlertController alertControllerWithTitle:roomSummary.displayname - message:messageText - preferredStyle:UIAlertControllerStyleAlert]; - - [self.mxInAppNotification addAction:[UIAlertAction actionWithTitle:[VectorL10n cancel] - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * action) { - - if (weakSelf) - { - typeof(self) self = weakSelf; - self.mxInAppNotification = nil; - [account updateNotificationListenerForRoomId:event.roomId ignore:YES]; - } - - }]]; - - [self.mxInAppNotification addAction:[UIAlertAction actionWithTitle:[VectorL10n view] - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * action) { - - if (weakSelf) - { - typeof(self) self = weakSelf; - self.mxInAppNotification = nil; - // Show the room - [self showRoom:event.roomId andEventId:nil withMatrixSession:account.mxSession]; - } - - }]]; - - [self.window.rootViewController presentViewController:self.mxInAppNotification animated:YES completion:nil]; - } - } - }]; - } - else - { - [account removeNotificationListener]; - } - } - - if (self.mxInAppNotification) - { - [self.mxInAppNotification dismissViewControllerAnimated:NO completion:nil]; - self.mxInAppNotification = nil; - } -} - - (void)selectMatrixAccount:(void (^)(MXKAccount *selectedAccount))onSelection { NSArray *mxAccounts = [MXKAccountManager sharedManager].activeAccounts; diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index f8e3837736..b0d5ffc153 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -103,6 +103,7 @@ typedef NS_ENUM(NSUInteger, NOTIFICATION_SETTINGS) { NOTIFICATION_SETTINGS_ENABLE_PUSH_INDEX = 0, NOTIFICATION_SETTINGS_SYSTEM_SETTINGS, + NOTIFICATION_SETTINGS_SHOW_IN_APP_INDEX, NOTIFICATION_SETTINGS_SHOW_DECODED_CONTENT, NOTIFICATION_SETTINGS_PIN_MISSED_NOTIFICATIONS_INDEX, NOTIFICATION_SETTINGS_PIN_UNREAD_INDEX, @@ -410,6 +411,7 @@ - (void)updateSections Section *sectionNotificationSettings = [Section sectionWithTag:SECTION_TAG_NOTIFICATIONS]; [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_ENABLE_PUSH_INDEX]; [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_SYSTEM_SETTINGS]; + [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_SHOW_IN_APP_INDEX]; if (RiotSettings.shared.settingsScreenShowNotificationDecodedContentOption) { [sectionNotificationSettings addRowWithTag:NOTIFICATION_SETTINGS_SHOW_DECODED_CONTENT]; @@ -2076,6 +2078,18 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N [cell vc_setAccessoryDisclosureIndicatorWithCurrentTheme]; cell.selectionStyle = UITableViewCellSelectionStyleDefault; } + else if (row == NOTIFICATION_SETTINGS_SHOW_IN_APP_INDEX) + { + MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; + + labelAndSwitchCell.mxkLabel.text = VectorL10n.settingsEnableInappNotifications; + labelAndSwitchCell.mxkSwitch.on = RiotSettings.shared.showInAppNotifications; + labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor; + labelAndSwitchCell.mxkSwitch.enabled = account.pushNotificationServiceIsActive; + [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleShowInAppNotifications:) forControlEvents:UIControlEventTouchUpInside]; + + cell = labelAndSwitchCell; + } else if (row == NOTIFICATION_SETTINGS_SHOW_DECODED_CONTENT) { MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; @@ -3165,6 +3179,11 @@ - (void)togglePushNotifications:(UISwitch *)sender } } +- (void)toggleShowInAppNotifications:(UISwitch *)sender +{ + RiotSettings.shared.showInAppNotifications = sender.isOn; +} + - (void)openSystemSettingsApp { NSURL *settingsAppURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; diff --git a/changelog.d/1108.feature b/changelog.d/1108.feature new file mode 100644 index 0000000000..e33cae1a0e --- /dev/null +++ b/changelog.d/1108.feature @@ -0,0 +1 @@ +Notifications: Add a setting for in-app notifications and use the value with existing functionality in PushNotificationService.