Created
January 19, 2023 17:17
-
-
Save bbsmithy/6c8abf88cff0ad8b52e7e8154354d6e8 to your computer and use it in GitHub Desktop.
NotificationsWrapper component for handling notifications setup and interactions in React Native Expo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as Notifications from 'expo-notifications'; | |
import { useEffect, useRef } from "react"; | |
import { Platform } from "react-native"; | |
import * as Device from "expo-device"; | |
import { useDispatch, useSelector } from 'react-redux'; | |
import { UserSlice } from '../state/reducers/UserReducer'; | |
import { navigateWhenReady } from '../navigation'; | |
import { RootState } from '../state/store'; | |
import { remindersList, RemindersSlice } from '../state/reducers/RemindersReducer'; | |
import { DEFAULT_THOUGHT_EXCERCISE_REMINDER } from '../state/middleware/NotificationsMiddleware'; | |
const NotificationWrapper = (props: any) => { | |
const dispatch = useDispatch(); | |
// const notificationListener = useRef(); | |
const responseListener = useRef(); | |
const lastNotificationResponse = Notifications.useLastNotificationResponse(); | |
const registeredReminders = useSelector(remindersList); | |
const handleNotificationType = (notif_type: string, notif_data: any) => { | |
switch (notif_type) { | |
case "THOUGHT_COMMENT": { | |
if (notif_data.thought_id) { | |
navigateWhenReady("NewThoughtModal", { id: notif_data.thought_id }); | |
} | |
break; | |
} | |
case "THOUGHT_EXCERCISE_REMINDER": { | |
navigateWhenReady("NewThoughtModal") | |
break; | |
} | |
case "OVERALL_PROGRESS_REPORT_REMINDER": { | |
navigateWhenReady("OverallProgressReport") | |
break; | |
} | |
case "SESSION_RATING_REPORT_REMINDER": { | |
navigateWhenReady("SessionRatingReport") | |
break; | |
} | |
default: { | |
alert(notif_type) | |
break; | |
} | |
} | |
} | |
const handleNotificationToken = (token: any) => { | |
dispatch(UserSlice.actions.setExpoToken(token)); | |
} | |
const handleTokenError = (err: any) => { | |
console.log(JSON.stringify(err)) | |
} | |
// // Handles notifications when app is in background | |
const handleNotificationResponse = (response: any) => { | |
const { notif_data, notif_type } = response.notification.request.content.data; | |
handleNotificationType(notif_type, notif_data); | |
} | |
// Handles notifications when app is closed | |
useEffect(() => { | |
if ( | |
lastNotificationResponse | |
) { | |
const notifData = lastNotificationResponse.notification.request.content.data?.notif_data | |
const notifType = lastNotificationResponse.notification.request.content.data?.notif_type | |
if (notifData && notifType) { | |
handleNotificationType(notifType as string, notifData); | |
} | |
} | |
}, [lastNotificationResponse]); | |
useEffect(() => { | |
// Check for registered reminder notifs in state | |
if (registeredReminders.thought_excercise === null) { | |
dispatch(RemindersSlice.actions.setThoughtExcerciseReminder(DEFAULT_THOUGHT_EXCERCISE_REMINDER)); | |
} | |
}, []) | |
useEffect(() => { | |
registerForPushNotificationsAsync().then(handleNotificationToken).catch(handleTokenError); | |
responseListener.current = Notifications.addNotificationResponseReceivedListener(handleNotificationResponse); | |
return () => { | |
Notifications.removeNotificationSubscription(responseListener.current); | |
}; | |
}, []); | |
return ( | |
<> | |
{props.children} | |
</> | |
) | |
} | |
export default NotificationWrapper; | |
async function registerForPushNotificationsAsync() { | |
let token; | |
if (Platform.OS === 'android') { | |
await Notifications.setNotificationChannelAsync('default', { | |
name: 'default', | |
importance: Notifications.AndroidImportance.MAX, | |
vibrationPattern: [0, 250, 250, 250], | |
lightColor: '#FF231F7C', | |
}); | |
} | |
if (Device.isDevice) { | |
const { status: existingStatus } = await Notifications.getPermissionsAsync(); | |
let finalStatus = existingStatus; | |
if (existingStatus !== 'granted') { | |
const { status } = await Notifications.requestPermissionsAsync(); | |
finalStatus = status; | |
} | |
if (finalStatus !== 'granted') { | |
alert('Failed to get push token for push notification!'); | |
return; | |
} | |
token = (await Notifications.getExpoPushTokenAsync()).data; | |
} else { | |
alert('Must use physical device for Push Notifications'); | |
} | |
return token; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment