[Gekidou MM-44135 MM-44134 MM-40088] Group & Clear channel and thread notifications when CRT is on (#6429)
* Android * iOS changes * client changes * Misc * Update CustomPushNotification.java Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
parent
f1665fa0ee
commit
306fbba3a7
9 changed files with 178 additions and 78 deletions
|
|
@ -101,6 +101,16 @@ public class CustomPushNotificationHelper {
|
|||
userInfoBundle.putString("channel_id", channelId);
|
||||
}
|
||||
|
||||
String postId = bundle.getString("post_id");
|
||||
if (postId != null) {
|
||||
userInfoBundle.putString("post_id", postId);
|
||||
}
|
||||
|
||||
String rootId = bundle.getString("root_id");
|
||||
if (rootId != null) {
|
||||
userInfoBundle.putString("root_id", rootId);
|
||||
}
|
||||
|
||||
notification.addExtras(userInfoBundle);
|
||||
}
|
||||
|
||||
|
|
@ -145,12 +155,16 @@ public class CustomPushNotificationHelper {
|
|||
|
||||
String channelId = bundle.getString("channel_id");
|
||||
String postId = bundle.getString("post_id");
|
||||
String rootId = bundle.getString("root_id");
|
||||
int notificationId = postId != null ? postId.hashCode() : MESSAGE_NOTIFICATION_ID;
|
||||
|
||||
Boolean is_crt_enabled = bundle.getString("is_crt_enabled") != null && bundle.getString("is_crt_enabled").equals("true");
|
||||
String groupId = is_crt_enabled && !android.text.TextUtils.isEmpty(rootId) ? rootId : channelId;
|
||||
|
||||
addNotificationExtras(notification, bundle);
|
||||
setNotificationIcons(context, notification, bundle);
|
||||
setNotificationMessagingStyle(context, notification, bundle);
|
||||
setNotificationGroup(notification, channelId, createSummary);
|
||||
setNotificationGroup(notification, groupId, createSummary);
|
||||
setNotificationBadgeType(notification);
|
||||
|
||||
setNotificationChannel(notification, bundle);
|
||||
|
|
|
|||
|
|
@ -16,11 +16,9 @@ import androidx.annotation.Nullable;
|
|||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
|
|
@ -36,7 +34,6 @@ import com.wix.reactnativenotifications.core.AppLifecycleFacade;
|
|||
import com.wix.reactnativenotifications.core.JsIOHelper;
|
||||
import static com.wix.reactnativenotifications.Defs.NOTIFICATION_RECEIVED_EVENT_NAME;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class CustomPushNotification extends PushNotification {
|
||||
|
|
@ -71,7 +68,7 @@ public class CustomPushNotification extends PushNotification {
|
|||
editor.apply();
|
||||
}
|
||||
|
||||
Map<String, List<Integer>> inputMap = new HashMap<>();
|
||||
Map<String, Map<String, JSONObject>> inputMap = new HashMap<>();
|
||||
saveNotificationsMap(context, inputMap);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
|
|
@ -79,55 +76,71 @@ public class CustomPushNotification extends PushNotification {
|
|||
}
|
||||
}
|
||||
|
||||
public static void cancelNotification(Context context, String channelId, Integer notificationId) {
|
||||
public static void cancelNotification(Context context, String channelId, String rootId, Integer notificationId, Boolean isCRTEnabled) {
|
||||
if (!android.text.TextUtils.isEmpty(channelId)) {
|
||||
Map<String, List<Integer>> notificationsInChannel = loadNotificationsMap(context);
|
||||
List<Integer> notifications = notificationsInChannel.get(channelId);
|
||||
final String notificationIdStr = notificationId.toString();
|
||||
final Boolean isThreadNotification = isCRTEnabled && !android.text.TextUtils.isEmpty(rootId);
|
||||
final String groupId = isThreadNotification ? rootId : channelId;
|
||||
Map<String, Map<String, JSONObject>> notificationsInChannel = loadNotificationsMap(context);
|
||||
Map<String, JSONObject> notifications = notificationsInChannel.get(groupId);
|
||||
if (notifications == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
|
||||
notificationManager.cancel(notificationId);
|
||||
notifications.remove(notificationId);
|
||||
notifications.remove(notificationIdStr);
|
||||
final StatusBarNotification[] statusNotifications = notificationManager.getActiveNotifications();
|
||||
boolean hasMore = false;
|
||||
for (final StatusBarNotification status : statusNotifications) {
|
||||
if (status.getNotification().extras.getString("channel_id").equals(channelId)) {
|
||||
hasMore = true;
|
||||
Bundle bundle = status.getNotification().extras;
|
||||
if (isThreadNotification) {
|
||||
hasMore = bundle.getString("root_id").equals(rootId);
|
||||
} else {
|
||||
hasMore = bundle.getString("channel_id").equals(channelId);
|
||||
}
|
||||
if (hasMore) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasMore) {
|
||||
notificationsInChannel.remove(channelId);
|
||||
notificationsInChannel.remove(groupId);
|
||||
} else {
|
||||
notificationsInChannel.put(groupId, notifications);
|
||||
}
|
||||
|
||||
saveNotificationsMap(context, notificationsInChannel);
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearChannelNotifications(Context context, String channelId) {
|
||||
public static void clearChannelNotifications(Context context, String channelId, String rootId, Boolean isCRTEnabled) {
|
||||
if (!android.text.TextUtils.isEmpty(channelId)) {
|
||||
Map<String, List<Integer>> notificationsInChannel = loadNotificationsMap(context);
|
||||
List<Integer> notifications = notificationsInChannel.get(channelId);
|
||||
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
|
||||
// rootId is available only when CRT is enabled & clearing the thread
|
||||
final boolean isClearThread = isCRTEnabled && !android.text.TextUtils.isEmpty(rootId);
|
||||
|
||||
Map<String, Map<String, JSONObject>> notificationsInChannel = loadNotificationsMap(context);
|
||||
String groupId = isClearThread ? rootId : channelId;
|
||||
Map<String, JSONObject> notifications = notificationsInChannel.get(groupId);
|
||||
|
||||
if (notifications == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
notificationsInChannel.remove(channelId);
|
||||
notificationsInChannel.remove(groupId);
|
||||
saveNotificationsMap(context, notificationsInChannel);
|
||||
|
||||
for (final Integer notificationId : notifications) {
|
||||
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
notificationManager.cancel(notificationId);
|
||||
}
|
||||
notifications.forEach(
|
||||
(notificationIdStr, post) -> notificationManager.cancel(Integer.valueOf(notificationIdStr))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static void clearAllNotifications(Context context) {
|
||||
if (context != null) {
|
||||
Map<String, List<Integer>> notificationsInChannel = loadNotificationsMap(context);
|
||||
Map<String, Map<String, JSONObject>> notificationsInChannel = loadNotificationsMap(context);
|
||||
notificationsInChannel.clear();
|
||||
saveNotificationsMap(context, notificationsInChannel);
|
||||
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
|
|
@ -142,6 +155,8 @@ public class CustomPushNotification extends PushNotification {
|
|||
final String ackId = initialData.getString("ack_id");
|
||||
final String postId = initialData.getString("post_id");
|
||||
final String channelId = initialData.getString("channel_id");
|
||||
final String rootId = initialData.getString("root_id");
|
||||
final boolean isCRTEnabled = initialData.getString("is_crt_enabled") != null && initialData.getString("is_crt_enabled").equals("true");
|
||||
final boolean isIdLoaded = initialData.getString("id_loaded") != null && initialData.getString("id_loaded").equals("true");
|
||||
int notificationId = CustomPushNotificationHelper.MESSAGE_NOTIFICATION_ID;
|
||||
if (postId != null) {
|
||||
|
|
@ -188,25 +203,40 @@ public class CustomPushNotification extends PushNotification {
|
|||
// Data will be fetch from within the JS context instead.
|
||||
dataHelper.fetchAndStoreDataForPushNotification(mNotificationProps.asBundle());
|
||||
}
|
||||
try {
|
||||
JSONObject post = new JSONObject();
|
||||
if (!android.text.TextUtils.isEmpty(rootId)) {
|
||||
post.put("root_id", rootId);
|
||||
}
|
||||
if (!android.text.TextUtils.isEmpty(postId)) {
|
||||
post.put("post_id", postId);
|
||||
}
|
||||
|
||||
Map<String, List<Integer>> notificationsInChannel = loadNotificationsMap(mContext);
|
||||
List<Integer> list = notificationsInChannel.get(channelId);
|
||||
if (list == null) {
|
||||
list = Collections.synchronizedList(new ArrayList<>(0));
|
||||
final Boolean isThreadNotification = isCRTEnabled && post.has("root_id");
|
||||
final String groupId = isThreadNotification ? rootId : channelId;
|
||||
|
||||
Map<String, Map<String, JSONObject>> notificationsInChannel = loadNotificationsMap(mContext);
|
||||
Map<String, JSONObject> notifications = notificationsInChannel.get(groupId);
|
||||
if (notifications == null) {
|
||||
notifications = Collections.synchronizedMap(new HashMap<String, JSONObject>());
|
||||
}
|
||||
|
||||
if (notifications.size() > 0) {
|
||||
createSummary = false;
|
||||
}
|
||||
|
||||
notifications.put(String.valueOf(notificationId), post);
|
||||
|
||||
if (createSummary) {
|
||||
// Add the summary notification id as well
|
||||
notifications.put(String.valueOf(notificationId + 1), new JSONObject());
|
||||
}
|
||||
|
||||
notificationsInChannel.put(groupId, notifications);
|
||||
saveNotificationsMap(mContext, notificationsInChannel);
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
list.add(0, notificationId);
|
||||
if (list.size() > 1) {
|
||||
createSummary = false;
|
||||
}
|
||||
|
||||
if (createSummary) {
|
||||
// Add the summary notification id as well
|
||||
list.add(0, notificationId + 1);
|
||||
}
|
||||
|
||||
notificationsInChannel.put(channelId, list);
|
||||
saveNotificationsMap(mContext, notificationsInChannel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -214,7 +244,7 @@ public class CustomPushNotification extends PushNotification {
|
|||
}
|
||||
break;
|
||||
case PUSH_TYPE_CLEAR:
|
||||
clearChannelNotifications(mContext, channelId);
|
||||
clearChannelNotifications(mContext, channelId, rootId, isCRTEnabled);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -229,21 +259,11 @@ public class CustomPushNotification extends PushNotification {
|
|||
|
||||
Bundle data = mNotificationProps.asBundle();
|
||||
final String channelId = data.getString("channel_id");
|
||||
final String postId = data.getString("post_id");
|
||||
Integer notificationId = CustomPushNotificationHelper.MESSAGE_NOTIFICATION_ID;
|
||||
|
||||
if (postId != null) {
|
||||
notificationId = postId.hashCode();
|
||||
}
|
||||
final String rootId = data.getString("root_id");
|
||||
final Boolean isCRTEnabled = data.getBoolean("is_crt_enabled");
|
||||
|
||||
if (channelId != null) {
|
||||
Map<String, List<Integer>> notificationsInChannel = loadNotificationsMap(mContext);
|
||||
List<Integer> notifications = notificationsInChannel.get(channelId);
|
||||
if (notifications != null) {
|
||||
notifications.remove(notificationId);
|
||||
}
|
||||
saveNotificationsMap(mContext, notificationsInChannel);
|
||||
clearChannelNotifications(mContext, channelId);
|
||||
clearChannelNotifications(mContext, channelId, rootId, isCRTEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -293,7 +313,7 @@ public class CustomPushNotification extends PushNotification {
|
|||
return serverUrl;
|
||||
}
|
||||
|
||||
private static void saveNotificationsMap(Context context, Map<String, List<Integer>> inputMap) {
|
||||
private static void saveNotificationsMap(Context context, Map<String, Map<String, JSONObject>> inputMap) {
|
||||
SharedPreferences pSharedPref = context.getSharedPreferences(PUSH_NOTIFICATIONS, Context.MODE_PRIVATE);
|
||||
if (pSharedPref != null) {
|
||||
JSONObject json = new JSONObject(inputMap);
|
||||
|
|
@ -305,23 +325,41 @@ public class CustomPushNotification extends PushNotification {
|
|||
}
|
||||
}
|
||||
|
||||
private static Map<String, List<Integer>> loadNotificationsMap(Context context) {
|
||||
Map<String, List<Integer>> outputMap = new HashMap<>();
|
||||
/**
|
||||
* Map Structure
|
||||
*
|
||||
* {
|
||||
* channel_id1 | thread_id1: {
|
||||
* notification_id1: {
|
||||
* post_id: 'p1',
|
||||
* root_id: 'r1',
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
*/
|
||||
private static Map<String, Map<String, JSONObject>> loadNotificationsMap(Context context) {
|
||||
Map<String, Map<String, JSONObject>> outputMap = new HashMap<>();
|
||||
if (context != null) {
|
||||
SharedPreferences pSharedPref = context.getSharedPreferences(PUSH_NOTIFICATIONS, Context.MODE_PRIVATE);
|
||||
try {
|
||||
if (pSharedPref != null) {
|
||||
String jsonString = pSharedPref.getString(NOTIFICATIONS_IN_CHANNEL, (new JSONObject()).toString());
|
||||
JSONObject json = new JSONObject(jsonString);
|
||||
Iterator<String> keysItr = json.keys();
|
||||
while (keysItr.hasNext()) {
|
||||
String key = keysItr.next();
|
||||
JSONArray array = json.getJSONArray(key);
|
||||
List<Integer> values = new ArrayList<>();
|
||||
for (int i = 0; i < array.length(); ++i) {
|
||||
values.add(array.getInt(i));
|
||||
|
||||
// Can be a channel_id or thread_id
|
||||
Iterator<String> groupIdsItr = json.keys();
|
||||
while (groupIdsItr.hasNext()) {
|
||||
String groupId = groupIdsItr.next();
|
||||
JSONObject notificationsJSONObj = json.getJSONObject(groupId);
|
||||
Map<String, JSONObject> notifications = new HashMap<>();
|
||||
Iterator<String> notificationIdKeys = notificationsJSONObj.keys();
|
||||
while(notificationIdKeys.hasNext()) {
|
||||
String notificationId = notificationIdKeys.next();
|
||||
JSONObject post = notificationsJSONObj.getJSONObject(notificationId);
|
||||
notifications.put(notificationId, post);
|
||||
}
|
||||
outputMap.put(key, values);
|
||||
outputMap.put(groupId, notifications);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@ public class NotificationDismissService extends IntentService {
|
|||
final Bundle bundle = NotificationIntentAdapter.extractPendingNotificationDataFromIntent(intent);
|
||||
final String channelId = bundle.getString("channel_id");
|
||||
final String postId = bundle.getString("post_id");
|
||||
final String rootId = bundle.getString("root_id");
|
||||
final Boolean isCRTEnabled = bundle.getString("is_crt_enabled") != null && bundle.getString("is_crt_enabled").equals("true");
|
||||
|
||||
int notificationId = CustomPushNotificationHelper.MESSAGE_NOTIFICATION_ID;
|
||||
if (postId != null) {
|
||||
notificationId = postId.hashCode();
|
||||
|
|
@ -27,7 +30,7 @@ public class NotificationDismissService extends IntentService {
|
|||
notificationId = channelId.hashCode();
|
||||
}
|
||||
|
||||
CustomPushNotification.cancelNotification(context, channelId, notificationId);
|
||||
CustomPushNotification.cancelNotification(context, channelId, rootId, notificationId, isCRTEnabled);
|
||||
Log.i("ReactNative", "Dismiss notification");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,10 @@ public class NotificationPreferencesModule extends ReactContextBaseJavaModule {
|
|||
WritableMap map = Arguments.createMap();
|
||||
Notification n = sbn.getNotification();
|
||||
Bundle bundle = n.extras;
|
||||
String postId = bundle.getString("post_id");
|
||||
map.putString("post_id", postId);
|
||||
String rootId = bundle.getString("root_id");
|
||||
map.putString("root_id", rootId);
|
||||
String channelId = bundle.getString("channel_id");
|
||||
map.putString("channel_id", channelId);
|
||||
result.pushMap(map);
|
||||
|
|
@ -59,8 +63,8 @@ public class NotificationPreferencesModule extends ReactContextBaseJavaModule {
|
|||
}
|
||||
|
||||
@ReactMethod
|
||||
public void removeDeliveredNotifications(String channelId) {
|
||||
public void removeDeliveredNotifications(String channelId, String rootId, Boolean isCRTEnabled) {
|
||||
Context context = mApplication.getApplicationContext();
|
||||
CustomPushNotification.clearChannelNotifications(context, channelId);
|
||||
CustomPushNotification.clearChannelNotifications(context, channelId, rootId, isCRTEnabled);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
|
||||
import {prepareCommonSystemValues, PrepareCommonSystemValuesArgs, getCommonSystemValues, getCurrentTeamId, setCurrentChannelId, getCurrentUserId} from '@queries/servers/system';
|
||||
import {addChannelToTeamHistory, addTeamToTeamHistory, getTeamById, removeChannelFromTeamHistory} from '@queries/servers/team';
|
||||
import {getIsCRTEnabled} from '@queries/servers/thread';
|
||||
import {getCurrentUser, queryUsersById} from '@queries/servers/user';
|
||||
import {dismissAllModalsAndPopToRoot, dismissAllModalsAndPopToScreen} from '@screens/navigation';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
|
|
@ -175,7 +176,8 @@ export async function markChannelAsViewed(serverUrl: string, channelId: string,
|
|||
m.viewedAt = member.lastViewedAt;
|
||||
m.lastViewedAt = Date.now();
|
||||
});
|
||||
PushNotifications.cancelChannelNotifications(channelId);
|
||||
const isCRTEnabled = await getIsCRTEnabled(database);
|
||||
PushNotifications.cancelChannelNotifications(channelId, undefined, isCRTEnabled);
|
||||
if (!prepareRecordsOnly) {
|
||||
await operator.batchRecords([member]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {markTeamThreadsAsRead, processReceivedThreads, switchToThread, updateThr
|
|||
import {fetchPostThread} from '@actions/remote/post';
|
||||
import {General} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import PushNotifications from '@init/push_notifications';
|
||||
import NetworkManager from '@managers/network_manager';
|
||||
import {getChannelById} from '@queries/servers/channel';
|
||||
import {getPostById} from '@queries/servers/post';
|
||||
|
|
@ -156,7 +157,7 @@ export const updateTeamThreadsAsRead = async (serverUrl: string, teamId: string)
|
|||
}
|
||||
};
|
||||
|
||||
export const markThreadAsRead = async (serverUrl: string, teamId: string, threadId: string) => {
|
||||
export const markThreadAsRead = async (serverUrl: string, teamId: string | undefined, threadId: string) => {
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
|
||||
if (!database) {
|
||||
|
|
@ -187,6 +188,12 @@ export const markThreadAsRead = async (serverUrl: string, teamId: string, thread
|
|||
unread_mentions: 0,
|
||||
});
|
||||
|
||||
const isCRTEnabled = await getIsCRTEnabled(database);
|
||||
const post = await getPostById(database, threadId);
|
||||
if (post) {
|
||||
PushNotifications.cancelChannelNotifications(post.channelId, threadId, isCRTEnabled);
|
||||
}
|
||||
|
||||
return {data};
|
||||
} catch (error) {
|
||||
forceLogoutIfNecessary(serverUrl, error as ClientErrorProps);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import {
|
|||
import {storeDeviceToken} from '@actions/app/global';
|
||||
import {markChannelAsViewed} from '@actions/local/channel';
|
||||
import {backgroundNotification, openNotification} from '@actions/remote/notifications';
|
||||
import {markThreadAsRead} from '@actions/remote/thread';
|
||||
import {Device, Events, Navigation, Screens} from '@constants';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getTotalMentionsForServer} from '@database/subscription/unreads';
|
||||
|
|
@ -55,9 +56,9 @@ class PushNotifications {
|
|||
Notifications.cancelAllLocalNotifications();
|
||||
};
|
||||
|
||||
cancelChannelNotifications = async (channelId: string) => {
|
||||
cancelChannelNotifications = async (channelId: string, rootId?: string, isCRTEnabled?: boolean) => {
|
||||
const notifications = await NativeNotifications.getDeliveredNotifications();
|
||||
this.cancelNotificationsForChannel(notifications, channelId);
|
||||
this.cancelNotificationsForChannel(notifications, channelId, rootId, isCRTEnabled);
|
||||
};
|
||||
|
||||
cancelChannelsNotifications = async (channelIds: string[]) => {
|
||||
|
|
@ -67,15 +68,25 @@ class PushNotifications {
|
|||
}
|
||||
};
|
||||
|
||||
cancelNotificationsForChannel = (notifications: NotificationWithChannel[], channelId: string) => {
|
||||
cancelNotificationsForChannel = (notifications: NotificationWithChannel[], channelId: string, rootId?: string, isCRTEnabled?: boolean) => {
|
||||
if (Platform.OS === 'android') {
|
||||
NativeNotifications.removeDeliveredNotifications(channelId);
|
||||
NativeNotifications.removeDeliveredNotifications(channelId, rootId, isCRTEnabled);
|
||||
} else {
|
||||
const ids: string[] = [];
|
||||
const clearThreads = Boolean(rootId);
|
||||
|
||||
for (const notification of notifications) {
|
||||
if (notification.channel_id === channelId) {
|
||||
ids.push(notification.identifier);
|
||||
let doesNotificationMatch = true;
|
||||
if (clearThreads) {
|
||||
doesNotificationMatch = notification.thread === rootId;
|
||||
} else if (isCRTEnabled) {
|
||||
// Do not match when CRT is enabled BUT post is not a root post
|
||||
doesNotificationMatch = !notification.root_id;
|
||||
}
|
||||
if (doesNotificationMatch) {
|
||||
ids.push(notification.identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,9 +139,10 @@ class PushNotifications {
|
|||
if (database) {
|
||||
const isCRTEnabled = await getIsCRTEnabled(database);
|
||||
if (isCRTEnabled && payload.root_id) {
|
||||
return;
|
||||
markThreadAsRead(serverUrl, payload.team_id, payload.post_id);
|
||||
} else {
|
||||
markChannelAsViewed(serverUrl, payload.channel_id, false);
|
||||
}
|
||||
markChannelAsViewed(serverUrl, payload.channel_id, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -133,6 +133,8 @@ MattermostBucket* bucket = nil;
|
|||
UIApplicationState state = [UIApplication sharedApplication].applicationState;
|
||||
NSString* action = [userInfo objectForKey:@"type"];
|
||||
NSString* channelId = [userInfo objectForKey:@"channel_id"];
|
||||
NSString* rootId = [userInfo objectForKey:@"root_id"];
|
||||
BOOL isCRTEnabled = [userInfo objectForKey:@"is_crt_enabled"];
|
||||
BOOL isClearAction = (action && [action isEqualToString: NOTIFICATION_CLEAR_ACTION]);
|
||||
BOOL isTestAction = (action && [action isEqualToString: NOTIFICATION_TEST_ACTION]);
|
||||
|
||||
|
|
@ -142,8 +144,11 @@ MattermostBucket* bucket = nil;
|
|||
}
|
||||
|
||||
if (isClearAction) {
|
||||
// When CRT is OFF:
|
||||
// If received a notification that a channel was read, remove all notifications from that channel (only with app in foreground/background)
|
||||
[self cleanNotificationsFromChannel:channelId];
|
||||
// When CRT is ON:
|
||||
// When rootId is nil, clear channel's root post notifications or else clear all thread notifications
|
||||
[self cleanNotificationsFromChannel:channelId :rootId :isCRTEnabled];
|
||||
[[GekidouWrapper default] postNotificationReceipt:userInfo];
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +209,7 @@ MattermostBucket* bucket = nil;
|
|||
return extraModules;
|
||||
}
|
||||
|
||||
-(void)cleanNotificationsFromChannel:(NSString *)channelId {
|
||||
-(void)cleanNotificationsFromChannel:(NSString *)channelId :(NSString *)rootId :(BOOL)isCRTEnabled {
|
||||
if ([UNUserNotificationCenter class]) {
|
||||
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
|
||||
[center getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
|
||||
|
|
@ -215,9 +220,23 @@ MattermostBucket* bucket = nil;
|
|||
UNNotificationContent *notificationContent = [notificationRequest content];
|
||||
NSString *identifier = [notificationRequest identifier];
|
||||
NSString* cId = [[notificationContent userInfo] objectForKey:@"channel_id"];
|
||||
NSString* pId = [[notificationContent userInfo] objectForKey:@"post_id"];
|
||||
NSString* rId = [[notificationContent userInfo] objectForKey:@"root_id"];
|
||||
|
||||
if ([cId isEqualToString: channelId]) {
|
||||
[notificationIds addObject:identifier];
|
||||
BOOL doesNotificationMatch = true;
|
||||
if (isCRTEnabled) {
|
||||
// Check if it is a thread notification
|
||||
if (rootId != nil) {
|
||||
doesNotificationMatch = [pId isEqualToString: rootId] || [rId isEqualToString: rootId];
|
||||
} else {
|
||||
// With CRT ON, remove notifications without rootId
|
||||
doesNotificationMatch = rId == nil;
|
||||
}
|
||||
}
|
||||
if (doesNotificationMatch) {
|
||||
[notificationIds addObject:identifier];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
1
types/global/push_notifications.d.ts
vendored
1
types/global/push_notifications.d.ts
vendored
|
|
@ -49,4 +49,5 @@ interface NotificationWithData extends Notification {
|
|||
|
||||
declare class NotificationWithChannel extends Notification {
|
||||
channel_id?: string;
|
||||
root_id?: string;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue