89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import { registerForPushNotificationsAsync } from "@/lib/registerForPushNotificationsAsync";
|
|
import { Subscription } from "expo-modules-core";
|
|
import * as Notifications from "expo-notifications";
|
|
import React, {
|
|
createContext,
|
|
ReactNode,
|
|
useContext,
|
|
useEffect,
|
|
useRef,
|
|
useState,
|
|
} from "react";
|
|
|
|
interface NotificationContextType {
|
|
expoPushToken: string | null;
|
|
notification: Notifications.Notification | null;
|
|
error: Error | null;
|
|
}
|
|
|
|
const NotificationContext = createContext<NotificationContextType | undefined>(
|
|
undefined
|
|
);
|
|
|
|
export const useNotification = () => {
|
|
const context = useContext(NotificationContext);
|
|
if (context === undefined) {
|
|
throw new Error(
|
|
"useNotification must be used within a NotificationProvider"
|
|
);
|
|
}
|
|
return context;
|
|
};
|
|
|
|
interface NotificationProviderProps {
|
|
children: ReactNode;
|
|
}
|
|
|
|
export const NotificationProvider: React.FC<NotificationProviderProps> = ({
|
|
children,
|
|
}) => {
|
|
const [expoPushToken, setExpoPushToken] = useState<string | null>(null);
|
|
const [notification, setNotification] =
|
|
useState<Notifications.Notification | null>(null);
|
|
const [error, setError] = useState<Error | null>(null);
|
|
|
|
const notificationListener = useRef<Subscription>();
|
|
const responseListener = useRef<Subscription>();
|
|
|
|
useEffect(() => {
|
|
registerForPushNotificationsAsync().then(
|
|
(token) => setExpoPushToken(token),
|
|
(error) => setError(error)
|
|
);
|
|
|
|
notificationListener.current =
|
|
Notifications.addNotificationReceivedListener((notification) => {
|
|
console.log("🔔 Notification Received: ", notification);
|
|
setNotification(notification);
|
|
});
|
|
|
|
responseListener.current =
|
|
Notifications.addNotificationResponseReceivedListener((response) => {
|
|
console.log(
|
|
"🔔 Notification Response: ",
|
|
JSON.stringify(response, null, 2),
|
|
JSON.stringify(response.notification.request.content.data, null, 2)
|
|
);
|
|
// Handle the notification response here
|
|
});
|
|
|
|
return () => {
|
|
if (notificationListener.current) {
|
|
Notifications.removeNotificationSubscription(
|
|
notificationListener.current
|
|
);
|
|
}
|
|
if (responseListener.current) {
|
|
Notifications.removeNotificationSubscription(responseListener.current);
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<NotificationContext.Provider
|
|
value={{ expoPushToken, notification, error }}
|
|
>
|
|
{children}
|
|
</NotificationContext.Provider>
|
|
);
|
|
}; |