Skip to content

Commit

Permalink
Add support for in-app notifications. (#6341)
Browse files Browse the repository at this point in the history
  • Loading branch information
pixlwave authored Jul 7, 2022
1 parent 45abf4d commit 00d781a
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 136 deletions.
2 changes: 1 addition & 1 deletion Riot/Assets/en.lproj/Vector.strings
Original file line number Diff line number Diff line change
Expand Up @@ -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 %@:";

Expand Down
2 changes: 1 addition & 1 deletion Riot/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
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);
}
}
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
{
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.

0 comments on commit 00d781a

Please sign in to comment.