diff --git a/src/components/ProfilePicture.js b/src/components/ProfilePicture.js new file mode 100644 index 0000000..583315a --- /dev/null +++ b/src/components/ProfilePicture.js @@ -0,0 +1,65 @@ +import { Image } from "expo-image"; +import { memo } from "react"; +import { Platform, StyleSheet, View } from "react-native"; +import { Palette } from "../styles"; + +const DEFAULT_INTENSITY = Platform.select({ ios: 22, default: 14 }); + +const ProfilePicture = ({ + uri = null, + size = 48, + style, + blurIntensity = DEFAULT_INTENSITY, + blurTint = "dark", + imageProps = {}, + transitionDuration = 120, + cachePolicy = "memory-disk", + contentFit = "cover", + accessibilityLabel, + ...rest +}) => { + const dimensionStyle = { + width: size, + height: size, + borderRadius: size / 2, + }; + + return ( + + {uri ? ( + + ) : ( + <> + + + )} + + ); +}; + +const styles = StyleSheet.create({ + container: { + overflow: "hidden", + backgroundColor: "transparent", + }, + fallback: { + backgroundColor: Palette.glass, + borderColor: Palette.ultraLightWhite, + borderWidth: 2, + }, +}); + +export default memo(ProfilePicture); diff --git a/src/components/bottomsheets/CommentsBottomSheet.js b/src/components/bottomsheets/CommentsBottomSheet.js index a8eed22..4377a1c 100644 --- a/src/components/bottomsheets/CommentsBottomSheet.js +++ b/src/components/bottomsheets/CommentsBottomSheet.js @@ -6,7 +6,6 @@ import { BottomSheetTextInput, } from '@gorhom/bottom-sheet'; import { BlurView } from 'expo-blur'; -import { Image as ExpoImage } from 'expo-image'; import React, { useCallback, useEffect, @@ -30,7 +29,7 @@ import { useUser } from '../../providers/UserDataProvider'; import { getArtistDisplayName } from '../../utils/artistName'; import { Palette } from '../../styles'; import { FONT_FAMILY } from '../../styles/Fonts'; -import { size } from '../../styles/Style'; +import ProfilePicture from '../ProfilePicture'; let externalOpen; let externalClose; @@ -273,24 +272,7 @@ const CommentsBottomSheet = () => { - {c?.profilePicture ? ( - - ) : ( - - )} + { }, [handleDeleteProject, menuProject?.id]); useEffect(() => { - if (route?.params?.showLyricsCongrats) { - Alert( - "Céline", - "Bravo ! Vous venez de terminer de créer les paroles de votre musique ! Maintenant vous pouvez passer à la prochaine étape : le Studio avec Malik. Dans cette étape vous allez pouvoir donner vie à votre chanson !" - ); - navigation?.setParams?.({ showLyricsCongrats: false }); + if (!route?.params?.showLyricsCongrats) { + return; } - }, [navigation, route?.params?.showLyricsCongrats]); + const beatmakerStage = currentProject + ? getStageAction("beatmaker", currentProject) + : null; + Alert( + "Céline", + "Bravo ! Vous venez de terminer de créer les paroles de votre musique ! Maintenant vous pouvez passer à la prochaine étape : le Studio avec Malik. Dans cette étape vous allez pouvoir donner vie à votre chanson !", + [ + { + text: "Retour à l'accueil", + style: "cancel", + }, + { + text: "Continuer avec Malik", + onPress: () => { + if (!currentProject?.id) { + return; + } + if (selectedProject?.id !== currentProject.id) { + selectProject(currentProject.id); + } + const targetRoute = beatmakerStage?.route || Routes.Compose; + navigate(targetRoute, beatmakerStage?.params); + }, + }, + ] + ); + navigation?.setParams?.({ showLyricsCongrats: false }); + }, [ + currentProject, + navigation, + selectProject, + selectedProject?.id, + route?.params?.showLyricsCongrats, + ]); const activeStage = stageStates[activeStageIndex] || stageStates[preferredStageIndex]; diff --git a/src/screens/Library/components/SearchResultsList.js b/src/screens/Library/components/SearchResultsList.js index abc3c7b..cff47ea 100644 --- a/src/screens/Library/components/SearchResultsList.js +++ b/src/screens/Library/components/SearchResultsList.js @@ -1,14 +1,12 @@ -import { Image as ExpoImage } from "expo-image"; import React, { useState } from "react"; import { Pressable, ScrollView, Text, View } from "react-native"; -import { img } from "../../../assets"; import MoreMenu from "../../../components/MoreMenu"; +import ProfilePicture from "../../../components/ProfilePicture"; import useNavigateToMusicDetails from "../../../hooks/useNavigateToMusicDetails"; import { Routes } from "../../../navigation"; import { navigate } from "../../../navigation/NavigationService"; import { Palette, Style } from "../../../styles"; import { FONT_FAMILY } from "../../../styles/Fonts"; -import { size } from "../../../styles/Style"; import { getArtistDisplayName } from "../../../utils/artistName"; import CreateLyricsHeader from "../../Writing/components/CreateLyricsHeader"; import MusicCard from "./MusicCard"; @@ -190,27 +188,15 @@ const SearchResultsList = ({ key={user.id} onPress={() => handleProfilePress(user.id)} > - { navigate(Routes.SingerProfile, { userId: item?.userId }); }} > - {owner?.profilePictureURL ? ( - - ) : ( - - )} + {owner?.id && currentUID && owner.id !== currentUID && ( 0 && styles.commentRowSpacing, ]} > - {c?.profilePicture ? ( - - ) : ( - - )} + @@ -315,14 +307,6 @@ const styles = StyleSheet.create({ marginTop: 16, }, commentAvatar: { - ...size({ size: 48 }), - borderRadius: 100, - marginRight: 12, - }, - commentAvatarFallback: { - ...size({ size: 48 }), - borderRadius: 100, - backgroundColor: "#FFFFFF33", marginRight: 12, }, commentBubble: { diff --git a/src/screens/Profile/EditProfile.js b/src/screens/Profile/EditProfile.js index 2cc4e3e..fce762c 100644 --- a/src/screens/Profile/EditProfile.js +++ b/src/screens/Profile/EditProfile.js @@ -1,12 +1,12 @@ import { BlurView } from "expo-blur"; -import { Image as ExpoImage } from "expo-image"; import * as ImagePicker from "expo-image-picker"; import React, { useEffect, useState } from "react"; import { Platform, Pressable, Text, View } from "react-native"; import { responsiveHeight } from "react-native-responsive-dimensions"; import { useGlobal } from "reactn"; -import { background, img } from "../../assets"; +import { background } from "../../assets"; import GradientButton from "../../components/GradientButton"; +import ProfilePicture from "../../components/ProfilePicture"; import firebase, { serverTimestamp, usersRef } from "../../config/firebase"; import { uploadFileToFirebase } from "../../helpers/uploadToFirebase"; import { isWeb } from "../../hooks/useLayoutType"; @@ -15,7 +15,6 @@ import { goBack } from "../../navigation/NavigationService"; import { useUser } from "../../providers/UserDataProvider"; import { gutters, Palette } from "../../styles"; import { FONT_FAMILY } from "../../styles/Fonts"; -import { size } from "../../styles/Style"; import EditInput from "./components/EditInput"; const EditProfile = () => { @@ -147,22 +146,10 @@ const EditProfile = () => { // } > - { const { params } = useRoute(); @@ -92,17 +91,10 @@ const Follows = () => { style={{ gap: 14, ...Style.containerRow }} onPress={() => navigate(Routes.SingerProfile, { userId: user?.id })} > - { - {isSelf && ( { @@ -264,17 +265,49 @@ const Lyrics = ({ navigation }) => { if (!isSame) { updateData.musicUrls = firebase.firestore.FieldValue.delete(); updateData.musicStatus = firebase.firestore.FieldValue.delete(); - await projectsRef - .doc(selectedProjectId) - .set(updateData, { merge: true }); } - navigate(Routes.BottomTab, { - screen: Routes.HomeStack, - params: { - screen: Routes.Home, - params: { showLyricsCongrats: true }, - }, - }); + await projectsRef + .doc(selectedProjectId) + .set(updateData, { merge: true }); + const projectForStage = { + ...selectedProject, + title: titleTrimmed, + lyrics: normalizedNewLyrics, + config: sanitize(projectConfig), + selections: sanitize(projectSelections), + hasLyrics: true, + }; + if (!isSame) { + projectForStage.musicUrls = undefined; + projectForStage.musicStatus = undefined; + } + const beatmakerStage = getStageAction("beatmaker", projectForStage); + await setIsLoading(false); + alert( + "Céline", + "Bravo ! Vous venez de terminer de créer les paroles de votre musique ! Maintenant vous pouvez passer à la prochaine étape : le Studio avec Malik. Dans cette étape vous allez pouvoir donner vie à votre chanson !", + [ + { + text: "Retour à l'accueil", + style: "cancel", + onPress: () => + navigate(Routes.BottomTab, { + screen: Routes.HomeStack, + params: { + screen: Routes.Home, + }, + }), + }, + { + text: "Continuer avec Malik", + onPress: () => { + const targetRoute = beatmakerStage?.route || Routes.Compose; + navigate(targetRoute, beatmakerStage?.params); + }, + }, + ] + ); + return; } catch (e) { console.log(e); alertMessage("Erreur", "Échec de l'enregistrement dans le projet."); @@ -293,6 +326,7 @@ const Lyrics = ({ navigation }) => { selectedProjectId, projectHasLyrics, projectLyrics, + selectedProject, ]); const typeOccurrences = {}; diff --git a/src/screens/cover/ValidateCover.js b/src/screens/cover/ValidateCover.js index 7dd441f..3b0496f 100644 --- a/src/screens/cover/ValidateCover.js +++ b/src/screens/cover/ValidateCover.js @@ -3,6 +3,7 @@ import React, { useCallback, useMemo, useState } from "react"; import { Pressable, Text, View } from "react-native"; import useMinuit from "react-native-minuit/src/hooks/useMinuit.js"; import { background } from "../../assets"; +import alert from "../../components/Alert"; import GradientButton from "../../components/GradientButton"; import MusicLandHeader from "../../components/MusicLandHeader"; import { isWeb } from "../../hooks/useLayoutType"; @@ -11,6 +12,7 @@ import { Routes } from "../../navigation"; import { goBack, navigate } from "../../navigation/NavigationService"; import { useUserData } from "../../providers/UserDataProvider"; import { gutters, Palette, Style } from "../../styles"; +import { getStageAction } from "../../utils/projectStages"; import CreateLyricsHeader from "../Writing/components/CreateLyricsHeader"; const ValidateCover = () => { @@ -95,18 +97,46 @@ const ValidateCover = () => { const existingCover = selectedProject?.cover || {}; const finalUrl = selectedOption.finalUrl || selectedOption.generatedUrl || null; + const nextCoverData = { + ...existingCover, + options: coverOptions, + selectedOptionId: selectedOption.id, + result: finalUrl, + generatedBackground: + selectedOption.generatedUrl || selectedOption.finalUrl || null, + }; await updateProjectData({ - cover: { - ...existingCover, - options: coverOptions, - selectedOptionId: selectedOption.id, - result: finalUrl, - generatedBackground: - selectedOption.generatedUrl || selectedOption.finalUrl || null, - }, + cover: nextCoverData, coverUrl: finalUrl, }); - navigate(Routes.Home); + const projectForStage = { + ...selectedProject, + cover: nextCoverData, + coverUrl: finalUrl, + }; + const playbackStage = getStageAction("director", projectForStage); + await setIsLoading(false); + alert( + "Malik", + "Super ! Ta pochette est validée. Tu peux retourner à l'accueil ou continuer avec John pour produire ton playback.", + [ + { + text: "Retour à l'accueil", + style: "cancel", + onPress: () => navigate(Routes.Home), + }, + { + text: "Continuer avec John", + onPress: () => { + const targetRoute = playbackStage?.route || Routes.Playback; + const params = + playbackStage?.params || { project: projectForStage }; + navigate(targetRoute, params); + }, + }, + ] + ); + return; } catch (e) { console.log(e); } finally {