diff --git a/src/assets/UI/libraryBgWeb.png b/src/assets/UI/libraryBgWeb.png index 0d38e16..980c737 100644 Binary files a/src/assets/UI/libraryBgWeb.png and b/src/assets/UI/libraryBgWeb.png differ diff --git a/src/components/ProjectDropDown/ProjectDropDown.js b/src/components/ProjectDropDown/ProjectDropDown.js index 286f6c2..f5349c2 100644 --- a/src/components/ProjectDropDown/ProjectDropDown.js +++ b/src/components/ProjectDropDown/ProjectDropDown.js @@ -1,8 +1,10 @@ import { BlurView } from "expo-blur"; import { Portal } from "@gorhom/portal"; import React, { + forwardRef, useCallback, useEffect, + useImperativeHandle, useMemo, useRef, useState, @@ -78,21 +80,25 @@ const defaultFormatDate = (timestamp) => { } }; -const ProjectDropDown = ({ - style, - projects = [], - selectedProject, - onSelectProject, - onModifyProject, - onCreateProject, - formatDate = defaultFormatDate, - allowEmptySelection = false, -}) => { - const [isOpen, setIsOpen] = useState(false); - const [triggerLayout, setTriggerLayout] = useState(null); - const [triggerWindowLayout, setTriggerWindowLayout] = useState(null); - const triggerRef = useRef(null); - const dropdownAnimation = useRef(new Animated.Value(0)).current; +const ProjectDropDown = forwardRef( + ( + { + style, + projects = [], + selectedProject, + onSelectProject, + onModifyProject, + onCreateProject, + formatDate = defaultFormatDate, + allowEmptySelection = false, + }, + ref + ) => { + const [isOpen, setIsOpen] = useState(false); + const [triggerLayout, setTriggerLayout] = useState(null); + const [triggerWindowLayout, setTriggerWindowLayout] = useState(null); + const triggerRef = useRef(null); + const dropdownAnimation = useRef(new Animated.Value(0)).current; const measureTriggerPosition = useCallback(() => { if (triggerRef.current?.measureInWindow) { @@ -133,39 +139,47 @@ const ProjectDropDown = ({ }) : normalizedProjects; - const toggleDropdown = useCallback(() => { - if (isDisabled) { - return; - } - if (!isOpen) { - measureTriggerPosition(); - } - setIsOpen((prev) => !prev); - }, [isDisabled, isOpen, measureTriggerPosition]); + const toggleDropdown = useCallback(() => { + if (isDisabled) { + return; + } + if (!isOpen) { + measureTriggerPosition(); + } + setIsOpen((prev) => !prev); + }, [isDisabled, isOpen, measureTriggerPosition]); - const closeDropdown = useCallback(() => setIsOpen(false), []); + const closeDropdown = useCallback(() => setIsOpen(false), []); - const handleSelect = useCallback( - (project) => { - if (!project?.id) return; - onSelectProject?.(project); + useImperativeHandle( + ref, + () => ({ + close: closeDropdown, + }), + [closeDropdown] + ); + + const handleSelect = useCallback( + (project) => { + if (!project?.id) return; + onSelectProject?.(project); + closeDropdown(); + }, + [closeDropdown, onSelectProject] + ); + + const handleModify = useCallback( + (project, anchor) => { + if (!project?.id) return; + onModifyProject?.(project, anchor); + }, + [onModifyProject] + ); + + const handleCreate = useCallback(() => { + onCreateProject?.(); closeDropdown(); - }, - [closeDropdown, onSelectProject] - ); - - const handleModify = useCallback( - (project, anchor) => { - if (!project?.id) return; - onModifyProject?.(project, anchor); - }, - [onModifyProject] - ); - - const handleCreate = useCallback(() => { - onCreateProject?.(); - closeDropdown(); - }, [closeDropdown, onCreateProject]); + }, [closeDropdown, onCreateProject]); const dropdownWidth = useMemo( () => triggerLayout?.width || 0, @@ -286,74 +300,75 @@ const ProjectDropDown = ({ ); - return ( - - { - setTriggerLayout(event.nativeEvent.layout); - measureTriggerPosition(); - }} - > - + { + setTriggerLayout(event.nativeEvent.layout); + measureTriggerPosition(); + }} > - - - - + + + + - {isOpen && triggerWindowLayout ? ( - - - - - - - {dropdownContent} - - - - ) : null} + {isOpen && triggerWindowLayout ? ( + + + + + + + {dropdownContent} + + + + ) : null} + - - ); -}; + ); + } +); export default ProjectDropDown; diff --git a/src/screens/Home/Home.js b/src/screens/Home/Home.js index ec040ce..ebf412a 100644 --- a/src/screens/Home/Home.js +++ b/src/screens/Home/Home.js @@ -33,6 +33,7 @@ import { getStageAction, } from "../../utils/projectStages"; import { openCoinPackModal } from "../../utils/coinPackModal"; +import useNavigateToMusicDetails from "../../hooks/useNavigateToMusicDetails"; import StageCard from "./components/StageCard"; import ClubCard from "./components/ClubCard"; @@ -66,7 +67,7 @@ const STAGE_CARD_CONTENT = [ key: "beatmaker", step: "ÉTAPE 2", description: - "Bienvenue au studio MusicLand.\nNous mettons en musique tes paroles en fonction de tes inspirations, ça va être top !", + "Je suis Malik, responsable du studio de MusicLand.\nJe vais mettre en musique tes paroles en fonction de tes goûts musicaux, ça va être top !", image: cardsImg.studio, imagePosition: "right", textAlign: "right", @@ -86,7 +87,7 @@ const STAGE_CARD_CONTENT = [ key: "publisher", step: "ÉTAPE 4", description: - "À la sortie du studio, l'équipe production te propose les prochaines étapes pour partager ta musique avec le monde.", + "Je suis Mr Benhaï, Producteur de MusicLand, et je vais te faire une proposition qui pourrait t’intéresser. On se retrouve à la sortie du studio !", image: cardsImg.production, imagePosition: "right", textAlign: "right", @@ -115,6 +116,7 @@ const Home = ({ navigation, route }) => { } = useUser(); const { setTooltip } = useMinuit(); const [videoUrl, setVideoUrl] = useState(null); + const navigateToMusicDetails = useNavigateToMusicDetails(); if (!currentUID) { return ; @@ -174,6 +176,7 @@ const Home = ({ navigation, route }) => { const [menuAnchor, setMenuAnchor] = useState(null); const [menuProject, setMenuProject] = useState(null); const menuAnchorRef = useRef(null); + const projectDropdownRef = useRef(null); const [hasLocalAdventureFlag, setHasLocalAdventureFlag] = useState(false); const handleSelectProject = useCallback( @@ -232,28 +235,48 @@ const Home = ({ navigation, route }) => { const moreMenuItems = useMemo(() => { if (!menuProject?.id) return []; - return [ - { - label: "Supprimer", - onPress: () => - Alert( - "Confirmer la suppression", - "Cette action supprimera définitivement ce projet.", - [ - { text: "Annuler", style: "cancel" }, - { - text: "Supprimer", - style: "destructive", - onPress: () => { - handleDeleteProject(); - }, + + const items = []; + const hasSongUrl = + typeof menuProject?.songUrl === "string" && + menuProject.songUrl.length > 0; + + if (hasSongUrl) { + items.push({ + label: "Jouer la musique", + onPress: () => { + projectDropdownRef.current?.close?.(); + navigateToMusicDetails({ + projectId: menuProject.id, + songUrl: menuProject.songUrl, + project: menuProject, + }); + }, + }); + } + + items.push({ + label: "Supprimer", + onPress: () => + Alert( + "Confirmer la suppression", + "Cette action supprimera définitivement ce projet.", + [ + { text: "Annuler", style: "cancel" }, + { + text: "Supprimer", + style: "destructive", + onPress: () => { + handleDeleteProject(); }, - ], - { cancelable: true }, - ), - }, - ]; - }, [handleDeleteProject, menuProject?.id]); + }, + ], + { cancelable: true }, + ), + }); + + return items; + }, [handleDeleteProject, menuProject, navigateToMusicDetails]); useEffect(() => { if (!route?.params?.showLyricsCongrats) { @@ -495,6 +518,7 @@ const Home = ({ navigation, route }) => { {mobileInfoRow}