From d0346a8d0d72b27294c610b11a8d127c6f6298dc Mon Sep 17 00:00:00 2001 From: Kushdeep Singh Date: Tue, 10 Dec 2024 16:02:39 +0530 Subject: [PATCH] DMAPP-115: Review Changes - Added a utility function for displaying notifications using Notifee to streamline notification handling. - Removed the `channelInboxNotificationAcknowledgement` object state from `homeSlice` to simplify state management --- src/components/ui/HomeFeed.js | 26 ++--- src/helpers/NotificationHelper.ts | 152 ++++++--------------------- src/helpers/helpers.types.ts | 3 + src/helpers/helpers.utils.ts | 47 +++++++++ src/navigation/NotifTabNavigator.tsx | 6 +- src/redux/homeSlice.ts | 36 +++---- 6 files changed, 112 insertions(+), 158 deletions(-) create mode 100644 src/helpers/helpers.types.ts create mode 100644 src/helpers/helpers.utils.ts diff --git a/src/components/ui/HomeFeed.js b/src/components/ui/HomeFeed.js index cf4e9d170..ac13d1290 100644 --- a/src/components/ui/HomeFeed.js +++ b/src/components/ui/HomeFeed.js @@ -17,8 +17,10 @@ import ImagePreviewFooter from 'src/components/ui/ImagePreviewFooter'; import {usePushApi} from 'src/contexts/PushApiContext'; import AppBadgeHelper from 'src/helpers/AppBadgeHelper'; import { - selectInboxNotificationAcknowledgement, - updateInboxNotificationAcknowledgement, + selectNotificationOpened, + selectNotificationReceived, + updateNotificationOpened, + updateNotificationReceived, } from 'src/redux/homeSlice'; import EmptyFeed from './EmptyFeed'; @@ -40,9 +42,8 @@ export default function InboxFeed(props) { const [startFromIndex, setStartFromIndex] = useState(0); // GET REDUX STATES AND DISPATCH ACTIONS - const channelInboxNotificationAcknowledgement = useSelector( - selectInboxNotificationAcknowledgement, - ); + const notificationOpened = useSelector(selectNotificationOpened); + const notificationReceived = useSelector(selectNotificationReceived); const dispatch = useDispatch(); @@ -57,19 +58,12 @@ export default function InboxFeed(props) { }, [initialized, userPushSDKInstance]); useEffect(() => { - if ( - channelInboxNotificationAcknowledgement.notificationReceived || - channelInboxNotificationAcknowledgement.notificationOpened - ) { + if (notificationReceived || notificationOpened) { fetchFeed(true, true); - dispatch( - updateInboxNotificationAcknowledgement({ - notificationOpened: false, - notificationReceived: false, - }), - ); + dispatch(updateNotificationOpened(false)); + dispatch(updateNotificationReceived(false)); } - }, [channelInboxNotificationAcknowledgement]); + }, [notificationOpened, notificationReceived]); useEffect(() => { if (Platform.OS === 'android') { diff --git a/src/helpers/NotificationHelper.ts b/src/helpers/NotificationHelper.ts index b5a477e6b..0c1edf41c 100644 --- a/src/helpers/NotificationHelper.ts +++ b/src/helpers/NotificationHelper.ts @@ -13,21 +13,13 @@ import envConfig from 'src/env.config'; import {getCurrentRouteName, navigate} from 'src/navigation/RootNavigation'; import {UserChatCredentials} from 'src/navigation/screens/chats/ChatScreen'; import {globalDispatch} from 'src/redux'; -import {updateInboxNotificationAcknowledgement} from 'src/redux/homeSlice'; +import { + updateNotificationOpened, + updateNotificationReceived, +} from 'src/redux/homeSlice'; import MetaStorage from 'src/singletons/MetaStorage'; -type SendNotifeeNotification = { - messageId: string; - title?: string; - body?: string; - conversationId: string; - from: { - id: string; - avatar: string; - name: string; - }; - newMessage: AndroidMessagingStyleMessage; -}; +import {getNotifeeConfig} from './helpers.utils'; const NOTIFICATION_TYPES = { CHANNEL: 'PUSH_NOTIFICATION_CHANNEL', @@ -49,6 +41,27 @@ export const NotificationHelper = { } }, + /**************************************************/ + /** This Function will push CHANNEL notification **/ + /**************************************************/ + handleChannelNotification: async ( + remoteMessage: FirebaseMessagingTypes.RemoteMessage, + ) => { + try { + const notifeeConfig = getNotifeeConfig( + 'PUSH_NOTIFICATION_CHANNEL', + remoteMessage, + ); + await notifee.displayNotification(notifeeConfig); + NotificationHelper.handlePostNotificationReceived(remoteMessage.data); + } catch (error) { + console.log('NOTIFEE ERROR', error); + } + }, + + /***************************************************/ + /** This Function will push CHAT notification **/ + /***************************************************/ handleChatNotification: async ( message: FirebaseMessagingTypes.RemoteMessage, ) => { @@ -80,98 +93,15 @@ export const NotificationHelper = { // }); }, - /**************************************************/ - /** This Function will push CHANNEL notification **/ - /**************************************************/ - handleChannelNotification: async ( + sendNotification: async ( remoteMessage: FirebaseMessagingTypes.RemoteMessage, ) => { try { - const parsedDetails = remoteMessage.data?.details - ? JSON.parse(remoteMessage.data?.details as string) - : {}; - const largeIcon = parsedDetails?.info?.icon ?? 'ic_launcher_round'; - await notifee.displayNotification({ - id: remoteMessage.messageId, - title: remoteMessage.notification?.title, - body: remoteMessage.notification?.body, - ios: { - sound: 'default', - foregroundPresentationOptions: { - banner: true, - list: true, - badge: true, - sound: true, - }, - }, - android: { - channelId: 'default', - largeIcon, - smallIcon: - remoteMessage.notification?.android?.smallIcon ?? 'ic_notification', - color: - remoteMessage.notification?.android?.color ?? - Globals.COLORS.IC_NOTIFICATION, - circularLargeIcon: true, - pressAction: { - id: 'default', - }, - }, - data: remoteMessage.data, - }); - NotificationHelper.handlePostNotificationReceived(remoteMessage.data); - } catch (error) { - console.log('NOTIFEE ERROR', error); - } - }, - - /***************************************************/ - /** This Function will push CHAT notification **/ - /***************************************************/ - sendNotification: async (notification: SendNotifeeNotification) => { - try { - const messages = [notification.newMessage]; - - await notifee.displayNotification({ - id: notification.messageId, - title: notification?.title, - body: notification?.body, - ios: { - sound: 'default', - foregroundPresentationOptions: { - alert: true, - badge: true, - sound: true, - }, - categoryId: 'Communications', - communicationInfo: { - conversationId: notification.conversationId, - sender: { - id: notification.from.id, - avatar: notification.from.avatar, - displayName: notification.from.name, - }, - }, - }, - android: { - channelId: 'default', - largeIcon: notification.from.avatar, - smallIcon: '@drawable/ic_stat_name', - color: '#e20880', - circularLargeIcon: true, - pressAction: { - id: 'default', - }, - style: { - type: AndroidStyle.MESSAGING, - person: { - name: notification.from.name, - icon: notification.from.avatar, - }, - messages: messages, - }, - }, - }); + const notifeeConfig = getNotifeeConfig( + 'PUSH_NOTIFICATION_CHAT', + remoteMessage, + ); + await notifee.displayNotification(notifeeConfig); } catch (error) { console.log('NOTIFEE ERROR', error); } @@ -246,20 +176,12 @@ export const NotificationHelper = { ) { // If Home(Notification) tab is active then update data if (getCurrentRouteName() == GLOBALS.SCREENS.NOTIF_TABS) { - globalDispatch( - updateInboxNotificationAcknowledgement({ - notificationOpened: true, - }), - ); + globalDispatch(updateNotificationOpened(true)); } else { // If Home(Notification) tab is inactive then first // navigate to Home tab then update data navigate(GLOBALS.SCREENS.NOTIF_TABS); - globalDispatch( - updateInboxNotificationAcknowledgement({ - notificationOpened: true, - }), - ); + globalDispatch(updateNotificationOpened(true)); } } else if (data?.type === NOTIFICATION_TYPES.CHAT) { } @@ -285,11 +207,7 @@ export const NotificationHelper = { parsedDetails?.subType === NOTIFICATION_SUB_TYPES.INBOX && getCurrentRouteName() == GLOBALS.SCREENS.NOTIF_TABS ) { - globalDispatch( - updateInboxNotificationAcknowledgement({ - notificationReceived: true, - }), - ); + globalDispatch(updateNotificationReceived(true)); } }, }; diff --git a/src/helpers/helpers.types.ts b/src/helpers/helpers.types.ts new file mode 100644 index 000000000..af97f7af1 --- /dev/null +++ b/src/helpers/helpers.types.ts @@ -0,0 +1,3 @@ +export type NotificationTypes = + | 'PUSH_NOTIFICATION_CHANNEL' + | 'PUSH_NOTIFICATION_CHAT'; diff --git a/src/helpers/helpers.utils.ts b/src/helpers/helpers.utils.ts new file mode 100644 index 000000000..867fad171 --- /dev/null +++ b/src/helpers/helpers.utils.ts @@ -0,0 +1,47 @@ +import {Notification} from '@notifee/react-native'; +import {FirebaseMessagingTypes} from '@react-native-firebase/messaging'; +import Globals from 'src/Globals'; + +import {NotificationTypes} from './helpers.types'; + +export const getNotifeeConfig = ( + type: NotificationTypes, + remoteMessage: FirebaseMessagingTypes.RemoteMessage, +): Notification => { + const parsedDetails = remoteMessage.data?.details + ? JSON.parse(remoteMessage.data?.details as string) + : {}; + if (type === 'PUSH_NOTIFICATION_CHANNEL') { + const largeIcon = parsedDetails?.info?.icon ?? 'ic_launcher_round'; + return { + id: remoteMessage.messageId, + title: remoteMessage.notification?.title, + body: remoteMessage.notification?.body, + ios: { + sound: 'default', + foregroundPresentationOptions: { + banner: true, + list: true, + badge: true, + sound: true, + }, + }, + android: { + channelId: 'default', + largeIcon, + smallIcon: + remoteMessage.notification?.android?.smallIcon ?? 'ic_notification', + color: + remoteMessage.notification?.android?.color ?? + Globals.COLORS.IC_NOTIFICATION, + circularLargeIcon: true, + pressAction: { + id: 'default', + }, + }, + data: remoteMessage.data, + }; + } else { + return {}; + } +}; diff --git a/src/navigation/NotifTabNavigator.tsx b/src/navigation/NotifTabNavigator.tsx index fdab56784..e138fece8 100644 --- a/src/navigation/NotifTabNavigator.tsx +++ b/src/navigation/NotifTabNavigator.tsx @@ -4,7 +4,7 @@ import {SceneMap, TabBar, TabView} from 'react-native-tab-view'; import {useSelector} from 'react-redux'; import GLOBALS from 'src/Globals'; import Header from 'src/components/ui/Header'; -import {selectInboxNotificationAcknowledgement} from 'src/redux/homeSlice'; +import {selectNotificationOpened} from 'src/redux/homeSlice'; import HomeScreen from './screens/HomeScreen'; import SpamBoxScreen from './screens/SpamBoxScreen'; @@ -19,9 +19,7 @@ const NotifTabNavigator = () => { const [index, setIndex] = useState(0); // GET REDUX STATES - const notificationOpened = useSelector( - selectInboxNotificationAcknowledgement, - )?.notificationOpened; + const notificationOpened = useSelector(selectNotificationOpened); useEffect(() => { if (notificationOpened && index === 1) { diff --git a/src/redux/homeSlice.ts b/src/redux/homeSlice.ts index 7d4429cc8..800217e88 100644 --- a/src/redux/homeSlice.ts +++ b/src/redux/homeSlice.ts @@ -1,42 +1,36 @@ import {PayloadAction, createSlice} from '@reduxjs/toolkit'; -export type ChannelInboxNotificationAcknowledgement = { - notificationReceived?: boolean; - notificationOpened?: boolean; -}; - type HomeInitialState = { - channelInboxNotificationAcknowledgement: ChannelInboxNotificationAcknowledgement; + notificationReceived: boolean; + notificationOpened: boolean; }; type ReturnTypeHome = {home: HomeInitialState}; const initialState: HomeInitialState = { - channelInboxNotificationAcknowledgement: { - notificationReceived: false, - notificationOpened: false, - }, + notificationReceived: false, + notificationOpened: false, }; const homeSlice = createSlice({ name: 'home', initialState, reducers: { - updateInboxNotificationAcknowledgement: ( - state, - action: PayloadAction, - ) => { - state.channelInboxNotificationAcknowledgement = { - ...state.channelInboxNotificationAcknowledgement, - ...action.payload, - }; + updateNotificationReceived: (state, action: PayloadAction) => { + state.notificationReceived = action.payload; + }, + updateNotificationOpened: (state, action: PayloadAction) => { + state.notificationOpened = action.payload; }, }, }); -export const {updateInboxNotificationAcknowledgement} = homeSlice.actions; +export const {updateNotificationReceived, updateNotificationOpened} = + homeSlice.actions; -export const selectInboxNotificationAcknowledgement = (state: ReturnTypeHome) => - state.home.channelInboxNotificationAcknowledgement; +export const selectNotificationReceived = (state: ReturnTypeHome) => + state.home.notificationReceived; +export const selectNotificationOpened = (state: ReturnTypeHome) => + state.home.notificationOpened; export default homeSlice.reducer;