MM-25931 Handle incoming session expired push notification (#4417)
This commit is contained in:
parent
c9dae37414
commit
b316ad5a20
7 changed files with 57 additions and 43 deletions
|
|
@ -50,6 +50,7 @@ public class CustomPushNotification extends PushNotification {
|
|||
|
||||
private static final String PUSH_TYPE_MESSAGE = "message";
|
||||
private static final String PUSH_TYPE_CLEAR = "clear";
|
||||
private static final String PUSH_TYPE_SESSION = "session";
|
||||
private static final String PUSH_TYPE_UPDATE_BADGE = "update_badge";
|
||||
|
||||
private NotificationChannel mHighImportanceChannel;
|
||||
|
|
@ -163,6 +164,7 @@ public class CustomPushNotification extends PushNotification {
|
|||
|
||||
switch(type) {
|
||||
case PUSH_TYPE_MESSAGE:
|
||||
case PUSH_TYPE_SESSION:
|
||||
super.postNotification(notificationId);
|
||||
break;
|
||||
case PUSH_TYPE_CLEAR:
|
||||
|
|
@ -177,8 +179,10 @@ public class CustomPushNotification extends PushNotification {
|
|||
public void onOpened() {
|
||||
Bundle data = mNotificationProps.asBundle();
|
||||
final String channelId = data.getString("channel_id");
|
||||
channelIdToNotificationCount.remove(channelId);
|
||||
channelIdToNotification.remove(channelId);
|
||||
if (channelId != null) {
|
||||
channelIdToNotificationCount.remove(channelId);
|
||||
channelIdToNotification.remove(channelId);
|
||||
}
|
||||
digestNotification();
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +226,9 @@ public class CustomPushNotification extends PushNotification {
|
|||
}
|
||||
|
||||
String channelId = bundle.getString("channel_id");
|
||||
userInfoBundle.putString("channel_id", channelId);
|
||||
if (channelId != null) {
|
||||
userInfoBundle.putString("channel_id", channelId);
|
||||
}
|
||||
|
||||
notification.addExtras(userInfoBundle);
|
||||
}
|
||||
|
|
@ -459,7 +465,8 @@ public class CustomPushNotification extends PushNotification {
|
|||
|
||||
private void addNotificationReplyAction(Notification.Builder notification, int notificationId, Bundle bundle) {
|
||||
String postId = bundle.getString("post_id");
|
||||
if (postId == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
|
||||
if (android.text.TextUtils.isEmpty(postId) || Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@
|
|||
import {Platform} from 'react-native';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
|
||||
import {setDeviceToken} from '@mm-redux/actions/general';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
|
||||
import {markChannelViewedAndRead, fetchPostActionWithRetry} from '@actions/views/channel';
|
||||
import {dismissAllModals, popToRoot} from '@actions/navigation';
|
||||
import {getPosts} from '@actions/views/post';
|
||||
|
|
@ -16,18 +11,28 @@ import {
|
|||
createPostForNotificationReply,
|
||||
loadFromPushNotification,
|
||||
} from '@actions/views/root';
|
||||
|
||||
import {logout} from '@actions/views/user';
|
||||
import {NavigationTypes, ViewTypes} from '@constants';
|
||||
import {getLocalizedMessage} from '@i18n';
|
||||
import {getCurrentServerUrl, getAppCredentials} from '@init/credentials';
|
||||
import {setDeviceToken} from '@mm-redux/actions/general';
|
||||
import {Client4} from '@mm-redux/client';
|
||||
import {General} from '@mm-redux/constants';
|
||||
import EventEmitter from '@mm-redux/utils/event_emitter';
|
||||
import {getCurrentLocale} from '@selectors/i18n';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import Store from '@store/store';
|
||||
import {waitForHydration} from '@store/utils';
|
||||
import {t} from '@utils/i18n';
|
||||
|
||||
import {getCurrentServerUrl, getAppCredentials} from 'app/init/credentials';
|
||||
import PushNotifications from 'app/push_notifications';
|
||||
|
||||
const NOTIFICATION_TYPE = {
|
||||
CLEAR: 'clear',
|
||||
MESSAGE: 'message',
|
||||
SESSION: 'session',
|
||||
};
|
||||
|
||||
class PushNotificationUtils {
|
||||
constructor() {
|
||||
this.configured = false;
|
||||
|
|
@ -70,20 +75,28 @@ class PushNotificationUtils {
|
|||
message,
|
||||
};
|
||||
|
||||
if (data.type === 'clear') {
|
||||
dispatch(markChannelViewedAndRead(data.channel_id, null, false));
|
||||
} else if (data.type === 'message') {
|
||||
// get the posts for the channel as soon as possible
|
||||
dispatch(fetchPostActionWithRetry(getPosts(data.channel_id)));
|
||||
waitForHydration(Store.redux, () => {
|
||||
switch (data.type) {
|
||||
case NOTIFICATION_TYPE.CLEAR:
|
||||
dispatch(markChannelViewedAndRead(data.channel_id, null, false));
|
||||
break;
|
||||
case NOTIFICATION_TYPE.MESSAGE:
|
||||
// get the posts for the channel as soon as possible
|
||||
dispatch(fetchPostActionWithRetry(getPosts(data.channel_id)));
|
||||
|
||||
if (foreground) {
|
||||
EventEmitter.emit(ViewTypes.NOTIFICATION_IN_APP, notification);
|
||||
} else if (userInteraction && !notification?.data?.localNotification) {
|
||||
waitForHydration(Store.redux, () => {
|
||||
if (foreground) {
|
||||
EventEmitter.emit(ViewTypes.NOTIFICATION_IN_APP, notification);
|
||||
} else if (userInteraction && !notification?.data?.localNotification) {
|
||||
this.loadFromNotification(notification);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case NOTIFICATION_TYPE.SESSION:
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Session expired notification');
|
||||
dispatch(logout());
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onPushNotificationReply = async (data, text, completion) => {
|
||||
|
|
@ -174,4 +187,4 @@ class PushNotificationUtils {
|
|||
};
|
||||
}
|
||||
|
||||
export default new PushNotificationUtils();
|
||||
export default new PushNotificationUtils();
|
||||
|
|
@ -17,6 +17,7 @@ import emmProvider from '@init/emm_provider';
|
|||
import '@init/device';
|
||||
import '@init/fetch';
|
||||
import globalEventHandler from '@init/global_event_handler';
|
||||
import pushNotifications from '@init/push_notifications';
|
||||
import {registerScreens} from '@screens';
|
||||
import configureStore from '@store';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
|
|
@ -24,7 +25,6 @@ import getStorage from '@store/mmkv_adapter';
|
|||
import Store from '@store/store';
|
||||
import {waitForHydration} from '@store/utils';
|
||||
import {validatePreviousVersion} from '@utils/general';
|
||||
import pushNotificationsUtils from '@utils/push_notifications';
|
||||
import {captureJSException} from '@utils/sentry';
|
||||
|
||||
const init = async () => {
|
||||
|
|
@ -37,7 +37,7 @@ const init = async () => {
|
|||
return;
|
||||
}
|
||||
|
||||
pushNotificationsUtils.configure();
|
||||
pushNotifications.configure();
|
||||
globalEventHandler.configure({
|
||||
launchApp,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -71,24 +71,18 @@ NSString* const NOTIFICATION_UPDATE_BADGE_ACTION = @"update_badge";
|
|||
NSString* action = [userInfo objectForKey:@"type"];
|
||||
NSString* channelId = [userInfo objectForKey:@"channel_id"];
|
||||
NSString* ackId = [userInfo objectForKey:@"ack_id"];
|
||||
RuntimeUtils *utils = [[RuntimeUtils alloc] init];
|
||||
|
||||
if (action && [action isEqualToString: NOTIFICATION_CLEAR_ACTION]) {
|
||||
if ((action && [action isEqualToString: NOTIFICATION_CLEAR_ACTION]) || (state == UIApplicationStateInactive)) {
|
||||
// If received a notification that a channel was read, remove all notifications from that channel (only with app in foreground/background)
|
||||
[self cleanNotificationsFromChannel:channelId];
|
||||
RuntimeUtils *utils = [[RuntimeUtils alloc] init];
|
||||
[[UploadSession shared] notificationReceiptWithNotificationId:ackId receivedAt:round([[NSDate date] timeIntervalSince1970] * 1000.0) type:action];
|
||||
[utils delayWithSeconds:0.2 closure:^(void) {
|
||||
// This is to notify the NotificationCenter that something has changed.
|
||||
completionHandler(UIBackgroundFetchResultNewData);
|
||||
}];
|
||||
|
||||
return;
|
||||
} else if (state == UIApplicationStateInactive) {
|
||||
// When the notification is opened
|
||||
[self cleanNotificationsFromChannel:channelId];
|
||||
}
|
||||
|
||||
completionHandler(UIBackgroundFetchResultNoData);
|
||||
[[UploadSession shared] notificationReceiptWithNotificationId:ackId receivedAt:round([[NSDate date] timeIntervalSince1970] * 1000.0) type:action];
|
||||
[utils delayWithSeconds:0.2 closure:^(void) {
|
||||
// This is to notify the NotificationCenter that something has changed.
|
||||
completionHandler(UIBackgroundFetchResultNewData);
|
||||
}];
|
||||
}
|
||||
|
||||
-(void)cleanNotificationsFromChannel:(NSString *)channelId {
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
|
||||
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
|
||||
if let bestAttemptContent = bestAttemptContent {
|
||||
let ackId = bestAttemptContent.userInfo["ack_id"] as! String
|
||||
let type = bestAttemptContent.userInfo["type"] as! String
|
||||
let postId = bestAttemptContent.userInfo["post_id"] as! String
|
||||
let ackId = (bestAttemptContent.userInfo["ack_id"] ?? "") as! String
|
||||
let type = (bestAttemptContent.userInfo["type"] ?? "") as! String
|
||||
let postId = (bestAttemptContent.userInfo["post_id"] ?? "") as! String
|
||||
let idLoaded = (bestAttemptContent.userInfo["id_loaded"] ?? false) as! Bool
|
||||
|
||||
fetchReceipt(
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ module.exports = [
|
|||
'app/init/emm_provider.js',
|
||||
'app/init/fetch.js',
|
||||
'app/init/global_event_handler.js',
|
||||
'app/init/push_notifications.js',
|
||||
'app/mattermost.js',
|
||||
'app/mattermost_bucket/index.js',
|
||||
'app/mattermost_managed/index.js',
|
||||
|
|
@ -182,7 +183,6 @@ module.exports = [
|
|||
'app/utils/general.js',
|
||||
'app/utils/i18n.js',
|
||||
'app/utils/preferences.js',
|
||||
'app/utils/push_notifications.js',
|
||||
'app/utils/security.js',
|
||||
'app/utils/sentry/index.js',
|
||||
'app/utils/time_tracker.js',
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ module.exports = [
|
|||
'./node_modules/app/init/emm_provider.js',
|
||||
'./node_modules/app/init/fetch.js',
|
||||
'./node_modules/app/init/global_event_handler.js',
|
||||
'./node_modules/app/init/push_notifications.js',
|
||||
'./node_modules/app/mattermost.js',
|
||||
'./node_modules/app/mattermost_bucket/index.js',
|
||||
'./node_modules/app/mattermost_managed/index.js',
|
||||
|
|
@ -182,7 +183,6 @@ module.exports = [
|
|||
'./node_modules/app/utils/general.js',
|
||||
'./node_modules/app/utils/i18n.js',
|
||||
'./node_modules/app/utils/preferences.js',
|
||||
'./node_modules/app/utils/push_notifications.js',
|
||||
'./node_modules/app/utils/security.js',
|
||||
'./node_modules/app/utils/sentry/index.js',
|
||||
'./node_modules/app/utils/time_tracker.js',
|
||||
|
|
|
|||
Loading…
Reference in a new issue