Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for in-app notifications. #6341

Merged
merged 2 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -2339,7 +2339,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 %@:";

Expand Down
2 changes: 1 addition & 1 deletion Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6719,7 +6719,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")
}
Expand Down
4 changes: 2 additions & 2 deletions Riot/Managers/PushNotification/PushNotificationService.m
Original file line number Diff line number Diff line change
Expand Up @@ -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"]])
Expand All @@ -347,7 +347,7 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNot
{
completionHandler(UNNotificationPresentationOptionBadge
| UNNotificationPresentationOptionSound
| UNNotificationPresentationOptionAlert);
| UNNotificationPresentationOptionBanner);
Copy link
Member Author

@pixlwave pixlwave Jun 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Alert option was deprecated in iOS 14. I'm not sure what this means for the Constants.userInfoKeyPresentNotificationOnForeground check: one change could be to include it in notification centre too if that is set, but that didn't seem worthwhile to me.

}
}
else
Expand Down
4 changes: 4 additions & 0 deletions Riot/Managers/Settings/RiotSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
132 changes: 0 additions & 132 deletions Riot/Modules/Application/LegacyAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ @interface LegacyAppDelegate () <GDPRConsentViewControllerDelegate, KeyVerificat
UIView *launchAnimationContainerView;
}

@property (strong, nonatomic) UIAlertController *mxInAppNotification;

@property (strong, nonatomic) UIAlertController *logoutConfirmation;

@property (weak, nonatomic) UIAlertController *gdprConsentNotGivenAlertController;
Expand Down Expand Up @@ -587,13 +585,6 @@ - (void)applicationDidEnterBackground:(UIApplication *)application
// Remove expired URL previews from the cache
[URLPreviewService.shared removeExpiredCacheData];

// Hide potential notification
if (self.mxInAppNotification)
{
[self.mxInAppNotification dismissViewControllerAnimated:NO completion:nil];
self.mxInAppNotification = nil;
}

// Discard any process on pending universal link
[self resetPendingUniversalLink];

Expand Down Expand Up @@ -1820,18 +1811,6 @@ - (void)initMatrixSessions
// start the call service
[self.callPresenter start];

// Look for the account related to this session.
NSArray *mxAccounts = [MXKAccountManager sharedManager].activeAccounts;
for (MXKAccount *account in mxAccounts)
{
if (account.mxSession == mxSession)
{
// Enable inApp notifications (if they are allowed for this account).
[self enableInAppNotificationsForAccount:account];
break;
}
}

[self.configuration setupSettingsWhenLoadedFor:mxSession];

// Register to user new device sign in notification
Expand Down Expand Up @@ -1888,9 +1867,6 @@ - (void)initMatrixSessions
// Set up push notifications
[self.pushNotificationService registerUserNotificationSettings];
}

// Observe inApp notifications toggle change
[account addObserver:self forKeyPath:@"enableInAppNotifications" options:0 context:nil];
}

[self.delegate legacyAppDelegate:self didAddAccount:account];
Expand All @@ -1901,10 +1877,6 @@ - (void)initMatrixSessions

// Remove inApp notifications toggle change
MXKAccount *account = notif.object;
if (!account.isSoftLogout)
{
[account removeObserver:self forKeyPath:@"enableInAppNotifications"];
}

// Clear Modular data
[[WidgetManager sharedManager] deleteDataForUser:account.mxCredentials.userId];
Expand Down Expand Up @@ -1984,12 +1956,6 @@ - (void)initMatrixSessions

// Set up push notifications
[self.pushNotificationService registerUserNotificationSettings];

// Observe inApp notifications toggle change for each account
for (MXKAccount *account in mxAccounts)
{
[account addObserver:self forKeyPath:@"enableInAppNotifications" options:0 context:nil];
}
}
}

Expand Down Expand Up @@ -2256,10 +2222,6 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
// Flush and restore Matrix data
[self reloadMatrixSessions:NO];
}
else if ([@"enableInAppNotifications" isEqualToString:keyPath] && [object isKindOfClass:[MXKAccount class]])
{
[self enableInAppNotificationsForAccount:(MXKAccount*)object];
}
else if (object == [MXKAppSettings standardAppSettings] && [keyPath isEqualToString:@"enableCallKit"])
{
BOOL isCallKitEnabled = [MXKAppSettings standardAppSettings].isCallKitEnabled;
Expand Down Expand Up @@ -2656,100 +2618,6 @@ - (UIViewController*)presentedViewController

#pragma mark - Matrix Accounts handling

- (void)enableInAppNotificationsForAccount:(MXKAccount*)account
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice chunk of code gone 🎉

{
if (account.mxSession)
{
if (account.enableInAppNotifications)
{
// Build MXEvent -> 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;
Expand Down
19 changes: 19 additions & 0 deletions Riot/Modules/Settings/SettingsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -3165,6 +3179,11 @@ - (void)togglePushNotifications:(UISwitch *)sender
}
}

- (void)toggleShowInAppNotifications:(UISwitch *)sender
{
RiotSettings.shared.showInAppNotifications = sender.isOn;
}

- (void)openSystemSettingsApp
{
NSURL *settingsAppURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
Expand Down
1 change: 1 addition & 0 deletions changelog.d/1108.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Notifications: Add a setting for in-app notifications and use the value with existing functionality in PushNotificationService.