diff --git a/src/config/firebase.js b/src/config/firebase.js
index 6ec7adf..1054af1 100644
--- a/src/config/firebase.js
+++ b/src/config/firebase.js
@@ -54,7 +54,7 @@ export const notificationsRef = firestore.collection("notifications");
export const documentsRef = firestore.collection("documents");
export const chatsRef = firestore.collection("chats");
-export const { arrayUnion, arrayRemove, increment } =
+export const { arrayUnion, arrayRemove, increment, serverTimestamp } =
firebase.firestore.FieldValue;
export default firebase;
diff --git a/src/providers/UserDataProvider.js b/src/providers/UserDataProvider.js
index b7e8a0b..7abe7dd 100644
--- a/src/providers/UserDataProvider.js
+++ b/src/providers/UserDataProvider.js
@@ -93,7 +93,7 @@ export default ({ children }) => {
{
followerId: currentUID,
followeeId: userId,
- createdAt: firebase.firestore.FieldValue.serverTimestamp(),
+ createdAt: new Date(),
},
{ merge: true }
);
@@ -109,7 +109,10 @@ export default ({ children }) => {
try {
if (currentUID && userId) {
await followsRef.doc(`${currentUID}_${userId}`).delete();
- setTooltip({ type: "success", text: "Vous ne suivez plus cet utilisateur" });
+ setTooltip({
+ type: "success",
+ text: "Vous ne suivez plus cet utilisateur",
+ });
}
} catch (e) {
console.log(e);
diff --git a/src/screens/AccountSettings.js b/src/screens/AccountSettings.js
index dc06b47..e804399 100644
--- a/src/screens/AccountSettings.js
+++ b/src/screens/AccountSettings.js
@@ -1,21 +1,21 @@
-import React, { useGlobal } from "reactn";
-import { Text, Pressable } from "react-native";
import * as ImagePicker from "expo-image-picker";
+import { Pressable, Text } from "react-native";
import useMinuit from "react-native-minuit/src/hooks/useMinuit.js";
+import React, { useGlobal } from "reactn";
import { responsiveWidth } from "../actions/responsiveSizes.js";
import Page from "../layouts/Page";
+import alert from "../components/Alert.js";
import Avatar from "../components/Avatar";
import InputRow from "../components/InputRow";
import ItemRowList from "../components/ItemRowList.js";
-import alert from "../components/Alert.js";
import firebase, { usersRef } from "../config/firebase";
-import { Fonts, gutters, Palette, Style } from "../styles";
import { uploadFileToFirebase } from "../helpers/uploadToFirebase";
import { Routes } from "../navigation/Routes.js";
+import { Fonts, gutters, Palette, Style } from "../styles";
import { useUserData } from "../providers/UserDataProvider.js";
diff --git a/src/screens/Library/Research.js b/src/screens/Library/Research.js
index 664ac05..99b5780 100644
--- a/src/screens/Library/Research.js
+++ b/src/screens/Library/Research.js
@@ -1,9 +1,10 @@
-import React, { useMemo, useState } from "react";
+import React, { useEffect, useMemo, useState } from "react";
import { Image, Pressable, ScrollView, Text, View } from "react-native";
import { background, img } from "../../assets";
import MoreMenu from "../../components/MoreMenu";
import { usersRef } from "../../config/firebase";
import useDataFromRef from "../../hooks/useDataFromRef";
+import { useGlobal } from "reactn";
import Page from "../../layouts/Page";
import { Routes } from "../../navigation";
import { navigate } from "../../navigation/NavigationService";
@@ -18,14 +19,18 @@ const Research = () => {
const [selected, setSelected] = useState(null);
const [search, setSearch] = useState("");
const queryText = useMemo(() => search.trim(), [search]);
+ const [currentUID] = useGlobal("currentUID");
+ const [autoLoads, setAutoLoads] = useState(0);
const usersQueryRef = useMemo(() => {
- if (!queryText) return null;
try {
- return usersRef
- .orderBy("userName")
- .startAt(queryText)
- .endAt(queryText + "\uf8ff");
+ if (queryText) {
+ return usersRef
+ .orderBy("userName")
+ .startAt(queryText)
+ .endAt(queryText + "\uf8ff");
+ }
+ return usersRef.orderBy("userName");
} catch (e) {
return null;
}
@@ -39,11 +44,28 @@ const Research = () => {
ref: usersQueryRef,
simpleRef: false,
listener: false,
- condition: !!usersQueryRef && queryText.length > 0,
+ condition: !!usersQueryRef,
refreshArray: [queryText],
usePagination: true,
batchSize: 5,
});
+ const filteredUsers = useMemo(() => {
+ const arr = Array.isArray(userResults) ? userResults : [];
+ return arr.filter((u) => u?.id !== currentUID && u?.userID !== currentUID);
+ }, [JSON.stringify(userResults), currentUID]);
+
+ useEffect(() => {
+ setAutoLoads(0);
+ }, [queryText]);
+
+ useEffect(() => {
+ if (filteredUsers.length < 5 && usersQueryRef && !usersLoading) {
+ if (autoLoads < 3) {
+ setAutoLoads((n) => n + 1);
+ loadMoreUsers();
+ }
+ }
+ }, [filteredUsers.length, usersLoading, usersQueryRef, autoLoads, loadMoreUsers]);
const [menuTop, setMenuTop] = useState(0);
const [showMenu, setShowMenu] = useState(false);
const [selectedProjectId, setSelectedProjectId] = useState(null);
@@ -138,21 +160,8 @@ const Research = () => {
gradientProps={{ start: { x: 0, y: 0 }, end: { x: 0, y: 1 } }}
>
- {queryText.length === 0 && (
-
- Commence à taper pour rechercher des profils…
-
- )}
-
- {queryText.length > 0 &&
- Array.isArray(userResults) &&
- userResults.map((u) => (
+ {Array.isArray(filteredUsers) &&
+ filteredUsers.slice(0, 5).map((u) => (
{
))}
-
- {queryText.length > 0 && userResults.length > 0 && (
+ {(filteredUsers.length >= 5 || usersLoading) && (
{
const [currentUserData] = useGlobal("currentUserData");
const [, setTooltip] = useGlobal("_tooltip");
-
+ const { currentUID } = useUser();
const [pseudo, setPseudo] = useState("");
const [loading, setLoading] = useState(false);
+ const [updatingPhoto, setUpdatingPhoto] = useState(false);
useEffect(() => {
if (currentUserData?.userName && !pseudo) {
@@ -53,18 +57,67 @@ const EditProfile = () => {
userNameLower: lower,
updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
},
- { merge: true },
+ { merge: true }
);
setTooltip({ text: "Pseudo mis à jour", type: "success" });
goBack();
} catch (e) {
console.log("EditProfile onSave error", e?.message);
- setTooltip({ text: e?.message || "Mise à jour impossible", type: "error" });
+ setTooltip({
+ text: e?.message || "Mise à jour impossible",
+ type: "error",
+ });
} finally {
setLoading(false);
}
};
+
+ const onChangePicture = async () => {
+ try {
+ setUpdatingPhoto(true);
+ const uid = currentUID;
+ if (!uid) return;
+
+ const result = await ImagePicker.launchImageLibraryAsync({
+ mediaTypes: ImagePicker.MediaTypeOptions.Images,
+ allowsEditing: true,
+ aspect: [4, 4],
+ quality: 1,
+ });
+
+ const pickedUri = result?.assets?.[0]?.uri || null;
+ if (!pickedUri) return;
+
+ const { resultURI = null } = await uploadFileToFirebase({
+ uri: pickedUri,
+ path: `users/${uid}/profilePicture.png`,
+ });
+
+ if (!resultURI) throw new Error("Téléversement de l'image impossible");
+
+ await usersRef.doc(uid).set(
+ {
+ profilePictureURL: resultURI,
+ updatedAt: serverTimestamp(),
+ },
+ { merge: true }
+ );
+
+ await firebase.auth().currentUser.updateProfile({
+ photoURL: resultURI,
+ });
+
+ setTooltip({ text: "Photo de profil mise à jour", type: "success" });
+ } catch (e) {
+ setTooltip({
+ text: e?.message || "Erreur changement photo de profil",
+ type: "error",
+ });
+ } finally {
+ setUpdatingPhoto(false);
+ }
+ };
return (
{
Platform.OS !== "ios" ? "dimezisBlurView" : "none"
}
>
-
+
{
fontFamily: FONT_FAMILY.InterRegular,
}}
>
- Modifier la photo
+ {updatingPhoto ? "Chargement..." : "Modifier la photo"}
-
-
+
+
{
alignSelf: "center",
}}
onPress={onSave}
- disabled={loading || !pseudo?.trim() || pseudo?.trim() === (currentUserData?.userName || "")}
+ disabled={
+ loading ||
+ updatingPhoto ||
+ !pseudo?.trim() ||
+ pseudo?.trim() === (currentUserData?.userName || "")
+ }
/>
diff --git a/src/screens/Profile/Profile.js b/src/screens/Profile/Profile.js
index 4b3ca1a..ab0666c 100644
--- a/src/screens/Profile/Profile.js
+++ b/src/screens/Profile/Profile.js
@@ -1,5 +1,5 @@
import { BlurView } from "expo-blur";
-import React, { useState } from "react";
+import React, { useEffect, useState } from "react";
import {
FlatList,
Image,
@@ -22,24 +22,29 @@ import Page from "../../layouts/Page";
import { Routes } from "../../navigation";
import { navigate } from "../../navigation/NavigationService";
import { useUser } from "../../providers/UserDataProvider";
+import { getFollowersCount, getFollowingCount } from "../../services/follows";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import Style, { gutters, size } from "../../styles/Style";
import MusicCard from "../Library/components/MusicCard";
-
const Profile = () => {
const [selected, setSelected] = useState("Chansons");
const [currentUserData] = useGlobal("currentUserData");
- const { userProjects } = useUser();
+ const { userProjects, currentUID } = useUser();
const [, setTooltip] = useGlobal("_tooltip");
const [menuTop, setMenuTop] = useState(0);
const [showMenu, setShowMenu] = useState(false);
const [selectedProjectId, setSelectedProjectId] = useState(null);
-
+ const [following, setFollowing] = useState(0);
+ const [followers, setFollowers] = useState(0);
const onPressMenu = (item) => {
setSelected(item);
};
-
+ useEffect(() => {
+ if (!currentUID) return;
+ getFollowersCount(currentUID).then(setFollowers);
+ getFollowingCount(currentUID).then(setFollowing);
+ }, [currentUID]);
return (
{
>
{
playbacks
-
- {currentUserData?.followBy?.length || 0}
-
+ {followers}
abonnés
-
- {currentUserData?.following?.length || 0}
-
+ {following}
abonnements
diff --git a/src/screens/Profile/SingerProfile.js b/src/screens/Profile/SingerProfile.js
index 6f66b12..1878e2c 100644
--- a/src/screens/Profile/SingerProfile.js
+++ b/src/screens/Profile/SingerProfile.js
@@ -10,14 +10,14 @@ import {
View,
} from "react-native";
import { responsiveHeight } from "react-native-responsive-dimensions";
+import { useGlobal } from "reactn";
import { background, icons, img } from "../../assets";
import BorderGradient from "../../components/BorderGradient/BorderGradient";
import GradientButton from "../../components/GradientButton";
+import { followsRef } from "../../config/firebase";
import Page from "../../layouts/Page";
import { useUser } from "../../providers/UserDataProvider";
import { getFollowersCount, getFollowingCount } from "../../services/follows";
-import { useGlobal } from "reactn";
-import { followsRef } from "../../config/firebase";
import { gutters, Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
import Style, { size } from "../../styles/Style";
diff --git a/src/services/follows.js b/src/services/follows.js
index 3218f06..7989ff5 100644
--- a/src/services/follows.js
+++ b/src/services/follows.js
@@ -13,7 +13,7 @@ export const getFollowingCount = async (userId) => {
};
export const unfollowUser = async ({ followerId, followeeId }) => {
- if (!followerId || !followeeId) throw new Error("Missing followerId/followeeId");
+ if (!followerId || !followeeId) throw new Error("Erreur lors du unfollow");
const id = `${followerId}_${followeeId}`;
await followsRef.doc(id).delete();
return id;