loading messages

This commit is contained in:
2025-10-06 11:27:02 +02:00
parent 35e8a0f6dc
commit fd416b5b05
9 changed files with 336 additions and 40 deletions
+150 -26
View File
@@ -1,8 +1,10 @@
import { useRoute } from "@react-navigation/native";
import { BlurView } from "expo-blur";
import { Image as ExpoImage } from "expo-image";
import * as ImagePicker from "expo-image-picker";
import React, { useEffect, useMemo, useState } from "react";
import {
ActivityIndicator,
FlatList,
Image,
Pressable,
@@ -18,13 +20,19 @@ import { background, icons, img } from "../../assets";
import BorderGradient from "../../components/BorderGradient/BorderGradient";
import MoreMenu from "../../components/MoreMenu";
import PressableScale from "../../components/PressableScale";
import { projectsRef, usersRef } from "../../config/firebase";
import firebase, {
projectsRef,
serverTimestamp,
usersRef,
} from "../../config/firebase";
import loaderMessages from "../../config/loaderMessages";
import { uploadFileToFirebase } from "../../helpers/uploadToFirebase";
import useDataFromRef from "../../hooks/useDataFromRef";
import useLayoutType from "../../hooks/useLayoutType";
import useNavigateToMusicDetails from "../../hooks/useNavigateToMusicDetails";
import Page from "../../layouts/Page";
import { Routes } from "../../navigation";
import { navigate, push } from "../../navigation/NavigationService";
import { push } from "../../navigation/NavigationService";
import { useUser } from "../../providers/UserDataProvider";
import { Palette } from "../../styles";
import { FONT_FAMILY } from "../../styles/Fonts";
@@ -54,6 +62,8 @@ const Profile = () => {
const [menuPosition, setMenuPosition] = useState(null);
const [showMenu, setShowMenu] = useState(false);
const [selectedProjectId, setSelectedProjectId] = useState(null);
const [updatingPhoto, setUpdatingPhoto] = useState(false);
const [webUploadMessage, setWebUploadMessage] = useState("");
const navigateToMusicDetails = useNavigateToMusicDetails();
const onPressMenu = (item) => {
setSelected(item);
@@ -114,6 +124,59 @@ const Profile = () => {
}
};
const onChangeProfilePicture = async (message = "") => {
if (!isSelf || updatingPhoto) return;
try {
setUpdatingPhoto(true);
setWebUploadMessage(isWeb && message ? message : "");
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 }
);
const authUser = firebase.auth().currentUser;
if (authUser) {
await authUser.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);
setWebUploadMessage("");
}
};
// Composant factorisé pour afficher la liste de musiques
const MusicListSection = ({ data, emptyText }) => (
<ScrollView style={{ flex: 1, marginBottom: 70 }}>
@@ -286,30 +349,59 @@ const Profile = () => {
</PressableScale>
)}
<View style={{ alignItems: "center" }}>
<ExpoImage
source={
(
isSelf
? currentUserData?.profilePictureURL
: userData?.profilePictureURL
)
? {
uri: isSelf
? currentUserData?.profilePictureURL
: userData?.profilePictureURL,
}
: img.profile
}
cachePolicy="memory-disk"
priority="high"
contentFit="cover"
transition={100}
style={{
...size({ size: 108 }),
borderRadius: 100,
}}
/>
<View style={{ alignItems: "center" }}>
<View style={styles.avatarWrapper}>
<ExpoImage
source={
(
isSelf
? currentUserData?.profilePictureURL
: userData?.profilePictureURL
)
? {
uri: isSelf
? currentUserData?.profilePictureURL
: userData?.profilePictureURL,
}
: img.profile
}
cachePolicy="memory-disk"
priority="high"
contentFit="cover"
transition={100}
style={{
...size({ size: 108 }),
borderRadius: 100,
}}
/>
{isSelf && (
<Pressable
style={styles.editAvatarButton}
onPress={() =>
onChangeProfilePicture(
loaderMessages.profilePhotoUploadWeb
)
}
disabled={updatingPhoto}
hitSlop={10}
>
<View style={styles.editAvatarBackground}>
{updatingPhoto ? (
<ActivityIndicator size="small" color={Palette.white} />
) : (
<Image
source={icons.edit}
style={styles.editAvatarIcon}
resizeMode="contain"
/>
)}
</View>
</Pressable>
)}
</View>
{isWeb && updatingPhoto && webUploadMessage ? (
<Text style={styles.webLoaderText}>{webUploadMessage}</Text>
) : null}
<Text
style={{
fontSize: 22,
@@ -498,4 +590,36 @@ const styles = StyleSheet.create({
paddingHorizontal: 10,
...Style.containerCenter,
},
avatarWrapper: {
position: "relative",
...size({ size: 108 }),
alignItems: "center",
justifyContent: "center",
},
editAvatarButton: {
position: "absolute",
bottom: 4,
right: 4,
},
editAvatarBackground: {
width: 36,
height: 36,
borderRadius: 18,
backgroundColor: Palette.transparentBlack,
borderWidth: 1,
borderColor: Palette.white,
...Style.containerCenter,
},
editAvatarIcon: {
...size({ size: 16 }),
tintColor: Palette.white,
},
webLoaderText: {
marginTop: 8,
color: Palette.white,
fontSize: 12,
fontFamily: FONT_FAMILY.InterRegular,
textAlign: "center",
opacity: 0.85,
},
});
+29 -3
View File
@@ -8,6 +8,7 @@ import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import MusicLandHeader from "../../components/MusicLandHeader";
import firebase, { tasksRef } from "../../config/firebase";
import loaderMessages from "../../config/loaderMessages";
import { uploadFileToFirebase } from "../../helpers/uploadToFirebase";
import { isWeb } from "../../hooks/useLayoutType";
import Page from "../../layouts/Page";
@@ -22,6 +23,9 @@ const PhotoCover = () => {
useUserData();
const { setIsLoading } = useMinuit();
const isGenerating = selectedProject?.coverStatus === "GENERATING";
const coverGenerationMessage = isWeb
? loaderMessages.photoCoverGenerationWeb
: "";
const onChooseForegroundImage = async () => {
try {
@@ -102,9 +106,31 @@ const PhotoCover = () => {
{isGenerating && (
<View style={{ alignItems: "center", gap: 8 }}>
<ActivityIndicator color={Palette.white} />
<Text style={{ color: Palette.white, marginTop: 6 }}>
Génération en cours.
</Text>
{isWeb ? (
coverGenerationMessage ? (
<Text
style={{
color: Palette.white,
marginTop: 6,
textAlign: "center",
opacity: 0.9,
}}
>
{coverGenerationMessage}
</Text>
) : null
) : (
<Text
style={{
color: Palette.white,
marginTop: 6,
textAlign: "center",
opacity: 0.9,
}}
>
Génération en cours.
</Text>
)}
</View>
)}
</View>
+29 -3
View File
@@ -8,6 +8,7 @@ import BorderGradientButton from "../../components/BorderGradientButton";
import GradientButton from "../../components/GradientButton";
import MusicLandHeader from "../../components/MusicLandHeader";
import firebase, { tasksRef } from "../../config/firebase";
import loaderMessages from "../../config/loaderMessages";
import { isWeb } from "../../hooks/useLayoutType";
import Page from "../../layouts/Page";
import { Routes } from "../../navigation";
@@ -21,6 +22,9 @@ const PouchReady = () => {
const { setIsLoading } = useMinuit();
const isGenerating = selectedProject?.coverStatus === "GENERATING";
const isFocused = useIsFocused();
const coverBackgroundMessage = isWeb
? loaderMessages.pouchReadyGenerationWeb
: "";
const generateCover = useCallback(async () => {
if (!selectedProjectId) return;
@@ -126,9 +130,31 @@ const PouchReady = () => {
{isGenerating && (
<View style={{ alignItems: "center", gap: 8 }}>
<ActivityIndicator color={Palette.white} />
<Text style={{ color: Palette.white, marginTop: 6 }}>
Génération en cours.
</Text>
{isWeb ? (
coverBackgroundMessage ? (
<Text
style={{
color: Palette.white,
marginTop: 6,
textAlign: "center",
opacity: 0.9,
}}
>
{coverBackgroundMessage}
</Text>
) : null
) : (
<Text
style={{
color: Palette.white,
marginTop: 6,
textAlign: "center",
opacity: 0.9,
}}
>
Génération en cours.
</Text>
)}
</View>
)}
</View>