notifications
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import Constants from "expo-constants";
|
||||
import * as Device from "expo-device";
|
||||
import * as Notifications from "expo-notifications";
|
||||
import React, { createContext, useEffect, useRef, useState } from "react";
|
||||
import { useGlobal } from "reactn";
|
||||
import { usersRef } from "../config/firebase";
|
||||
|
||||
export const NotificationContext = createContext(null);
|
||||
|
||||
export default function NotificationProvider({ children }) {
|
||||
const [user] = useGlobal("currentUserData");
|
||||
const [uid] = useGlobal("currentUID");
|
||||
|
||||
const [pendingData, setPendingData] = useGlobal("pendingData");
|
||||
const [notifInit, setNotifInit] = useState(false);
|
||||
const [allowNotifications, setAllowNotifications] = useState(false);
|
||||
|
||||
const notificationListener = useRef();
|
||||
const responseListener = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
if (!!uid && !!user && !notifInit) {
|
||||
registerForPushNotificationsAsync();
|
||||
} else if (notifInit && allowNotifications) {
|
||||
notificationListener.current =
|
||||
Notifications.addNotificationReceivedListener(async (notification) => {
|
||||
console.log("Notification received", notification);
|
||||
await Notifications.scheduleNotificationAsync(notification?.request);
|
||||
});
|
||||
|
||||
responseListener.current =
|
||||
Notifications.addNotificationResponseReceivedListener(
|
||||
async (response) => {
|
||||
console.log("Notification response", response);
|
||||
if (
|
||||
response?.actionIdentifier ===
|
||||
"expo.modules.notifications.actions.DEFAULT"
|
||||
) {
|
||||
const { data } = response.notification.request.content;
|
||||
if (data) {
|
||||
console.log("Notification data", data);
|
||||
await setPendingData(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (notifInit && allowNotifications) {
|
||||
Notifications.removeNotificationSubscription(
|
||||
notificationListener.current
|
||||
);
|
||||
Notifications.removeNotificationSubscription(responseListener.current);
|
||||
}
|
||||
};
|
||||
}, [user, uid, notifInit]);
|
||||
|
||||
async function registerForPushNotificationsAsync() {
|
||||
try {
|
||||
if (Device.isDevice) {
|
||||
const { status } = await Notifications.requestPermissionsAsync();
|
||||
if (status !== "granted") {
|
||||
console.log("Notification permissions denied");
|
||||
return;
|
||||
}
|
||||
setAllowNotifications(true);
|
||||
setNotifInit(true);
|
||||
|
||||
// Get the push token
|
||||
const pushToken = (
|
||||
await Notifications.getExpoPushTokenAsync({
|
||||
projectId: Constants.expoConfig?.extra?.eas?.projectId || "",
|
||||
})
|
||||
).data;
|
||||
if (user?.pushToken !== pushToken && !!user) {
|
||||
await usersRef.doc(uid).update({ pushToken });
|
||||
// if (!user?.alerts) {
|
||||
// await usersRef.doc(uid).update({
|
||||
// alerts: Object.values(ALERT_TYPE),
|
||||
// });
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
console.log("Must use physical device for Push Notifications");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<NotificationContext.Provider
|
||||
value={{
|
||||
allowNotifications,
|
||||
pendingData,
|
||||
setPendingData,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</NotificationContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import React from "react";
|
||||
import { SafeAreaProvider } from "react-native-safe-area-context";
|
||||
|
||||
import { SheetProvider } from "react-native-actions-sheet";
|
||||
import NotificationProvider from "./NotificationProvider";
|
||||
import PlayerProvider from "./PlayerProvider";
|
||||
import SplashAnimationProvider from "./SplashAnimationProvider";
|
||||
import StripeEmbeddedProvider from "./StripeEmbeddedProvider";
|
||||
@@ -23,6 +24,7 @@ const SharedProviders = ({ children }) => {
|
||||
[BottomSheetModalProvider, {}],
|
||||
[SheetProvider, {}],
|
||||
[PlayerProvider, {}],
|
||||
[NotificationProvider, {}],
|
||||
];
|
||||
|
||||
// Dynamically nest the providers using reduce
|
||||
|
||||
@@ -100,6 +100,7 @@ const PlaybackItem = ({ item, isActive, userCache, getUserByUid }) => {
|
||||
|
||||
// Follow state derived from owner.followedBy
|
||||
const [isFollowing, setIsFollowing] = useState(false);
|
||||
const [isFollowActionPending, setIsFollowActionPending] = useState(false);
|
||||
useEffect(() => {
|
||||
const list = Array.isArray(owner?.followedBy) ? owner.followedBy : [];
|
||||
setIsFollowing(currentUID ? list.includes(currentUID) : false);
|
||||
@@ -278,9 +279,14 @@ const PlaybackItem = ({ item, isActive, userCache, getUserByUid }) => {
|
||||
</Pressable>
|
||||
{owner?.id && currentUID && owner.id !== currentUID && (
|
||||
<Pressable
|
||||
disabled={isFollowActionPending}
|
||||
onPress={async () => {
|
||||
if (isFollowActionPending) return;
|
||||
|
||||
try {
|
||||
setIsFollowActionPending(true);
|
||||
const next = !isFollowing;
|
||||
console.log("follwin");
|
||||
setIsFollowing(next);
|
||||
// Optimistic update of local owner.followedBy
|
||||
setOwner((prev) => {
|
||||
@@ -294,9 +300,15 @@ const PlaybackItem = ({ item, isActive, userCache, getUserByUid }) => {
|
||||
});
|
||||
if (next) await followUser?.(owner.id);
|
||||
else await unfollowUser?.(owner.id);
|
||||
|
||||
// Timeout de 2 secondes avant de pouvoir recliquer
|
||||
global.setTimeout(() => {
|
||||
setIsFollowActionPending(false);
|
||||
}, 1000);
|
||||
} catch (e) {
|
||||
// rollback on failure
|
||||
setIsFollowing((v) => !v);
|
||||
setIsFollowActionPending(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user