notifications
This commit is contained in:
@@ -50,6 +50,7 @@ SplashScreen.preventAutoHideAsync();
|
|||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
const [currentUID, setCurrentUID] = useGlobal("currentUID");
|
const [currentUID, setCurrentUID] = useGlobal("currentUID");
|
||||||
|
const [pendingData, setPendingData] = useGlobal("pendingData");
|
||||||
const [, setCurrentUserRoles] = useGlobal("currentUserRoles");
|
const [, setCurrentUserRoles] = useGlobal("currentUserRoles");
|
||||||
|
|
||||||
const [appIsReady, setAppIsReady] = useState(false);
|
const [appIsReady, setAppIsReady] = useState(false);
|
||||||
|
|||||||
@@ -8,6 +8,13 @@ exports.refList = {
|
|||||||
projects: admin.firestore().collection("projects"),
|
projects: admin.firestore().collection("projects"),
|
||||||
playlists: admin.firestore().collection("playlists"),
|
playlists: admin.firestore().collection("playlists"),
|
||||||
tasks: admin.firestore().collection("tasks"),
|
tasks: admin.firestore().collection("tasks"),
|
||||||
|
notifications: admin.firestore().collection("notifications"),
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.ALERT_TYPE = {
|
||||||
|
NEW_LIKE: "NEW_LIKE",
|
||||||
|
NEW_COMMENT: "NEW_COMMENT",
|
||||||
|
NEW_FOLLOWER: "NEW_FOLLOWER",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Exporter toutes les fonctions
|
// Exporter toutes les fonctions
|
||||||
@@ -19,3 +26,4 @@ exports.projects = require("./src/project");
|
|||||||
exports.thumbnail = require("./src/thumbnail");
|
exports.thumbnail = require("./src/thumbnail");
|
||||||
exports.upload = require("./src/upload");
|
exports.upload = require("./src/upload");
|
||||||
exports.algolia = require("./src/algolia");
|
exports.algolia = require("./src/algolia");
|
||||||
|
exports.notifications = require("./src/notifications");
|
||||||
|
|||||||
Generated
+69
@@ -10,6 +10,7 @@
|
|||||||
"@genkit-ai/googleai": "^1.18.0",
|
"@genkit-ai/googleai": "^1.18.0",
|
||||||
"@google-cloud/storage": "^7.17.1",
|
"@google-cloud/storage": "^7.17.1",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
|
"expo-server-sdk": "^4.0.0",
|
||||||
"ffmpeg-static": "^5.2.0",
|
"ffmpeg-static": "^5.2.0",
|
||||||
"firebase-admin": "^12.7.0",
|
"firebase-admin": "^12.7.0",
|
||||||
"firebase-functions": "^6.4.0",
|
"firebase-functions": "^6.4.0",
|
||||||
@@ -3416,6 +3417,12 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/err-code": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/error": {
|
"node_modules/error": {
|
||||||
"version": "7.0.2",
|
"version": "7.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz",
|
||||||
@@ -3703,6 +3710,40 @@
|
|||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/expo-server-sdk": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/expo-server-sdk/-/expo-server-sdk-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-zi83XtG2pqyP3gyn1JIRYkydo2i6HU3CYaWo/VvhZG/F29U+QIDv6LBEUsWf4ddZlVE7c9WN1N8Be49rHgO8OQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": "^2.6.0",
|
||||||
|
"promise-limit": "^2.7.0",
|
||||||
|
"promise-retry": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/expo-server-sdk/node_modules/node-fetch": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.21.2",
|
"version": "4.21.2",
|
||||||
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
|
||||||
@@ -5707,6 +5748,34 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/promise-limit": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise-limit/-/promise-limit-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
|
"node_modules/promise-retry": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"err-code": "^2.0.2",
|
||||||
|
"retry": "^0.12.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/promise-retry/node_modules/retry": {
|
||||||
|
"version": "0.12.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
|
||||||
|
"integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/proto3-json-serializer": {
|
"node_modules/proto3-json-serializer": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"@genkit-ai/googleai": "^1.18.0",
|
"@genkit-ai/googleai": "^1.18.0",
|
||||||
"@google-cloud/storage": "^7.17.1",
|
"@google-cloud/storage": "^7.17.1",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
|
"expo-server-sdk": "^4.0.0",
|
||||||
"ffmpeg-static": "^5.2.0",
|
"ffmpeg-static": "^5.2.0",
|
||||||
"firebase-admin": "^12.7.0",
|
"firebase-admin": "^12.7.0",
|
||||||
"firebase-functions": "^6.4.0",
|
"firebase-functions": "^6.4.0",
|
||||||
|
|||||||
@@ -0,0 +1,213 @@
|
|||||||
|
const { onDocumentCreated } = require("firebase-functions/v2/firestore");
|
||||||
|
const admin = require("firebase-admin");
|
||||||
|
const { refList, ALERT_TYPE } = require("../index");
|
||||||
|
const { Expo } = require("expo-server-sdk");
|
||||||
|
|
||||||
|
// Initialisation de Expo SDK
|
||||||
|
let expo = new Expo();
|
||||||
|
const db = admin.firestore();
|
||||||
|
|
||||||
|
exports.sendNotificationWhenDocIsCreated = onDocumentCreated(
|
||||||
|
{ region: "europe-west1", document: "notifications/{notificationId}" },
|
||||||
|
async (event) => {
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
receiver = null,
|
||||||
|
title = "MusicLand",
|
||||||
|
receiverCollection = "users",
|
||||||
|
message = "",
|
||||||
|
data: notifData = {},
|
||||||
|
} = event.data.data();
|
||||||
|
|
||||||
|
const { pushToken = null } =
|
||||||
|
(await db.collection(receiverCollection).doc(receiver).get())?.data() ||
|
||||||
|
{};
|
||||||
|
|
||||||
|
if (!receiver || !message) {
|
||||||
|
throw new Error("Receiver and message are required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pushToken) {
|
||||||
|
await sendExpoNotification(pushToken, {
|
||||||
|
title: title || "MusicLand",
|
||||||
|
message: message,
|
||||||
|
data: notifData || {},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn("User push token not found");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fonction pour envoyer la notification via Expo SDK
|
||||||
|
async function sendExpoNotification(
|
||||||
|
pushToken,
|
||||||
|
{ title = "", message = "", data = {} }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
if (!Expo.isExpoPushToken(pushToken)) {
|
||||||
|
throw new Error(`Invalid push token: ${pushToken}`);
|
||||||
|
} else {
|
||||||
|
console.log("Valid push token:", pushToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
const receipts = await expo.sendPushNotificationsAsync([
|
||||||
|
{
|
||||||
|
to: pushToken,
|
||||||
|
sound: "default",
|
||||||
|
title: title,
|
||||||
|
body: message,
|
||||||
|
data: data || {},
|
||||||
|
priority: "high",
|
||||||
|
badge: 1,
|
||||||
|
channelId: "default",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
console.log("Sent push notifications:", receipts);
|
||||||
|
|
||||||
|
return { sent: true };
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Error sending notification:", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fonction pour ajouter une notification à la base de données
|
||||||
|
const sendNotification = async ({
|
||||||
|
sender = "SYSTEM",
|
||||||
|
receiver = null,
|
||||||
|
receiverCollection = "users",
|
||||||
|
title = "",
|
||||||
|
message = null,
|
||||||
|
data = {},
|
||||||
|
}) => {
|
||||||
|
try {
|
||||||
|
if (!receiver || !message) {
|
||||||
|
throw new Error("Receiver and message are required");
|
||||||
|
}
|
||||||
|
const { id } = await refList.notifications.add({
|
||||||
|
sender,
|
||||||
|
receiver,
|
||||||
|
receiverCollection,
|
||||||
|
title,
|
||||||
|
message,
|
||||||
|
time: new Date(),
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
console.log(`Notification ${id} created`);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.sendNotification = sendNotification;
|
||||||
|
|
||||||
|
exports.createProjectCommentNotification = onDocumentCreated(
|
||||||
|
{
|
||||||
|
region: "europe-west1",
|
||||||
|
document: "projects/{projectId}/comments/{commentId}",
|
||||||
|
},
|
||||||
|
async (event) => {
|
||||||
|
try {
|
||||||
|
console.log(
|
||||||
|
"[createProjectCommentNotification] Trigger received",
|
||||||
|
JSON.stringify(event.params || {}, null, 2)
|
||||||
|
);
|
||||||
|
const { data: snap } = event;
|
||||||
|
const { projectId, commentId } = event.params || {};
|
||||||
|
const comment = snap?.data();
|
||||||
|
|
||||||
|
if (!projectId || !comment) {
|
||||||
|
console.log(
|
||||||
|
"[createProjectCommentNotification] Missing project/comment data",
|
||||||
|
{ hasProjectId: !!projectId, hasComment: !!comment }
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"[createProjectCommentNotification] Comment payload",
|
||||||
|
JSON.stringify(comment, null, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
const projectSnap = await refList.projects.doc(projectId).get();
|
||||||
|
if (!projectSnap.exists) {
|
||||||
|
console.log(
|
||||||
|
"[createProjectCommentNotification] Project not found",
|
||||||
|
projectId
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const project = projectSnap.data() || {};
|
||||||
|
const receiver = project.userId || null;
|
||||||
|
|
||||||
|
if (!receiver || receiver === comment.userId) {
|
||||||
|
console.log(
|
||||||
|
"[createProjectCommentNotification] Invalid receiver",
|
||||||
|
JSON.stringify({ receiver, commentUserId: comment.userId })
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const commenterName =
|
||||||
|
typeof comment?.userName === "string" && comment.userName.trim()
|
||||||
|
? comment.userName.trim()
|
||||||
|
: "Un utilisateur";
|
||||||
|
const projectTitle =
|
||||||
|
typeof project.title === "string" && project.title.trim()
|
||||||
|
? project.title.trim()
|
||||||
|
: "ton projet";
|
||||||
|
const message = `${commenterName} a commenté ton projet "${projectTitle}"`;
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"[createProjectCommentNotification] Creating notification",
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
receiver,
|
||||||
|
message,
|
||||||
|
commentId,
|
||||||
|
projectId,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
await sendNotification({
|
||||||
|
sender: comment.userId || "SYSTEM",
|
||||||
|
receiver,
|
||||||
|
receiverCollection: "users",
|
||||||
|
title: "Nouveau commentaire",
|
||||||
|
message,
|
||||||
|
data: {
|
||||||
|
type: ALERT_TYPE?.NEW_COMMENT,
|
||||||
|
projectId,
|
||||||
|
commentId,
|
||||||
|
commenterId: comment.userId || null,
|
||||||
|
commenterName: commenterName,
|
||||||
|
commenterProfilePicture: comment?.profilePicture || "",
|
||||||
|
text:
|
||||||
|
typeof comment?.text === "string" && comment.text.trim()
|
||||||
|
? comment.text.trim()
|
||||||
|
: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"[createProjectCommentNotification] Notification creation complete"
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
} catch (error) {
|
||||||
|
console.log("createProjectCommentNotification error:", error);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
"expo-linear-gradient": "~14.0.2",
|
"expo-linear-gradient": "~14.0.2",
|
||||||
"expo-linking": "~7.0.5",
|
"expo-linking": "~7.0.5",
|
||||||
"expo-location": "~18.0.10",
|
"expo-location": "~18.0.10",
|
||||||
|
"expo-notifications": "~0.29.14",
|
||||||
"expo-speech": "~13.0.1",
|
"expo-speech": "~13.0.1",
|
||||||
"expo-splash-screen": "~0.29.24",
|
"expo-splash-screen": "~0.29.24",
|
||||||
"expo-status-bar": "~2.0.1",
|
"expo-status-bar": "~2.0.1",
|
||||||
|
|||||||
@@ -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 { SafeAreaProvider } from "react-native-safe-area-context";
|
||||||
|
|
||||||
import { SheetProvider } from "react-native-actions-sheet";
|
import { SheetProvider } from "react-native-actions-sheet";
|
||||||
|
import NotificationProvider from "./NotificationProvider";
|
||||||
import PlayerProvider from "./PlayerProvider";
|
import PlayerProvider from "./PlayerProvider";
|
||||||
import SplashAnimationProvider from "./SplashAnimationProvider";
|
import SplashAnimationProvider from "./SplashAnimationProvider";
|
||||||
import StripeEmbeddedProvider from "./StripeEmbeddedProvider";
|
import StripeEmbeddedProvider from "./StripeEmbeddedProvider";
|
||||||
@@ -23,6 +24,7 @@ const SharedProviders = ({ children }) => {
|
|||||||
[BottomSheetModalProvider, {}],
|
[BottomSheetModalProvider, {}],
|
||||||
[SheetProvider, {}],
|
[SheetProvider, {}],
|
||||||
[PlayerProvider, {}],
|
[PlayerProvider, {}],
|
||||||
|
[NotificationProvider, {}],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Dynamically nest the providers using reduce
|
// Dynamically nest the providers using reduce
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ const PlaybackItem = ({ item, isActive, userCache, getUserByUid }) => {
|
|||||||
|
|
||||||
// Follow state derived from owner.followedBy
|
// Follow state derived from owner.followedBy
|
||||||
const [isFollowing, setIsFollowing] = useState(false);
|
const [isFollowing, setIsFollowing] = useState(false);
|
||||||
|
const [isFollowActionPending, setIsFollowActionPending] = useState(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const list = Array.isArray(owner?.followedBy) ? owner.followedBy : [];
|
const list = Array.isArray(owner?.followedBy) ? owner.followedBy : [];
|
||||||
setIsFollowing(currentUID ? list.includes(currentUID) : false);
|
setIsFollowing(currentUID ? list.includes(currentUID) : false);
|
||||||
@@ -278,9 +279,14 @@ const PlaybackItem = ({ item, isActive, userCache, getUserByUid }) => {
|
|||||||
</Pressable>
|
</Pressable>
|
||||||
{owner?.id && currentUID && owner.id !== currentUID && (
|
{owner?.id && currentUID && owner.id !== currentUID && (
|
||||||
<Pressable
|
<Pressable
|
||||||
|
disabled={isFollowActionPending}
|
||||||
onPress={async () => {
|
onPress={async () => {
|
||||||
|
if (isFollowActionPending) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
setIsFollowActionPending(true);
|
||||||
const next = !isFollowing;
|
const next = !isFollowing;
|
||||||
|
console.log("follwin");
|
||||||
setIsFollowing(next);
|
setIsFollowing(next);
|
||||||
// Optimistic update of local owner.followedBy
|
// Optimistic update of local owner.followedBy
|
||||||
setOwner((prev) => {
|
setOwner((prev) => {
|
||||||
@@ -294,9 +300,15 @@ const PlaybackItem = ({ item, isActive, userCache, getUserByUid }) => {
|
|||||||
});
|
});
|
||||||
if (next) await followUser?.(owner.id);
|
if (next) await followUser?.(owner.id);
|
||||||
else await unfollowUser?.(owner.id);
|
else await unfollowUser?.(owner.id);
|
||||||
|
|
||||||
|
// Timeout de 2 secondes avant de pouvoir recliquer
|
||||||
|
global.setTimeout(() => {
|
||||||
|
setIsFollowActionPending(false);
|
||||||
|
}, 1000);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// rollback on failure
|
// rollback on failure
|
||||||
setIsFollowing((v) => !v);
|
setIsFollowing((v) => !v);
|
||||||
|
setIsFollowActionPending(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1898,6 +1898,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba"
|
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba"
|
||||||
integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==
|
integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==
|
||||||
|
|
||||||
|
"@ide/backoff@^1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ide/backoff/-/backoff-1.0.0.tgz#466842c25bd4a4833e0642fab41ccff064010176"
|
||||||
|
integrity sha512-F0YfUDjvT+Mtt/R4xdl2X0EYCHMMiJqNLdxHD++jDT5ydEFIyqbCHh51Qx2E211dgZprPKhV7sHmnXKpLuvc5g==
|
||||||
|
|
||||||
"@isaacs/cliui@^8.0.2":
|
"@isaacs/cliui@^8.0.2":
|
||||||
version "8.0.2"
|
version "8.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
|
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
|
||||||
@@ -3155,6 +3160,17 @@ asap@~2.0.3, asap@~2.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||||
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
|
integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==
|
||||||
|
|
||||||
|
assert@^2.0.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd"
|
||||||
|
integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==
|
||||||
|
dependencies:
|
||||||
|
call-bind "^1.0.2"
|
||||||
|
is-nan "^1.3.2"
|
||||||
|
object-is "^1.1.5"
|
||||||
|
object.assign "^4.1.4"
|
||||||
|
util "^0.12.5"
|
||||||
|
|
||||||
ast-types@0.15.2:
|
ast-types@0.15.2:
|
||||||
version "0.15.2"
|
version "0.15.2"
|
||||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.15.2.tgz#39ae4809393c4b16df751ee563411423e85fb49d"
|
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.15.2.tgz#39ae4809393c4b16df751ee563411423e85fb49d"
|
||||||
@@ -3322,6 +3338,11 @@ babel-preset-jest@^29.6.3:
|
|||||||
babel-plugin-jest-hoist "^29.6.3"
|
babel-plugin-jest-hoist "^29.6.3"
|
||||||
babel-preset-current-node-syntax "^1.0.0"
|
babel-preset-current-node-syntax "^1.0.0"
|
||||||
|
|
||||||
|
badgin@^1.1.5:
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/badgin/-/badgin-1.2.3.tgz#994b5f519827d7d5422224825b2c8faea2bc43ad"
|
||||||
|
integrity sha512-NQGA7LcfCpSzIbGRbkgjgdWkjy7HI+Th5VLxTJfW5EeaAf3fnS+xWQaQOCYiny+q6QSvxqoSO04vCx+4u++EJw==
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||||
@@ -3557,7 +3578,7 @@ call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-
|
|||||||
es-errors "^1.3.0"
|
es-errors "^1.3.0"
|
||||||
function-bind "^1.1.2"
|
function-bind "^1.1.2"
|
||||||
|
|
||||||
call-bind@^1.0.7, call-bind@^1.0.8:
|
call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.7, call-bind@^1.0.8:
|
||||||
version "1.0.8"
|
version "1.0.8"
|
||||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c"
|
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c"
|
||||||
integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==
|
integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==
|
||||||
@@ -5233,6 +5254,19 @@ expo-modules-core@2.2.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
invariant "^2.2.4"
|
invariant "^2.2.4"
|
||||||
|
|
||||||
|
expo-notifications@~0.29.14:
|
||||||
|
version "0.29.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/expo-notifications/-/expo-notifications-0.29.14.tgz#77beb6bc74b1b1abfa3adcab77fb6c9ea5d7d1b0"
|
||||||
|
integrity sha512-AVduNx9mKOgcAqBfrXS1OHC9VAQZrDQLbVbcorMjPDGXW7m0Q5Q+BG6FYM/saVviF2eO8fhQRsTT40yYv5/bhQ==
|
||||||
|
dependencies:
|
||||||
|
"@expo/image-utils" "^0.6.5"
|
||||||
|
"@ide/backoff" "^1.0.0"
|
||||||
|
abort-controller "^3.0.0"
|
||||||
|
assert "^2.0.0"
|
||||||
|
badgin "^1.1.5"
|
||||||
|
expo-application "~6.0.2"
|
||||||
|
expo-constants "~17.0.8"
|
||||||
|
|
||||||
expo-speech@~13.0.1:
|
expo-speech@~13.0.1:
|
||||||
version "13.0.1"
|
version "13.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/expo-speech/-/expo-speech-13.0.1.tgz#f49fc2c8a73f9bada030e52fc86a235cd3963f4a"
|
resolved "https://registry.yarnpkg.com/expo-speech/-/expo-speech-13.0.1.tgz#f49fc2c8a73f9bada030e52fc86a235cd3963f4a"
|
||||||
@@ -5791,6 +5825,11 @@ functions-have-names@^1.2.3:
|
|||||||
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
|
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
|
||||||
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
|
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
|
||||||
|
|
||||||
|
generator-function@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/generator-function/-/generator-function-2.0.1.tgz#0e75dd410d1243687a0ba2e951b94eedb8f737a2"
|
||||||
|
integrity sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==
|
||||||
|
|
||||||
gensync@^1.0.0-beta.2:
|
gensync@^1.0.0-beta.2:
|
||||||
version "1.0.0-beta.2"
|
version "1.0.0-beta.2"
|
||||||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||||
@@ -6332,7 +6371,7 @@ inflight@^1.0.4:
|
|||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
|
|
||||||
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@~2.0.3:
|
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
@@ -6392,6 +6431,14 @@ ipaddr.js@^1.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
||||||
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
||||||
|
|
||||||
|
is-arguments@^1.0.4:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.2.0.tgz#ad58c6aecf563b78ef2bf04df540da8f5d7d8e1b"
|
||||||
|
integrity sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==
|
||||||
|
dependencies:
|
||||||
|
call-bound "^1.0.2"
|
||||||
|
has-tostringtag "^1.0.2"
|
||||||
|
|
||||||
is-array-buffer@^3.0.4, is-array-buffer@^3.0.5:
|
is-array-buffer@^3.0.4, is-array-buffer@^3.0.5:
|
||||||
version "3.0.5"
|
version "3.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280"
|
resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280"
|
||||||
@@ -6520,6 +6567,17 @@ is-generator-function@^1.0.10:
|
|||||||
has-tostringtag "^1.0.2"
|
has-tostringtag "^1.0.2"
|
||||||
safe-regex-test "^1.1.0"
|
safe-regex-test "^1.1.0"
|
||||||
|
|
||||||
|
is-generator-function@^1.0.7:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.2.tgz#ae3b61e3d5ea4e4839b90bad22b02335051a17d5"
|
||||||
|
integrity sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==
|
||||||
|
dependencies:
|
||||||
|
call-bound "^1.0.4"
|
||||||
|
generator-function "^2.0.0"
|
||||||
|
get-proto "^1.0.1"
|
||||||
|
has-tostringtag "^1.0.2"
|
||||||
|
safe-regex-test "^1.1.0"
|
||||||
|
|
||||||
is-gif@^3.0.0:
|
is-gif@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-gif/-/is-gif-3.0.0.tgz#c4be60b26a301d695bb833b20d9b5d66c6cf83b1"
|
resolved "https://registry.yarnpkg.com/is-gif/-/is-gif-3.0.0.tgz#c4be60b26a301d695bb833b20d9b5d66c6cf83b1"
|
||||||
@@ -6552,6 +6610,14 @@ is-map@^2.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e"
|
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e"
|
||||||
integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==
|
integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==
|
||||||
|
|
||||||
|
is-nan@^1.3.2:
|
||||||
|
version "1.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d"
|
||||||
|
integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==
|
||||||
|
dependencies:
|
||||||
|
call-bind "^1.0.0"
|
||||||
|
define-properties "^1.1.3"
|
||||||
|
|
||||||
is-natural-number@^4.0.1:
|
is-natural-number@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"
|
resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8"
|
||||||
@@ -6678,7 +6744,7 @@ is-symbol@^1.0.4, is-symbol@^1.1.1:
|
|||||||
has-symbols "^1.1.0"
|
has-symbols "^1.1.0"
|
||||||
safe-regex-test "^1.1.0"
|
safe-regex-test "^1.1.0"
|
||||||
|
|
||||||
is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15:
|
is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15, is-typed-array@^1.1.3:
|
||||||
version "1.1.15"
|
version "1.1.15"
|
||||||
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b"
|
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b"
|
||||||
integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==
|
integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==
|
||||||
@@ -7945,6 +8011,14 @@ object-inspect@^1.13.3, object-inspect@^1.13.4:
|
|||||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213"
|
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213"
|
||||||
integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==
|
integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==
|
||||||
|
|
||||||
|
object-is@^1.1.5:
|
||||||
|
version "1.1.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07"
|
||||||
|
integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==
|
||||||
|
dependencies:
|
||||||
|
call-bind "^1.0.7"
|
||||||
|
define-properties "^1.2.1"
|
||||||
|
|
||||||
object-keys@^1.1.1:
|
object-keys@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
||||||
@@ -10497,6 +10571,17 @@ util-deprecate@~1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||||
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
|
||||||
|
|
||||||
|
util@^0.12.5:
|
||||||
|
version "0.12.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc"
|
||||||
|
integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==
|
||||||
|
dependencies:
|
||||||
|
inherits "^2.0.3"
|
||||||
|
is-arguments "^1.0.4"
|
||||||
|
is-generator-function "^1.0.7"
|
||||||
|
is-typed-array "^1.1.3"
|
||||||
|
which-typed-array "^1.1.2"
|
||||||
|
|
||||||
utils-merge@1.0.1:
|
utils-merge@1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
|
||||||
@@ -10650,7 +10735,7 @@ which-collection@^1.0.2:
|
|||||||
is-weakmap "^2.0.2"
|
is-weakmap "^2.0.2"
|
||||||
is-weakset "^2.0.3"
|
is-weakset "^2.0.3"
|
||||||
|
|
||||||
which-typed-array@^1.1.16, which-typed-array@^1.1.19:
|
which-typed-array@^1.1.16, which-typed-array@^1.1.19, which-typed-array@^1.1.2:
|
||||||
version "1.1.19"
|
version "1.1.19"
|
||||||
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956"
|
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956"
|
||||||
integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==
|
integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==
|
||||||
|
|||||||
Reference in New Issue
Block a user