From ecb9bde1fdffaa326b95656f41987f6d94f55f0c Mon Sep 17 00:00:00 2001 From: Elias Nahum Date: Wed, 25 Sep 2019 20:31:44 +0300 Subject: [PATCH] MM-18740 Sync app badge number when opening a push notification (#3322) --- .../push_notifications.ios.js | 15 ++++++++ .../channel_drawer_button/index.js | 34 ++----------------- app/selectors/views.js | 28 ++++++++++++++- app/utils/push_notifications.js | 1 + 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/app/push_notifications/push_notifications.ios.js b/app/push_notifications/push_notifications.ios.js index dae936ecf..e9ac2e9a8 100644 --- a/app/push_notifications/push_notifications.ios.js +++ b/app/push_notifications/push_notifications.ios.js @@ -4,6 +4,7 @@ import {AppState} from 'react-native'; import NotificationsIOS, {NotificationAction, NotificationCategory} from 'react-native-notifications'; +import {getBadgeCount} from 'app/selectors/views'; import ephemeralStore from 'app/store/ephemeral_store'; const CATEGORY = 'CAN_REPLY'; @@ -18,6 +19,7 @@ class PushNotification { this.onRegister = null; this.onNotification = null; this.onReply = null; + this.reduxStore = null; NotificationsIOS.addEventListener('remoteNotificationsRegistered', this.onRemoteNotificationsRegistered); NotificationsIOS.addEventListener('notificationReceivedForeground', this.onNotificationReceivedForeground); @@ -69,6 +71,7 @@ class PushNotification { }; configure(options) { + this.reduxStore = options.reduxStore; this.onRegister = options.onRegister; this.onNotification = options.onNotification; this.onReply = options.onReply; @@ -165,6 +168,15 @@ class PushNotification { clearChannelNotifications(channelId) { NotificationsIOS.getDeliveredNotifications((notifications) => { const ids = []; + let badgeCount = notifications.length; + + if (this.reduxStore) { + const totalMentions = getBadgeCount(this.reduxStore.getState()); + if (totalMentions > -1) { + badgeCount = totalMentions; + } + } + for (let i = 0; i < notifications.length; i++) { const notification = notifications[i]; @@ -174,8 +186,11 @@ class PushNotification { } if (ids.length) { + badgeCount -= ids.length; NotificationsIOS.removeDeliveredNotifications(ids); } + + this.setApplicationIconBadgeNumber(badgeCount); }); } diff --git a/app/screens/channel/channel_nav_bar/channel_drawer_button/index.js b/app/screens/channel/channel_nav_bar/channel_drawer_button/index.js index 535664510..714aaf2e1 100644 --- a/app/screens/channel/channel_nav_bar/channel_drawer_button/index.js +++ b/app/screens/channel/channel_nav_bar/channel_drawer_button/index.js @@ -2,45 +2,15 @@ // See LICENSE.txt for license information. import {connect} from 'react-redux'; -import {createSelector} from 'reselect'; -import {getUnreadsInCurrentTeam} from 'mattermost-redux/selectors/entities/channels'; -import {getCurrentTeamId, getTeamMemberships} from 'mattermost-redux/selectors/entities/teams'; import {getTheme} from 'mattermost-redux/selectors/entities/preferences'; +import {getBadgeCount} from 'app/selectors/views'; import ChannelDrawerButton from './channel_drawer_button'; -const getBadgeCount = createSelector( - getCurrentTeamId, - getTeamMemberships, - (state, mentionCount) => mentionCount, - (state, _, messageCount) => messageCount, - (currentTeamId, myTeamMembers, mentionCount, messageCount) => { - let mentions = mentionCount; - let messages = messageCount; - - const members = Object.values(myTeamMembers).filter((m) => m.team_id !== currentTeamId); - members.forEach((m) => { - mentions += (m.mention_count || 0); - messages += (m.msg_count || 0); - }); - - let badgeCount = 0; - if (mentions) { - badgeCount = mentions; - } else if (messages) { - badgeCount = -1; - } - - return badgeCount; - } -); - function mapStateToProps(state) { - const {mentionCount, messageCount} = getUnreadsInCurrentTeam(state); - return { - badgeCount: getBadgeCount(state, mentionCount, messageCount), + badgeCount: getBadgeCount(state), theme: getTheme(state), }; } diff --git a/app/selectors/views.js b/app/selectors/views.js index 81c68a185..e321e4f6d 100644 --- a/app/selectors/views.js +++ b/app/selectors/views.js @@ -3,7 +3,8 @@ import {createSelector} from 'reselect'; -import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels'; +import {getCurrentChannelId, getUnreadsInCurrentTeam} from 'mattermost-redux/selectors/entities/channels'; +import {getCurrentTeamId, getTeamMemberships} from 'mattermost-redux/selectors/entities/teams'; const emptyDraft = { draft: '', @@ -42,3 +43,28 @@ export const getThreadDraft = createSelector( export function getProfileImageUri(state) { return state.views.user.profileImageUri; } + +export const getBadgeCount = createSelector( + getCurrentTeamId, + getTeamMemberships, + getUnreadsInCurrentTeam, + (currentTeamId, myTeamMembers, {mentionCount, messageCount}) => { + let mentions = mentionCount; + let messages = messageCount; + + const members = Object.values(myTeamMembers).filter((m) => m.team_id !== currentTeamId); + members.forEach((m) => { + mentions += (m.mention_count || 0); + messages += (m.msg_count || 0); + }); + + let badgeCount = 0; + if (mentions) { + badgeCount = mentions; + } else if (messages) { + badgeCount = -1; + } + + return badgeCount; + } +); diff --git a/app/utils/push_notifications.js b/app/utils/push_notifications.js index 265388db8..3a7529959 100644 --- a/app/utils/push_notifications.js +++ b/app/utils/push_notifications.js @@ -34,6 +34,7 @@ class PushNotificationUtils { this.store = store; PushNotifications.configure({ + reduxStore: store, onRegister: this.onRegisterDevice, onNotification: this.onPushNotification, onReply: this.onPushNotificationReply,