import React, { createContext, useContext, useState, useEffect, FC, useRef, } from "react"; import { Platform } from "react-native"; import * as Notifications from "expo-notifications"; import * as Device from "expo-device"; import Constants from "expo-constants"; type initialStateType = { expoPushToken: string; }; const initialState = { expoPushToken: "", }; Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowAlert: true, shouldPlaySound: true, shouldSetBadge: true, }), }); function handleRegistrationError(errorMessage: string) { console.log(errorMessage); //throw new Error(errorMessage); } async function registerForPushNotificationsAsync() { if (Platform.OS === "android") { Notifications.setNotificationChannelAsync("default", { name: "default", importance: Notifications.AndroidImportance.DEFAULT, vibrationPattern: [0, 250, 250, 250], lightColor: "#FF231F7C", }); Notifications.setNotificationChannelAsync("運行情報", { name: "運行情報", importance: Notifications.AndroidImportance.DEFAULT, vibrationPattern: [0, 250, 250, 250], lightColor: "#FF231F7C", }); Notifications.setNotificationChannelAsync("遅延速報EX", { name: "遅延速報EX", importance: Notifications.AndroidImportance.LOW, vibrationPattern: [0, 250, 250, 250], lightColor: "#FF231F7C", }); Notifications.setNotificationChannelAsync("怪レい列車BOT", { name: "怪レい列車BOT", importance: Notifications.AndroidImportance.LOW, 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") { handleRegistrationError( "Permission not granted to get push token for push notification!" ); return; } const projectId = Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.easConfig?.projectId; if (!projectId) { handleRegistrationError("Project ID not found"); } try { const pushTokenString = ( await Notifications.getExpoPushTokenAsync({ projectId, }) ).data; console.log(pushTokenString); return pushTokenString; } catch (e) { handleRegistrationError(`${e}`); } } else { handleRegistrationError("Must use physical device for push notifications"); } } const NotificationContext = createContext(initialState); type Props = { children: React.ReactNode; }; export const useNotification = () => { return useContext(NotificationContext); }; export const NotificationProvider: FC = ({ children }) => { const [expoPushToken, setExpoPushToken] = useState(""); const [notification, setNotification] = useState< Notifications.Notification | undefined >(undefined); const notificationListener = useRef(); const responseListener = useRef(); useEffect(() => { registerForPushNotificationsAsync() .then((token) => setExpoPushToken(token ?? "")) .catch((error) => setExpoPushToken(`${error}`)); notificationListener.current = Notifications.addNotificationReceivedListener((notification) => { setNotification(notification); }); responseListener.current = Notifications.addNotificationResponseReceivedListener((response) => { console.log(response); }); return () => { notificationListener.current && Notifications.removeNotificationSubscription( notificationListener.current ); responseListener.current && Notifications.removeNotificationSubscription(responseListener.current); }; }, []); return ( {children} ); };